blob: f66b99b61683c07ccdcad080a9f96f3ad13a20ea [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.IApplicationThread;
42import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070043import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070044import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.app.IServiceConnection;
46import android.app.IThumbnailReceiver;
47import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070048import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070049import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070051import android.app.Service;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080052import android.app.WallpaperManager;
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;
Amith Yamasani742a6712011-05-04 14:49:28 -070078import android.content.pm.UserInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070079import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040080import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.content.res.Configuration;
82import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070083import android.net.Proxy;
84import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.net.Uri;
86import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080087import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080088import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070089import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080090import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080092import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.os.FileUtils;
94import android.os.Handler;
95import android.os.IBinder;
96import android.os.IPermissionController;
97import android.os.Looper;
98import android.os.Message;
99import android.os.Parcel;
100import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700102import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.os.RemoteException;
104import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700105import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.os.SystemClock;
107import android.os.SystemProperties;
Amith Yamasani742a6712011-05-04 14:49:28 -0700108import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700111import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800112import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800113import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.util.PrintWriterPrinter;
115import android.util.SparseArray;
Amith Yamasani742a6712011-05-04 14:49:28 -0700116import android.util.SparseIntArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700117import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import android.view.Gravity;
119import android.view.LayoutInflater;
120import android.view.View;
121import android.view.WindowManager;
122import android.view.WindowManagerPolicy;
123
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.BufferedInputStream;
125import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700126import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.DataInputStream;
128import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.File;
130import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700131import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700133import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200134import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800135import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700137import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.lang.IllegalStateException;
139import java.lang.ref.WeakReference;
140import java.util.ArrayList;
Dianne Hackborncbb722e2012-02-07 18:33:49 -0800141import java.util.Arrays;
Amith Yamasani742a6712011-05-04 14:49:28 -0700142import java.util.Collection;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700143import java.util.Collections;
144import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145import java.util.HashMap;
146import java.util.HashSet;
147import java.util.Iterator;
148import java.util.List;
149import java.util.Locale;
150import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700151import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700152import java.util.concurrent.atomic.AtomicBoolean;
153import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700155public final class ActivityManagerService extends ActivityManagerNative
156 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
Amith Yamasani742a6712011-05-04 14:49:28 -0700157 private static final String USER_DATA_DIR = "/data/user/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final String TAG = "ActivityManager";
Amith Yamasani742a6712011-05-04 14:49:28 -0700159 static final String TAG_MU = "ActivityManagerServiceMU";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400161 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_SWITCH = localLOGV || false;
163 static final boolean DEBUG_TASKS = localLOGV || false;
164 static final boolean DEBUG_PAUSE = localLOGV || false;
165 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
166 static final boolean DEBUG_TRANSITION = localLOGV || false;
167 static final boolean DEBUG_BROADCAST = localLOGV || false;
Christopher Tatef46723b2012-01-26 14:19:24 -0800168 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700169 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700171 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean DEBUG_VISBILITY = localLOGV || false;
173 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700174 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800175 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700177 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700178 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700179 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700180 static final boolean DEBUG_POWER = localLOGV || false;
181 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
Amith Yamasani742a6712011-05-04 14:49:28 -0700182 static final boolean DEBUG_MU = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 static final boolean VALIDATE_TOKENS = false;
184 static final boolean SHOW_ACTIVITY_START_TIME = true;
185
186 // Control over CPU and battery monitoring.
187 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
188 static final boolean MONITOR_CPU_USAGE = true;
189 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
190 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
191 static final boolean MONITOR_THREAD_CPU_USAGE = false;
192
Dianne Hackborn1655be42009-05-08 14:29:01 -0700193 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700194 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700195
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800196 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 // Maximum number of recent tasks that we can remember.
199 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700200
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700201 // Amount of time after a call to stopAppSwitches() during which we will
202 // prevent further untrusted switches from happening.
203 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204
205 // How long we wait for a launched process to attach to the activity manager
206 // before we decide it's never going to come up for real.
207 static final int PROC_START_TIMEOUT = 10*1000;
208
Jeff Brown3f9dd282011-07-08 20:02:19 -0700209 // How long we wait for a launched process to attach to the activity manager
210 // before we decide it's never going to come up for real, when the process was
211 // started with a wrapper for instrumentation (such as Valgrind) because it
212 // could take much longer than usual.
213 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 // How long to wait after going idle before forcing apps to GC.
216 static final int GC_TIMEOUT = 5*1000;
217
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700218 // The minimum amount of time between successive GC requests for a process.
219 static final int GC_MIN_INTERVAL = 60*1000;
220
Dianne Hackborn287952c2010-09-22 22:34:31 -0700221 // The rate at which we check for apps using excessive power -- 15 mins.
222 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
223
224 // The minimum sample duration we will allow before deciding we have
225 // enough data on wake locks to start killing things.
226 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
227
228 // The minimum sample duration we will allow before deciding we have
229 // enough data on CPU usage to start killing things.
230 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 // How long we allow a receiver to run before giving up on it.
Christopher Tatef46723b2012-01-26 14:19:24 -0800233 static final int BROADCAST_FG_TIMEOUT = 10*1000;
234 static final int BROADCAST_BG_TIMEOUT = 60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235
236 // How long we wait for a service to finish executing.
237 static final int SERVICE_TIMEOUT = 20*1000;
238
239 // How long a service needs to be running until restarting its process
240 // is no longer considered to be a relaunch of the service.
241 static final int SERVICE_RESTART_DURATION = 5*1000;
242
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700243 // How long a service needs to be running until it will start back at
244 // SERVICE_RESTART_DURATION after being killed.
245 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
246
247 // Multiplying factor to increase restart duration time by, for each time
248 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
249 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
250
251 // The minimum amount of time between restarting services that we allow.
252 // That is, when multiple services are restarting, we won't allow each
253 // to restart less than this amount of time from the last one.
254 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 // Maximum amount of time for there to be no activity on a service before
257 // we consider it non-essential and allow its process to go on the
258 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700259 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260
261 // How long we wait until we timeout on key dispatching.
262 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 // How long we wait until we timeout on key dispatching during instrumentation.
265 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
266
Dan Egnor42471dd2010-01-07 17:25:22 -0800267 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268
269 static final String[] EMPTY_STRING_ARRAY = new String[0];
270
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700271 public ActivityStack mMainStack;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700272
273 private final boolean mHeadless;
274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700276 * Description of a request to start a new activity, which has been held
277 * due to app switches being disabled.
278 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700279 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700280 ActivityRecord r;
281 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700282 Uri[] grantedUriPermissions;
283 int grantedMode;
284 boolean onlyIfNeeded;
285 }
286
287 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
288 = new ArrayList<PendingActivityLaunch>();
289
290 /**
Christopher Tatef46723b2012-01-26 14:19:24 -0800291 * BROADCASTS
292 *
293 * We keep two broadcast queues and associated bookkeeping, one for those at
294 * foreground priority, and one for normal (background-priority) broadcasts.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 */
Christopher Tatef46723b2012-01-26 14:19:24 -0800296 public class BroadcastQueue {
297 static final String TAG = "BroadcastQueue";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298
Christopher Tatef46723b2012-01-26 14:19:24 -0800299 static final int MAX_BROADCAST_HISTORY = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300
Christopher Tatef46723b2012-01-26 14:19:24 -0800301 /**
302 * Recognizable moniker for this queue
303 */
304 String mQueueName;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800305
Christopher Tatef46723b2012-01-26 14:19:24 -0800306 /**
307 * Timeout period for this queue's broadcasts
308 */
309 long mTimeoutPeriod;
310
311 /**
312 * Lists of all active broadcasts that are to be executed immediately
313 * (without waiting for another broadcast to finish). Currently this only
314 * contains broadcasts to registered receivers, to avoid spinning up
315 * a bunch of processes to execute IntentReceiver components. Background-
316 * and foreground-priority broadcasts are queued separately.
317 */
318 final ArrayList<BroadcastRecord> mParallelBroadcasts
319 = new ArrayList<BroadcastRecord>();
320 /**
321 * List of all active broadcasts that are to be executed one at a time.
322 * The object at the top of the list is the currently activity broadcasts;
323 * those after it are waiting for the top to finish. As with parallel
324 * broadcasts, separate background- and foreground-priority queues are
325 * maintained.
326 */
327 final ArrayList<BroadcastRecord> mOrderedBroadcasts
328 = new ArrayList<BroadcastRecord>();
329
330 /**
331 * Historical data of past broadcasts, for debugging.
332 */
333 final BroadcastRecord[] mBroadcastHistory
334 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
335
336 /**
337 * Set when we current have a BROADCAST_INTENT_MSG in flight.
338 */
339 boolean mBroadcastsScheduled = false;
340
341 /**
342 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
343 */
344 boolean mPendingBroadcastTimeoutMessage;
345
346 /**
347 * Intent broadcasts that we have tried to start, but are
348 * waiting for the application's process to be created. We only
349 * need one per scheduling class (instead of a list) because we always
350 * process broadcasts one at a time, so no others can be started while
351 * waiting for this one.
352 */
353 BroadcastRecord mPendingBroadcast = null;
354
355 /**
356 * The receiver index that is pending, to restart the broadcast if needed.
357 */
358 int mPendingBroadcastRecvIndex;
359
360 BroadcastQueue(String name, long timeoutPeriod) {
361 mQueueName = name;
362 mTimeoutPeriod = timeoutPeriod;
363 }
364
365 public boolean isPendingBroadcastProcessLocked(int pid) {
366 return mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid;
367 }
368
369 public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
370 mParallelBroadcasts.add(r);
371 }
372
373 public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
374 mOrderedBroadcasts.add(r);
375 }
376
377 public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
378 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
379 if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
380 if (DEBUG_BROADCAST) Slog.v(TAG,
381 "***** DROPPING PARALLEL ["
382 + mQueueName + "]: " + r.intent);
383 mParallelBroadcasts.set(i, r);
384 return true;
385 }
386 }
387 return false;
388 }
389
390 public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
391 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
392 if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
393 if (DEBUG_BROADCAST) Slog.v(TAG,
394 "***** DROPPING ORDERED ["
395 + mQueueName + "]: " + r.intent);
396 mOrderedBroadcasts.set(i, r);
397 return true;
398 }
399 }
400 return false;
401 }
402
403 public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
404 boolean didSomething = false;
405 final BroadcastRecord br = mPendingBroadcast;
406 if (br != null && br.curApp.pid == app.pid) {
407 try {
408 mPendingBroadcast = null;
409 processCurBroadcastLocked(br, app);
410 didSomething = true;
411 } catch (Exception e) {
412 Slog.w(TAG, "Exception in new application when starting receiver "
413 + br.curComponent.flattenToShortString(), e);
414 logBroadcastReceiverDiscardLocked(br);
415 finishReceiverLocked(br, br.resultCode, br.resultData,
416 br.resultExtras, br.resultAbort, true);
417 scheduleBroadcastsLocked();
418 // We need to reset the state if we fails to start the receiver.
419 br.state = BroadcastRecord.IDLE;
420 throw new RuntimeException(e.getMessage());
421 }
422 }
423 return didSomething;
424 }
425
426 public void skipPendingBroadcastLocked(int pid) {
427 final BroadcastRecord br = mPendingBroadcast;
428 if (br != null && br.curApp.pid == pid) {
429 br.state = BroadcastRecord.IDLE;
430 br.nextReceiver = mPendingBroadcastRecvIndex;
431 mPendingBroadcast = null;
432 scheduleBroadcastsLocked();
433 }
434 }
435
436 public void skipCurrentReceiverLocked(ProcessRecord app) {
437 boolean reschedule = false;
438 BroadcastRecord r = app.curReceiver;
439 if (r != null) {
440 // The current broadcast is waiting for this app's receiver
441 // to be finished. Looks like that's not going to happen, so
442 // let the broadcast continue.
443 logBroadcastReceiverDiscardLocked(r);
444 finishReceiverLocked(r, r.resultCode, r.resultData,
445 r.resultExtras, r.resultAbort, true);
446 reschedule = true;
447 }
448
449 r = mPendingBroadcast;
450 if (r != null && r.curApp == app) {
451 if (DEBUG_BROADCAST) Slog.v(TAG,
452 "[" + mQueueName + "] skip & discard pending app " + r);
453 logBroadcastReceiverDiscardLocked(r);
454 finishReceiverLocked(r, r.resultCode, r.resultData,
455 r.resultExtras, r.resultAbort, true);
456 reschedule = true;
457 }
458 if (reschedule) {
459 scheduleBroadcastsLocked();
460 }
461 }
462
463 public void scheduleBroadcastsLocked() {
464 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
465 + mQueueName + "]: current="
466 + mBroadcastsScheduled);
467
468 if (mBroadcastsScheduled) {
469 return;
470 }
471 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
472 mBroadcastsScheduled = true;
473 }
474
475 public BroadcastRecord getMatchingOrderedReceiver(IBinder receiver) {
476 if (mOrderedBroadcasts.size() > 0) {
477 final BroadcastRecord r = mOrderedBroadcasts.get(0);
478 if (r != null && r.receiver == receiver) {
479 return r;
480 }
481 }
482 return null;
483 }
484
485 public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
486 String resultData, Bundle resultExtras, boolean resultAbort,
487 boolean explicit) {
488 int state = r.state;
489 r.state = BroadcastRecord.IDLE;
490 if (state == BroadcastRecord.IDLE) {
491 if (explicit) {
492 Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
493 }
494 }
495 r.receiver = null;
496 r.intent.setComponent(null);
497 if (r.curApp != null) {
498 r.curApp.curReceiver = null;
499 }
500 if (r.curFilter != null) {
501 r.curFilter.receiverList.curBroadcast = null;
502 }
503 r.curFilter = null;
504 r.curApp = null;
505 r.curComponent = null;
506 r.curReceiver = null;
507 mPendingBroadcast = null;
508
509 r.resultCode = resultCode;
510 r.resultData = resultData;
511 r.resultExtras = resultExtras;
512 r.resultAbort = resultAbort;
513
514 // We will process the next receiver right now if this is finishing
515 // an app receiver (which is always asynchronous) or after we have
516 // come back from calling a receiver.
517 return state == BroadcastRecord.APP_RECEIVE
518 || state == BroadcastRecord.CALL_DONE_RECEIVE;
519 }
520
521 private final void processNextBroadcast(boolean fromMsg) {
522 synchronized(ActivityManagerService.this) {
523 BroadcastRecord r;
524
525 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast ["
526 + mQueueName + "]: "
527 + mParallelBroadcasts.size() + " broadcasts, "
528 + mOrderedBroadcasts.size() + " ordered broadcasts");
529
530 updateCpuStats();
531
532 if (fromMsg) {
533 mBroadcastsScheduled = false;
534 }
535
536 // First, deliver any non-serialized broadcasts right away.
537 while (mParallelBroadcasts.size() > 0) {
538 r = mParallelBroadcasts.remove(0);
539 r.dispatchTime = SystemClock.uptimeMillis();
540 r.dispatchClockTime = System.currentTimeMillis();
541 final int N = r.receivers.size();
542 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast ["
543 + mQueueName + "] " + r);
544 for (int i=0; i<N; i++) {
545 Object target = r.receivers.get(i);
546 if (DEBUG_BROADCAST) Slog.v(TAG,
547 "Delivering non-ordered on [" + mQueueName + "] to registered "
548 + target + ": " + r);
549 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
550 }
551 addBroadcastToHistoryLocked(r);
552 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast ["
553 + mQueueName + "] " + r);
554 }
555
556 // Now take care of the next serialized one...
557
558 // If we are waiting for a process to come up to handle the next
559 // broadcast, then do nothing at this point. Just in case, we
560 // check that the process we're waiting for still exists.
561 if (mPendingBroadcast != null) {
562 if (DEBUG_BROADCAST_LIGHT) {
563 Slog.v(TAG, "processNextBroadcast ["
564 + mQueueName + "]: waiting for "
565 + mPendingBroadcast.curApp);
566 }
567
568 boolean isDead;
569 synchronized (mPidsSelfLocked) {
570 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
571 }
572 if (!isDead) {
573 // It's still alive, so keep waiting
574 return;
575 } else {
576 Slog.w(TAG, "pending app ["
577 + mQueueName + "]" + mPendingBroadcast.curApp
578 + " died before responding to broadcast");
579 mPendingBroadcast.state = BroadcastRecord.IDLE;
580 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
581 mPendingBroadcast = null;
582 }
583 }
584
585 boolean looped = false;
586
587 do {
588 if (mOrderedBroadcasts.size() == 0) {
589 // No more broadcasts pending, so all done!
590 scheduleAppGcsLocked();
591 if (looped) {
592 // If we had finished the last ordered broadcast, then
593 // make sure all processes have correct oom and sched
594 // adjustments.
595 updateOomAdjLocked();
596 }
597 return;
598 }
599 r = mOrderedBroadcasts.get(0);
600 boolean forceReceive = false;
601
602 // Ensure that even if something goes awry with the timeout
603 // detection, we catch "hung" broadcasts here, discard them,
604 // and continue to make progress.
605 //
606 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
607 // receivers don't get executed with timeouts. They're intended for
608 // one time heavy lifting after system upgrades and can take
609 // significant amounts of time.
610 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
611 if (mProcessesReady && r.dispatchTime > 0) {
612 long now = SystemClock.uptimeMillis();
613 if ((numReceivers > 0) &&
614 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
615 Slog.w(TAG, "Hung broadcast ["
616 + mQueueName + "] discarded after timeout failure:"
617 + " now=" + now
618 + " dispatchTime=" + r.dispatchTime
619 + " startTime=" + r.receiverTime
620 + " intent=" + r.intent
621 + " numReceivers=" + numReceivers
622 + " nextReceiver=" + r.nextReceiver
623 + " state=" + r.state);
624 broadcastTimeoutLocked(false); // forcibly finish this broadcast
625 forceReceive = true;
626 r.state = BroadcastRecord.IDLE;
627 }
628 }
629
630 if (r.state != BroadcastRecord.IDLE) {
631 if (DEBUG_BROADCAST) Slog.d(TAG,
632 "processNextBroadcast("
633 + mQueueName + ") called when not idle (state="
634 + r.state + ")");
635 return;
636 }
637
638 if (r.receivers == null || r.nextReceiver >= numReceivers
639 || r.resultAbort || forceReceive) {
640 // No more receivers for this broadcast! Send the final
641 // result if requested...
642 if (r.resultTo != null) {
643 try {
644 if (DEBUG_BROADCAST) {
645 int seq = r.intent.getIntExtra("seq", -1);
646 Slog.i(TAG, "Finishing broadcast ["
647 + mQueueName + "] " + r.intent.getAction()
648 + " seq=" + seq + " app=" + r.callerApp);
649 }
650 performReceiveLocked(r.callerApp, r.resultTo,
651 new Intent(r.intent), r.resultCode,
652 r.resultData, r.resultExtras, false, false);
653 // Set this to null so that the reference
654 // (local and remote) isnt kept in the mBroadcastHistory.
655 r.resultTo = null;
656 } catch (RemoteException e) {
657 Slog.w(TAG, "Failure ["
658 + mQueueName + "] sending broadcast result of "
659 + r.intent, e);
660 }
661 }
662
663 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
664 cancelBroadcastTimeoutLocked();
665
666 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
667 + r);
668
669 // ... and on to the next...
670 addBroadcastToHistoryLocked(r);
671 mOrderedBroadcasts.remove(0);
672 r = null;
673 looped = true;
674 continue;
675 }
676 } while (r == null);
677
678 // Get the next receiver...
679 int recIdx = r.nextReceiver++;
680
681 // Keep track of when this receiver started, and make sure there
682 // is a timeout message pending to kill it if need be.
683 r.receiverTime = SystemClock.uptimeMillis();
684 if (recIdx == 0) {
685 r.dispatchTime = r.receiverTime;
686 r.dispatchClockTime = System.currentTimeMillis();
687 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["
688 + mQueueName + "] " + r);
689 }
690 if (! mPendingBroadcastTimeoutMessage) {
691 long timeoutTime = r.receiverTime + mTimeoutPeriod;
692 if (DEBUG_BROADCAST) Slog.v(TAG,
693 "Submitting BROADCAST_TIMEOUT_MSG ["
694 + mQueueName + "] for " + r + " at " + timeoutTime);
695 setBroadcastTimeoutLocked(timeoutTime);
696 }
697
698 Object nextReceiver = r.receivers.get(recIdx);
699 if (nextReceiver instanceof BroadcastFilter) {
700 // Simple case: this is a registered receiver who gets
701 // a direct call.
702 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
703 if (DEBUG_BROADCAST) Slog.v(TAG,
704 "Delivering ordered ["
705 + mQueueName + "] to registered "
706 + filter + ": " + r);
707 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
708 if (r.receiver == null || !r.ordered) {
709 // The receiver has already finished, so schedule to
710 // process the next one.
711 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing ["
712 + mQueueName + "]: ordered="
713 + r.ordered + " receiver=" + r.receiver);
714 r.state = BroadcastRecord.IDLE;
715 scheduleBroadcastsLocked();
716 }
717 return;
718 }
719
720 // Hard case: need to instantiate the receiver, possibly
721 // starting its application process to host it.
722
723 ResolveInfo info =
724 (ResolveInfo)nextReceiver;
725
726 boolean skip = false;
727 int perm = checkComponentPermission(info.activityInfo.permission,
728 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
729 info.activityInfo.exported);
730 if (perm != PackageManager.PERMISSION_GRANTED) {
731 if (!info.activityInfo.exported) {
732 Slog.w(TAG, "Permission Denial: broadcasting "
733 + r.intent.toString()
734 + " from " + r.callerPackage + " (pid=" + r.callingPid
735 + ", uid=" + r.callingUid + ")"
736 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
737 + " due to receiver " + info.activityInfo.packageName
738 + "/" + info.activityInfo.name);
739 } else {
740 Slog.w(TAG, "Permission Denial: broadcasting "
741 + r.intent.toString()
742 + " from " + r.callerPackage + " (pid=" + r.callingPid
743 + ", uid=" + r.callingUid + ")"
744 + " requires " + info.activityInfo.permission
745 + " due to receiver " + info.activityInfo.packageName
746 + "/" + info.activityInfo.name);
747 }
748 skip = true;
749 }
750 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
751 r.requiredPermission != null) {
752 try {
753 perm = AppGlobals.getPackageManager().
754 checkPermission(r.requiredPermission,
755 info.activityInfo.applicationInfo.packageName);
756 } catch (RemoteException e) {
757 perm = PackageManager.PERMISSION_DENIED;
758 }
759 if (perm != PackageManager.PERMISSION_GRANTED) {
760 Slog.w(TAG, "Permission Denial: receiving "
761 + r.intent + " to "
762 + info.activityInfo.applicationInfo.packageName
763 + " requires " + r.requiredPermission
764 + " due to sender " + r.callerPackage
765 + " (uid " + r.callingUid + ")");
766 skip = true;
767 }
768 }
769 if (r.curApp != null && r.curApp.crashing) {
770 // If the target process is crashing, just skip it.
771 if (DEBUG_BROADCAST) Slog.v(TAG,
772 "Skipping deliver ordered ["
773 + mQueueName + "] " + r + " to " + r.curApp
774 + ": process crashing");
775 skip = true;
776 }
777
778 if (skip) {
779 if (DEBUG_BROADCAST) Slog.v(TAG,
780 "Skipping delivery of ordered ["
781 + mQueueName + "] " + r + " for whatever reason");
782 r.receiver = null;
783 r.curFilter = null;
784 r.state = BroadcastRecord.IDLE;
785 scheduleBroadcastsLocked();
786 return;
787 }
788
789 r.state = BroadcastRecord.APP_RECEIVE;
790 String targetProcess = info.activityInfo.processName;
791 r.curComponent = new ComponentName(
792 info.activityInfo.applicationInfo.packageName,
793 info.activityInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -0700794 if (r.callingUid != Process.SYSTEM_UID) {
795 info.activityInfo = getActivityInfoForUser(info.activityInfo, UserId
796 .getUserId(r.callingUid));
797 }
Christopher Tatef46723b2012-01-26 14:19:24 -0800798 r.curReceiver = info.activityInfo;
Amith Yamasani742a6712011-05-04 14:49:28 -0700799 if (DEBUG_MU && r.callingUid > UserId.PER_USER_RANGE) {
800 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
801 + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
802 + info.activityInfo.applicationInfo.uid);
803 }
Christopher Tatef46723b2012-01-26 14:19:24 -0800804
805 // Broadcast is being executed, its package can't be stopped.
806 try {
807 AppGlobals.getPackageManager().setPackageStoppedState(
808 r.curComponent.getPackageName(), false);
809 } catch (RemoteException e) {
810 } catch (IllegalArgumentException e) {
811 Slog.w(TAG, "Failed trying to unstop package "
812 + r.curComponent.getPackageName() + ": " + e);
813 }
814
815 // Is this receiver's application already running?
816 ProcessRecord app = getProcessRecordLocked(targetProcess,
817 info.activityInfo.applicationInfo.uid);
818 if (app != null && app.thread != null) {
819 try {
820 app.addPackage(info.activityInfo.packageName);
821 processCurBroadcastLocked(r, app);
822 return;
823 } catch (RemoteException e) {
824 Slog.w(TAG, "Exception when sending broadcast to "
825 + r.curComponent, e);
826 }
827
828 // If a dead object exception was thrown -- fall through to
829 // restart the application.
830 }
831
832 // Not running -- get it started, to be executed when the app comes up.
833 if (DEBUG_BROADCAST) Slog.v(TAG,
834 "Need to start app ["
835 + mQueueName + "] " + targetProcess + " for broadcast " + r);
836 if ((r.curApp=startProcessLocked(targetProcess,
837 info.activityInfo.applicationInfo, true,
838 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
839 "broadcast", r.curComponent,
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800840 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false))
Christopher Tatef46723b2012-01-26 14:19:24 -0800841 == null) {
842 // Ah, this recipient is unavailable. Finish it if necessary,
843 // and mark the broadcast record as ready for the next.
844 Slog.w(TAG, "Unable to launch app "
845 + info.activityInfo.applicationInfo.packageName + "/"
846 + info.activityInfo.applicationInfo.uid + " for broadcast "
847 + r.intent + ": process is bad");
848 logBroadcastReceiverDiscardLocked(r);
849 finishReceiverLocked(r, r.resultCode, r.resultData,
850 r.resultExtras, r.resultAbort, true);
851 scheduleBroadcastsLocked();
852 r.state = BroadcastRecord.IDLE;
853 return;
854 }
855
856 mPendingBroadcast = r;
857 mPendingBroadcastRecvIndex = recIdx;
858 }
859 }
860
861 final void setBroadcastTimeoutLocked(long timeoutTime) {
862 if (! mPendingBroadcastTimeoutMessage) {
863 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
864 mHandler.sendMessageAtTime(msg, timeoutTime);
865 mPendingBroadcastTimeoutMessage = true;
866 }
867 }
868
869 final void cancelBroadcastTimeoutLocked() {
870 if (mPendingBroadcastTimeoutMessage) {
871 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
872 mPendingBroadcastTimeoutMessage = false;
873 }
874 }
875
876 final void broadcastTimeoutLocked(boolean fromMsg) {
877 if (fromMsg) {
878 mPendingBroadcastTimeoutMessage = false;
879 }
880
881 if (mOrderedBroadcasts.size() == 0) {
882 return;
883 }
884
885 long now = SystemClock.uptimeMillis();
886 BroadcastRecord r = mOrderedBroadcasts.get(0);
887 if (fromMsg) {
888 if (mDidDexOpt) {
889 // Delay timeouts until dexopt finishes.
890 mDidDexOpt = false;
891 long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
892 setBroadcastTimeoutLocked(timeoutTime);
893 return;
894 }
895 if (! mProcessesReady) {
896 // Only process broadcast timeouts if the system is ready. That way
897 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
898 // to do heavy lifting for system up.
899 return;
900 }
901
902 long timeoutTime = r.receiverTime + mTimeoutPeriod;
903 if (timeoutTime > now) {
904 // We can observe premature timeouts because we do not cancel and reset the
905 // broadcast timeout message after each receiver finishes. Instead, we set up
906 // an initial timeout then kick it down the road a little further as needed
907 // when it expires.
908 if (DEBUG_BROADCAST) Slog.v(TAG,
909 "Premature timeout ["
910 + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
911 + timeoutTime);
912 setBroadcastTimeoutLocked(timeoutTime);
913 return;
914 }
915 }
916
917 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
918 + ", started " + (now - r.receiverTime) + "ms ago");
919 r.receiverTime = now;
920 r.anrCount++;
921
922 // Current receiver has passed its expiration date.
923 if (r.nextReceiver <= 0) {
924 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
925 return;
926 }
927
928 ProcessRecord app = null;
929 String anrMessage = null;
930
931 Object curReceiver = r.receivers.get(r.nextReceiver-1);
932 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
933 logBroadcastReceiverDiscardLocked(r);
934 if (curReceiver instanceof BroadcastFilter) {
935 BroadcastFilter bf = (BroadcastFilter)curReceiver;
936 if (bf.receiverList.pid != 0
937 && bf.receiverList.pid != MY_PID) {
938 synchronized (ActivityManagerService.this.mPidsSelfLocked) {
939 app = ActivityManagerService.this.mPidsSelfLocked.get(
940 bf.receiverList.pid);
941 }
942 }
943 } else {
944 app = r.curApp;
945 }
946
947 if (app != null) {
948 anrMessage = "Broadcast of " + r.intent.toString();
949 }
950
951 if (mPendingBroadcast == r) {
952 mPendingBroadcast = null;
953 }
954
955 // Move on to the next receiver.
956 finishReceiverLocked(r, r.resultCode, r.resultData,
957 r.resultExtras, r.resultAbort, true);
958 scheduleBroadcastsLocked();
959
960 if (anrMessage != null) {
961 // Post the ANR to the handler since we do not want to process ANRs while
962 // potentially holding our lock.
963 mHandler.post(new AppNotResponding(app, anrMessage));
964 }
965 }
966
967 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
968 if (r.callingUid < 0) {
969 // This was from a registerReceiver() call; ignore it.
970 return;
971 }
972 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
973 MAX_BROADCAST_HISTORY-1);
974 r.finishTime = SystemClock.uptimeMillis();
975 mBroadcastHistory[0] = r;
976 }
977
978 final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
979 if (r.nextReceiver > 0) {
980 Object curReceiver = r.receivers.get(r.nextReceiver-1);
981 if (curReceiver instanceof BroadcastFilter) {
982 BroadcastFilter bf = (BroadcastFilter) curReceiver;
983 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
984 System.identityHashCode(r),
985 r.intent.getAction(),
986 r.nextReceiver - 1,
987 System.identityHashCode(bf));
988 } else {
989 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
990 System.identityHashCode(r),
991 r.intent.getAction(),
992 r.nextReceiver - 1,
993 ((ResolveInfo)curReceiver).toString());
994 }
995 } else {
996 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
997 + r);
998 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
999 System.identityHashCode(r),
1000 r.intent.getAction(),
1001 r.nextReceiver,
1002 "NONE");
1003 }
1004 }
1005
1006 final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
1007 int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
1008 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
1009 || mPendingBroadcast != null) {
1010 boolean printed = false;
1011 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
1012 BroadcastRecord br = mParallelBroadcasts.get(i);
1013 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1014 continue;
1015 }
1016 if (!printed) {
1017 if (needSep) {
1018 pw.println();
1019 needSep = false;
1020 }
1021 printed = true;
1022 pw.println(" Active broadcasts [" + mQueueName + "]:");
1023 }
1024 pw.println(" Broadcast #" + i + ":");
1025 br.dump(pw, " ");
1026 }
1027 printed = false;
1028 needSep = true;
1029 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
1030 BroadcastRecord br = mOrderedBroadcasts.get(i);
1031 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1032 continue;
1033 }
1034 if (!printed) {
1035 if (needSep) {
1036 pw.println();
1037 }
1038 needSep = true;
1039 pw.println(" Active ordered broadcasts [" + mQueueName + "]:");
1040 }
1041 pw.println(" Ordered Broadcast #" + i + ":");
1042 mOrderedBroadcasts.get(i).dump(pw, " ");
1043 }
1044 if (dumpPackage == null || (mPendingBroadcast != null
1045 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
1046 if (needSep) {
1047 pw.println();
1048 }
1049 pw.println(" Pending broadcast [" + mQueueName + "]:");
1050 if (mPendingBroadcast != null) {
1051 mPendingBroadcast.dump(pw, " ");
1052 } else {
1053 pw.println(" (null)");
1054 }
1055 needSep = true;
1056 }
1057 }
1058
1059 boolean printed = false;
1060 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
1061 BroadcastRecord r = mBroadcastHistory[i];
1062 if (r == null) {
1063 break;
1064 }
1065 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
1066 continue;
1067 }
1068 if (!printed) {
1069 if (needSep) {
1070 pw.println();
1071 }
1072 needSep = true;
1073 pw.println(" Historical broadcasts [" + mQueueName + "]:");
1074 printed = true;
1075 }
1076 if (dumpAll) {
1077 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
1078 r.dump(pw, " ");
1079 } else {
1080 if (i >= 50) {
1081 pw.println(" ...");
1082 break;
1083 }
1084 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
1085 }
1086 }
1087
1088 return needSep;
1089 }
1090 }
1091
1092 final BroadcastQueue mFgBroadcastQueue = new BroadcastQueue("foreground", BROADCAST_FG_TIMEOUT);
1093 final BroadcastQueue mBgBroadcastQueue = new BroadcastQueue("background", BROADCAST_BG_TIMEOUT);
1094 // Convenient for easy iteration over the queues. Foreground is first
1095 // so that dispatch of foreground broadcasts gets precedence.
1096 final BroadcastQueue[] mBroadcastQueues = { mFgBroadcastQueue, mBgBroadcastQueue };
1097
1098 BroadcastQueue broadcastQueueForIntent(Intent intent) {
1099 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
1100 if (DEBUG_BACKGROUND_BROADCAST) {
1101 Slog.i(TAG, "Broadcast intent " + intent + " on "
1102 + (isFg ? "foreground" : "background")
1103 + " queue");
1104 }
1105 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
1106 }
1107
1108 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
1109 for (BroadcastQueue queue : mBroadcastQueues) {
1110 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
1111 if (r != null) {
1112 return r;
1113 }
1114 }
1115 return null;
1116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117
1118 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 * Activity we have told the window manager to have key focus.
1120 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001121 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001122 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 * List of intents that were used to start the most recent tasks.
1124 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07001125 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126
1127 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -07001128 * Process management.
1129 */
1130 final ProcessList mProcessList = new ProcessList();
1131
1132 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 * All of the applications we currently have running organized by name.
1134 * The keys are strings of the application package name (as
1135 * returned by the package manager), and the keys are ApplicationRecord
1136 * objects.
1137 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07001138 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139
1140 /**
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001141 * The currently running isolated processes.
1142 */
1143 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
1144
1145 /**
1146 * Counter for assigning isolated process uids, to avoid frequently reusing the
1147 * same ones.
1148 */
1149 int mNextIsolatedProcessUid = 0;
1150
1151 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -07001152 * The currently running heavy-weight process, if any.
1153 */
1154 ProcessRecord mHeavyWeightProcess = null;
1155
1156 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 * The last time that various processes have crashed.
1158 */
1159 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
1160
1161 /**
1162 * Set of applications that we consider to be bad, and will reject
1163 * incoming broadcasts from (which the user has no control over).
1164 * Processes are added to this set when they have crashed twice within
1165 * a minimum amount of time; they are removed from it when they are
1166 * later restarted (hopefully due to some user action). The value is the
1167 * time it was added to the list.
1168 */
1169 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
1170
1171 /**
1172 * All of the processes we currently have running organized by pid.
1173 * The keys are the pid running the application.
1174 *
1175 * <p>NOTE: This object is protected by its own lock, NOT the global
1176 * activity manager lock!
1177 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07001178 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179
1180 /**
1181 * All of the processes that have been forced to be foreground. The key
1182 * is the pid of the caller who requested it (we hold a death
1183 * link on it).
1184 */
1185 abstract class ForegroundToken implements IBinder.DeathRecipient {
1186 int pid;
1187 IBinder token;
1188 }
1189 final SparseArray<ForegroundToken> mForegroundProcesses
1190 = new SparseArray<ForegroundToken>();
1191
1192 /**
1193 * List of records for processes that someone had tried to start before the
1194 * system was ready. We don't start them at that point, but ensure they
1195 * are started by the time booting is complete.
1196 */
1197 final ArrayList<ProcessRecord> mProcessesOnHold
1198 = new ArrayList<ProcessRecord>();
1199
1200 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 * List of persistent applications that are in the process
1202 * of being started.
1203 */
1204 final ArrayList<ProcessRecord> mPersistentStartingProcesses
1205 = new ArrayList<ProcessRecord>();
1206
1207 /**
1208 * Processes that are being forcibly torn down.
1209 */
1210 final ArrayList<ProcessRecord> mRemovedProcesses
1211 = new ArrayList<ProcessRecord>();
1212
1213 /**
1214 * List of running applications, sorted by recent usage.
1215 * The first entry in the list is the least recently used.
1216 * It contains ApplicationRecord objects. This list does NOT include
1217 * any persistent application records (since we never want to exit them).
1218 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001219 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 = new ArrayList<ProcessRecord>();
1221
1222 /**
1223 * List of processes that should gc as soon as things are idle.
1224 */
1225 final ArrayList<ProcessRecord> mProcessesToGc
1226 = new ArrayList<ProcessRecord>();
1227
1228 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -08001229 * This is the process holding what we currently consider to be
1230 * the "home" activity.
1231 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001232 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -08001233
1234 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -07001235 * This is the process holding the activity the user last visited that
1236 * is in a different process from the one they are currently in.
1237 */
1238 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -08001239
1240 /**
1241 * The time at which the previous process was last visible.
1242 */
1243 long mPreviousProcessVisibleTime;
1244
Dianne Hackbornf35fe232011-11-01 19:25:20 -07001245 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001246 * Packages that the user has asked to have run in screen size
1247 * compatibility mode instead of filling the screen.
1248 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001249 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001250
1251 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 * Set of PendingResultRecord objects that are currently active.
1253 */
1254 final HashSet mPendingResultRecords = new HashSet();
1255
1256 /**
1257 * Set of IntentSenderRecord objects that are currently active.
1258 */
1259 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1260 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1261
1262 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08001263 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07001264 * already logged DropBox entries for. Guarded by itself. If
1265 * something (rogue user app) forces this over
1266 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1267 */
1268 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1269 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1270
1271 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07001272 * Strict Mode background batched logging state.
1273 *
1274 * The string buffer is guarded by itself, and its lock is also
1275 * used to determine if another batched write is already
1276 * in-flight.
1277 */
1278 private final StringBuilder mStrictModeBuffer = new StringBuilder();
1279
1280 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 * Keeps track of all IIntentReceivers that have been registered for
1282 * broadcasts. Hash keys are the receiver IBinder, hash value is
1283 * a ReceiverList.
1284 */
1285 final HashMap mRegisteredReceivers = new HashMap();
1286
1287 /**
1288 * Resolver for broadcast intents to registered receivers.
1289 * Holds BroadcastFilter (subclass of IntentFilter).
1290 */
1291 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1292 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1293 @Override
1294 protected boolean allowFilterResult(
1295 BroadcastFilter filter, List<BroadcastFilter> dest) {
1296 IBinder target = filter.receiverList.receiver.asBinder();
1297 for (int i=dest.size()-1; i>=0; i--) {
1298 if (dest.get(i).receiverList.receiver.asBinder() == target) {
1299 return false;
1300 }
1301 }
1302 return true;
1303 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001304
1305 @Override
1306 protected String packageForFilter(BroadcastFilter filter) {
1307 return filter.packageName;
1308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 };
1310
1311 /**
1312 * State of all active sticky broadcasts. Keys are the action of the
1313 * sticky Intent, values are an ArrayList of all broadcasted intents with
1314 * that action (which should usually be one).
1315 */
1316 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
1317 new HashMap<String, ArrayList<Intent>>();
1318
Amith Yamasani742a6712011-05-04 14:49:28 -07001319 final ServiceMap mServiceMap = new ServiceMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320
1321 /**
1322 * All currently bound service connections. Keys are the IBinder of
1323 * the client's IServiceConnection.
1324 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07001325 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
1326 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327
1328 /**
1329 * List of services that we have been asked to start,
1330 * but haven't yet been able to. It is used to hold start requests
1331 * while waiting for their corresponding application thread to get
1332 * going.
1333 */
1334 final ArrayList<ServiceRecord> mPendingServices
1335 = new ArrayList<ServiceRecord>();
1336
1337 /**
1338 * List of services that are scheduled to restart following a crash.
1339 */
1340 final ArrayList<ServiceRecord> mRestartingServices
1341 = new ArrayList<ServiceRecord>();
1342
1343 /**
1344 * List of services that are in the process of being stopped.
1345 */
1346 final ArrayList<ServiceRecord> mStoppingServices
1347 = new ArrayList<ServiceRecord>();
1348
1349 /**
Christopher Tate181fafa2009-05-14 11:12:14 -07001350 * Backup/restore process management
1351 */
1352 String mBackupAppName = null;
1353 BackupRecord mBackupTarget = null;
1354
1355 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 * List of PendingThumbnailsRecord objects of clients who are still
1357 * waiting to receive all of the thumbnails for a task.
1358 */
1359 final ArrayList mPendingThumbnails = new ArrayList();
1360
1361 /**
1362 * List of HistoryRecord objects that have been finished and must
1363 * still report back to a pending thumbnail receiver.
1364 */
1365 final ArrayList mCancelledThumbnails = new ArrayList();
1366
Amith Yamasani742a6712011-05-04 14:49:28 -07001367 final ProviderMap mProviderMap = new ProviderMap();
1368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 /**
1370 * List of content providers who have clients waiting for them. The
1371 * application is currently being launched and the provider will be
1372 * removed from this list once it is published.
1373 */
Dianne Hackborn860755f2010-06-03 18:47:52 -07001374 final ArrayList<ContentProviderRecord> mLaunchingProviders
1375 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376
1377 /**
1378 * Global set of specific Uri permissions that have been granted.
1379 */
1380 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
1381 = new SparseArray<HashMap<Uri, UriPermission>>();
1382
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001383 CoreSettingsObserver mCoreSettingsObserver;
1384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 /**
1386 * Thread-local storage used to carry caller permissions over through
1387 * indirect content-provider access.
1388 * @see #ActivityManagerService.openContentUri()
1389 */
1390 private class Identity {
1391 public int pid;
1392 public int uid;
1393
1394 Identity(int _pid, int _uid) {
1395 pid = _pid;
1396 uid = _uid;
1397 }
1398 }
Amith Yamasani742a6712011-05-04 14:49:28 -07001399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1401
1402 /**
1403 * All information we have collected about the runtime performance of
1404 * any user id that can impact battery performance.
1405 */
1406 final BatteryStatsService mBatteryStatsService;
1407
1408 /**
1409 * information about component usage
1410 */
1411 final UsageStatsService mUsageStatsService;
1412
1413 /**
1414 * Current configuration information. HistoryRecord objects are given
1415 * a reference to this object to indicate which configuration they are
1416 * currently running in, so this object must be kept immutable.
1417 */
1418 Configuration mConfiguration = new Configuration();
1419
1420 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001421 * Current sequencing integer of the configuration, for skipping old
1422 * configurations.
1423 */
1424 int mConfigurationSeq = 0;
1425
1426 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -07001427 * Hardware-reported OpenGLES version.
1428 */
1429 final int GL_ES_VERSION;
1430
1431 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 * List of initialization arguments to pass to all processes when binding applications to them.
1433 * For example, references to the commonly used services.
1434 */
1435 HashMap<String, IBinder> mAppBindArgs;
1436
1437 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001438 * Temporary to avoid allocations. Protected by main lock.
1439 */
1440 final StringBuilder mStringBuilder = new StringBuilder(256);
1441
1442 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 * Used to control how we initialize the service.
1444 */
1445 boolean mStartRunning = false;
1446 ComponentName mTopComponent;
1447 String mTopAction;
1448 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001449 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 boolean mSystemReady = false;
1451 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001452 boolean mWaitingUpdate = false;
1453 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001454 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -07001455 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456
1457 Context mContext;
1458
1459 int mFactoryTest;
1460
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001461 boolean mCheckedForSetup;
1462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001464 * The time at which we will allow normal application switches again,
1465 * after a call to {@link #stopAppSwitches()}.
1466 */
1467 long mAppSwitchesAllowedTime;
1468
1469 /**
1470 * This is set to true after the first switch after mAppSwitchesAllowedTime
1471 * is set; any switches after that will clear the time.
1472 */
1473 boolean mDidAppSwitch;
1474
1475 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -07001476 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001477 */
Dianne Hackborn287952c2010-09-22 22:34:31 -07001478 long mLastPowerCheckRealtime;
1479
1480 /**
1481 * Last time (in uptime) at which we checked for power usage.
1482 */
1483 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001484
1485 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 * Set while we are wanting to sleep, to prevent any
1487 * activities from being started/resumed.
1488 */
1489 boolean mSleeping = false;
1490
1491 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -07001492 * Set if we are shutting down the system, similar to sleeping.
1493 */
1494 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495
1496 /**
1497 * Task identifier that activities are currently being started
1498 * in. Incremented each time a new task is created.
1499 * todo: Replace this with a TokenSpace class that generates non-repeating
1500 * integers that won't wrap.
1501 */
1502 int mCurTask = 1;
1503
1504 /**
1505 * Current sequence id for oom_adj computation traversal.
1506 */
1507 int mAdjSeq = 0;
1508
1509 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -07001510 * Current sequence id for process LRU updating.
1511 */
1512 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513
1514 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -07001515 * Keep track of the number of service processes we last found, to
1516 * determine on the next iteration which should be B services.
1517 */
1518 int mNumServiceProcs = 0;
1519 int mNewNumServiceProcs = 0;
1520
1521 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 * System monitoring: number of processes that died since the last
1523 * N procs were started.
1524 */
1525 int[] mProcDeaths = new int[20];
1526
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001527 /**
1528 * This is set if we had to do a delayed dexopt of an app before launching
1529 * it, to increasing the ANR timeouts in that case.
1530 */
1531 boolean mDidDexOpt;
1532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 String mDebugApp = null;
1534 boolean mWaitForDebugger = false;
1535 boolean mDebugTransient = false;
1536 String mOrigDebugApp = null;
1537 boolean mOrigWaitForDebugger = false;
1538 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001539 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001540 String mProfileApp = null;
1541 ProcessRecord mProfileProc = null;
1542 String mProfileFile;
1543 ParcelFileDescriptor mProfileFd;
1544 int mProfileType = 0;
1545 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546
Jeff Sharkeya4620792011-05-20 15:29:23 -07001547 final RemoteCallbackList<IProcessObserver> mProcessObservers
1548 = new RemoteCallbackList<IProcessObserver>();
1549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 /**
1551 * Callback of last caller to {@link #requestPss}.
1552 */
1553 Runnable mRequestPssCallback;
1554
1555 /**
1556 * Remaining processes for which we are waiting results from the last
1557 * call to {@link #requestPss}.
1558 */
1559 final ArrayList<ProcessRecord> mRequestPssList
1560 = new ArrayList<ProcessRecord>();
1561
1562 /**
1563 * Runtime statistics collection thread. This object's lock is used to
1564 * protect all related state.
1565 */
1566 final Thread mProcessStatsThread;
1567
1568 /**
1569 * Used to collect process stats when showing not responding dialog.
1570 * Protected by mProcessStatsThread.
1571 */
1572 final ProcessStats mProcessStats = new ProcessStats(
1573 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001574 final AtomicLong mLastCpuTime = new AtomicLong(0);
1575 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
1576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 long mLastWriteTime = 0;
1578
1579 /**
1580 * Set to true after the system has finished booting.
1581 */
1582 boolean mBooted = false;
1583
Dianne Hackborn7d608422011-08-07 16:24:18 -07001584 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001585 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586
1587 WindowManagerService mWindowManager;
1588
1589 static ActivityManagerService mSelf;
1590 static ActivityThread mSystemThread;
1591
1592 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1593 final ProcessRecord mApp;
1594 final int mPid;
1595 final IApplicationThread mAppThread;
1596
1597 AppDeathRecipient(ProcessRecord app, int pid,
1598 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001599 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 TAG, "New death recipient " + this
1601 + " for thread " + thread.asBinder());
1602 mApp = app;
1603 mPid = pid;
1604 mAppThread = thread;
1605 }
1606
1607 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001608 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 TAG, "Death received in " + this
1610 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 synchronized(ActivityManagerService.this) {
1612 appDiedLocked(mApp, mPid, mAppThread);
1613 }
1614 }
1615 }
1616
1617 static final int SHOW_ERROR_MSG = 1;
1618 static final int SHOW_NOT_RESPONDING_MSG = 2;
1619 static final int SHOW_FACTORY_ERROR_MSG = 3;
1620 static final int UPDATE_CONFIGURATION_MSG = 4;
1621 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1622 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1623 static final int BROADCAST_INTENT_MSG = 7;
1624 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 static final int SERVICE_TIMEOUT_MSG = 12;
1626 static final int UPDATE_TIME_ZONE = 13;
1627 static final int SHOW_UID_ERROR_MSG = 14;
1628 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001630 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001631 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001632 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001633 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1634 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001635 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001636 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001637 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001638 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001639 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001640 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
1641 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001642 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001643
1644 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001645 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001646 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001647
1648 final Handler mHandler = new Handler() {
1649 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001650 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 //}
1652
1653 public void handleMessage(Message msg) {
1654 switch (msg.what) {
1655 case SHOW_ERROR_MSG: {
1656 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 synchronized (ActivityManagerService.this) {
1658 ProcessRecord proc = (ProcessRecord)data.get("app");
1659 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001660 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 return;
1662 }
1663 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -07001664 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -08001665 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 d.show();
1667 proc.crashDialog = d;
1668 } else {
1669 // The device is asleep, so just pretend that the user
1670 // saw a crash dialog and hit "force quit".
1671 res.set(0);
1672 }
1673 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001674
1675 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 } break;
1677 case SHOW_NOT_RESPONDING_MSG: {
1678 synchronized (ActivityManagerService.this) {
1679 HashMap data = (HashMap) msg.obj;
1680 ProcessRecord proc = (ProcessRecord)data.get("app");
1681 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001682 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 return;
1684 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001685
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001686 Intent intent = new Intent("android.intent.action.ANR");
1687 if (!mProcessesReady) {
Christopher Tatef46723b2012-01-26 14:19:24 -08001688 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1689 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001690 }
1691 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001692 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001693 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
The Android Open Source Project4df24232009-03-05 14:34:35 -08001694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001696 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697 d.show();
1698 proc.anrDialog = d;
1699 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001700
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001701 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001703 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1704 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1705 synchronized (ActivityManagerService.this) {
1706 ProcessRecord proc = (ProcessRecord) data.get("app");
1707 if (proc == null) {
1708 Slog.e(TAG, "App not found when showing strict mode dialog.");
1709 break;
1710 }
1711 if (proc.crashDialog != null) {
1712 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1713 return;
1714 }
1715 AppErrorResult res = (AppErrorResult) data.get("result");
1716 if (!mSleeping && !mShuttingDown) {
1717 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1718 d.show();
1719 proc.crashDialog = d;
1720 } else {
1721 // The device is asleep, so just pretend that the user
1722 // saw a crash dialog and hit "force quit".
1723 res.set(0);
1724 }
1725 }
1726 ensureBootCompleted();
1727 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001728 case SHOW_FACTORY_ERROR_MSG: {
1729 Dialog d = new FactoryErrorDialog(
1730 mContext, msg.getData().getCharSequence("msg"));
1731 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001732 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 } break;
1734 case UPDATE_CONFIGURATION_MSG: {
1735 final ContentResolver resolver = mContext.getContentResolver();
1736 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1737 } break;
1738 case GC_BACKGROUND_PROCESSES_MSG: {
1739 synchronized (ActivityManagerService.this) {
1740 performAppGcsIfAppropriateLocked();
1741 }
1742 } break;
1743 case WAIT_FOR_DEBUGGER_MSG: {
1744 synchronized (ActivityManagerService.this) {
1745 ProcessRecord app = (ProcessRecord)msg.obj;
1746 if (msg.arg1 != 0) {
1747 if (!app.waitedForDebugger) {
1748 Dialog d = new AppWaitingForDebuggerDialog(
1749 ActivityManagerService.this,
1750 mContext, app);
1751 app.waitDialog = d;
1752 app.waitedForDebugger = true;
1753 d.show();
1754 }
1755 } else {
1756 if (app.waitDialog != null) {
1757 app.waitDialog.dismiss();
1758 app.waitDialog = null;
1759 }
1760 }
1761 }
1762 } break;
1763 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001764 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001765 TAG, "Received BROADCAST_INTENT_MSG");
Christopher Tatef46723b2012-01-26 14:19:24 -08001766 BroadcastQueue queue = (BroadcastQueue) msg.obj;
1767 queue.processNextBroadcast(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 } break;
1769 case BROADCAST_TIMEOUT_MSG: {
Christopher Tatef46723b2012-01-26 14:19:24 -08001770 final BroadcastQueue queue = (BroadcastQueue) msg.obj;
Jeff Brown4d94a762010-09-23 11:33:28 -07001771 synchronized (ActivityManagerService.this) {
Christopher Tatef46723b2012-01-26 14:19:24 -08001772 queue.broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001774 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001776 if (mDidDexOpt) {
1777 mDidDexOpt = false;
1778 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1779 nmsg.obj = msg.obj;
1780 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1781 return;
1782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 serviceTimeout((ProcessRecord)msg.obj);
1784 } break;
1785 case UPDATE_TIME_ZONE: {
1786 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001787 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1788 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 if (r.thread != null) {
1790 try {
1791 r.thread.updateTimeZone();
1792 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001793 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 }
1795 }
1796 }
1797 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001798 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001799 case CLEAR_DNS_CACHE: {
1800 synchronized (ActivityManagerService.this) {
1801 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1802 ProcessRecord r = mLruProcesses.get(i);
1803 if (r.thread != null) {
1804 try {
1805 r.thread.clearDnsCache();
1806 } catch (RemoteException ex) {
1807 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1808 }
1809 }
1810 }
1811 }
1812 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001813 case UPDATE_HTTP_PROXY: {
1814 ProxyProperties proxy = (ProxyProperties)msg.obj;
1815 String host = "";
1816 String port = "";
1817 String exclList = "";
1818 if (proxy != null) {
1819 host = proxy.getHost();
1820 port = Integer.toString(proxy.getPort());
1821 exclList = proxy.getExclusionList();
1822 }
1823 synchronized (ActivityManagerService.this) {
1824 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1825 ProcessRecord r = mLruProcesses.get(i);
1826 if (r.thread != null) {
1827 try {
1828 r.thread.setHttpProxy(host, port, exclList);
1829 } catch (RemoteException ex) {
1830 Slog.w(TAG, "Failed to update http proxy for: " +
1831 r.info.processName);
1832 }
1833 }
1834 }
1835 }
1836 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837 case SHOW_UID_ERROR_MSG: {
1838 // XXX This is a temporary dialog, no need to localize.
1839 AlertDialog d = new BaseErrorDialog(mContext);
1840 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1841 d.setCancelable(false);
1842 d.setTitle("System UIDs Inconsistent");
1843 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 +02001844 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1846 mUidAlert = d;
1847 d.show();
1848 } break;
1849 case IM_FEELING_LUCKY_MSG: {
1850 if (mUidAlert != null) {
1851 mUidAlert.dismiss();
1852 mUidAlert = null;
1853 }
1854 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001856 if (mDidDexOpt) {
1857 mDidDexOpt = false;
1858 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1859 nmsg.obj = msg.obj;
1860 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1861 return;
1862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 ProcessRecord app = (ProcessRecord)msg.obj;
1864 synchronized (ActivityManagerService.this) {
1865 processStartTimedOutLocked(app);
1866 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001867 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001868 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869 synchronized (ActivityManagerService.this) {
1870 doPendingActivityLaunchesLocked(true);
1871 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001872 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001873 case KILL_APPLICATION_MSG: {
1874 synchronized (ActivityManagerService.this) {
1875 int uid = msg.arg1;
1876 boolean restart = (msg.arg2 == 1);
1877 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001878 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001879 }
1880 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001881 case FINALIZE_PENDING_INTENT_MSG: {
1882 ((PendingIntentRecord)msg.obj).completeFinalize();
1883 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001884 case POST_HEAVY_NOTIFICATION_MSG: {
1885 INotificationManager inm = NotificationManager.getService();
1886 if (inm == null) {
1887 return;
1888 }
1889
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001890 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001891 ProcessRecord process = root.app;
1892 if (process == null) {
1893 return;
1894 }
1895
1896 try {
1897 Context context = mContext.createPackageContext(process.info.packageName, 0);
1898 String text = mContext.getString(R.string.heavy_weight_notification,
1899 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1900 Notification notification = new Notification();
1901 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1902 notification.when = 0;
1903 notification.flags = Notification.FLAG_ONGOING_EVENT;
1904 notification.tickerText = text;
1905 notification.defaults = 0; // please be quiet
1906 notification.sound = null;
1907 notification.vibrate = null;
1908 notification.setLatestEventInfo(context, text,
1909 mContext.getText(R.string.heavy_weight_notification_detail),
1910 PendingIntent.getActivity(mContext, 0, root.intent,
1911 PendingIntent.FLAG_CANCEL_CURRENT));
1912
1913 try {
1914 int[] outId = new int[1];
1915 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1916 notification, outId);
1917 } catch (RuntimeException e) {
1918 Slog.w(ActivityManagerService.TAG,
1919 "Error showing notification for heavy-weight app", e);
1920 } catch (RemoteException e) {
1921 }
1922 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001923 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001924 }
1925 } break;
1926 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1927 INotificationManager inm = NotificationManager.getService();
1928 if (inm == null) {
1929 return;
1930 }
1931 try {
1932 inm.cancelNotification("android",
1933 R.string.heavy_weight_notification);
1934 } catch (RuntimeException e) {
1935 Slog.w(ActivityManagerService.TAG,
1936 "Error canceling notification for service", e);
1937 } catch (RemoteException e) {
1938 }
1939 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001940 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1941 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001942 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001943 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001944 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1945 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001946 }
1947 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001948 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1949 synchronized (ActivityManagerService.this) {
1950 ActivityRecord ar = (ActivityRecord)msg.obj;
1951 if (mCompatModeDialog != null) {
1952 if (mCompatModeDialog.mAppInfo.packageName.equals(
1953 ar.info.applicationInfo.packageName)) {
1954 return;
1955 }
1956 mCompatModeDialog.dismiss();
1957 mCompatModeDialog = null;
1958 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001959 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001960 if (mCompatModePackages.getPackageAskCompatModeLocked(
1961 ar.packageName)) {
1962 int mode = mCompatModePackages.computeCompatModeLocked(
1963 ar.info.applicationInfo);
1964 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1965 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1966 mCompatModeDialog = new CompatModeDialog(
1967 ActivityManagerService.this, mContext,
1968 ar.info.applicationInfo);
1969 mCompatModeDialog.show();
1970 }
1971 }
1972 }
1973 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001974 break;
1975 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001976 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001977 final int pid = msg.arg1;
1978 final int uid = msg.arg2;
1979 final boolean foregroundActivities = (Boolean) msg.obj;
1980 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001981 break;
1982 }
1983 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001984 final int pid = msg.arg1;
1985 final int uid = msg.arg2;
1986 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001987 break;
1988 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001989 case REPORT_MEM_USAGE: {
1990 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1991 if (!isDebuggable) {
1992 return;
1993 }
1994 synchronized (ActivityManagerService.this) {
1995 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001996 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1997 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001998 // avoid spamming.
1999 return;
2000 }
2001 mLastMemUsageReportTime = now;
2002 }
2003 Thread thread = new Thread() {
2004 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002005 StringBuilder dropBuilder = new StringBuilder(1024);
2006 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08002007 StringWriter oomSw = new StringWriter();
2008 PrintWriter oomPw = new PrintWriter(oomSw);
2009 StringWriter catSw = new StringWriter();
2010 PrintWriter catPw = new PrintWriter(catSw);
2011 String[] emptyArgs = new String[] { };
2012 StringBuilder tag = new StringBuilder(128);
2013 StringBuilder stack = new StringBuilder(128);
2014 tag.append("Low on memory -- ");
2015 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
2016 tag, stack);
2017 dropBuilder.append(stack);
2018 dropBuilder.append('\n');
2019 dropBuilder.append('\n');
2020 String oomString = oomSw.toString();
2021 dropBuilder.append(oomString);
2022 dropBuilder.append('\n');
2023 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002024 try {
2025 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
2026 "procrank", });
2027 final InputStreamReader converter = new InputStreamReader(
2028 proc.getInputStream());
2029 BufferedReader in = new BufferedReader(converter);
2030 String line;
2031 while (true) {
2032 line = in.readLine();
2033 if (line == null) {
2034 break;
2035 }
2036 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002037 logBuilder.append(line);
2038 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002039 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002040 dropBuilder.append(line);
2041 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002042 }
2043 converter.close();
2044 } catch (IOException e) {
2045 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002046 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08002047 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002048 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002049 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002050 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002051 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002052 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002053 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002054 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08002055 addErrorToDropBox("lowmem", null, "system_server", null,
2056 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002057 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002058 synchronized (ActivityManagerService.this) {
2059 long now = SystemClock.uptimeMillis();
2060 if (mLastMemUsageReportTime < now) {
2061 mLastMemUsageReportTime = now;
2062 }
2063 }
2064 }
2065 };
2066 thread.start();
2067 break;
2068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 }
2070 }
2071 };
2072
2073 public static void setSystemProcess() {
2074 try {
2075 ActivityManagerService m = mSelf;
2076
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002077 ServiceManager.addService("activity", m, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07002079 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08002080 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002081 if (MONITOR_CPU_USAGE) {
2082 ServiceManager.addService("cpuinfo", new CpuBinder(m));
2083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002084 ServiceManager.addService("permission", new PermissionController(m));
2085
2086 ApplicationInfo info =
2087 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07002088 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07002089 mSystemThread.installSystemApplicationInfo(info);
2090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002091 synchronized (mSelf) {
2092 ProcessRecord app = mSelf.newProcessRecordLocked(
2093 mSystemThread.getApplicationThread(), info,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002094 info.processName, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002095 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002096 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07002097 app.maxAdj = ProcessList.SYSTEM_ADJ;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002098 mSelf.mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099 synchronized (mSelf.mPidsSelfLocked) {
2100 mSelf.mPidsSelfLocked.put(app.pid, app);
2101 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002102 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 }
2104 } catch (PackageManager.NameNotFoundException e) {
2105 throw new RuntimeException(
2106 "Unable to find android system package", e);
2107 }
2108 }
2109
2110 public void setWindowManager(WindowManagerService wm) {
2111 mWindowManager = wm;
2112 }
2113
2114 public static final Context main(int factoryTest) {
2115 AThread thr = new AThread();
2116 thr.start();
2117
2118 synchronized (thr) {
2119 while (thr.mService == null) {
2120 try {
2121 thr.wait();
2122 } catch (InterruptedException e) {
2123 }
2124 }
2125 }
2126
2127 ActivityManagerService m = thr.mService;
2128 mSelf = m;
2129 ActivityThread at = ActivityThread.systemMain();
2130 mSystemThread = at;
2131 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08002132 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002133 m.mContext = context;
2134 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002135 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136
2137 m.mBatteryStatsService.publish(context);
2138 m.mUsageStatsService.publish(context);
2139
2140 synchronized (thr) {
2141 thr.mReady = true;
2142 thr.notifyAll();
2143 }
2144
2145 m.startRunning(null, null, null, null);
2146
2147 return context;
2148 }
2149
2150 public static ActivityManagerService self() {
2151 return mSelf;
2152 }
2153
2154 static class AThread extends Thread {
2155 ActivityManagerService mService;
2156 boolean mReady = false;
2157
2158 public AThread() {
2159 super("ActivityManager");
2160 }
2161
2162 public void run() {
2163 Looper.prepare();
2164
2165 android.os.Process.setThreadPriority(
2166 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07002167 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002168
2169 ActivityManagerService m = new ActivityManagerService();
2170
2171 synchronized (this) {
2172 mService = m;
2173 notifyAll();
2174 }
2175
2176 synchronized (this) {
2177 while (!mReady) {
2178 try {
2179 wait();
2180 } catch (InterruptedException e) {
2181 }
2182 }
2183 }
2184
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07002185 // For debug builds, log event loop stalls to dropbox for analysis.
2186 if (StrictMode.conditionallyEnableDebugLogging()) {
2187 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
2188 }
2189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 Looper.loop();
2191 }
2192 }
2193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002194 static class MemBinder extends Binder {
2195 ActivityManagerService mActivityManagerService;
2196 MemBinder(ActivityManagerService activityManagerService) {
2197 mActivityManagerService = activityManagerService;
2198 }
2199
2200 @Override
2201 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002202 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2203 != PackageManager.PERMISSION_GRANTED) {
2204 pw.println("Permission Denial: can't dump meminfo from from pid="
2205 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2206 + " without permission " + android.Manifest.permission.DUMP);
2207 return;
2208 }
2209
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08002210 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08002211 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002212 }
2213 }
2214
Chet Haase9c1e23b2011-03-24 10:51:31 -07002215 static class GraphicsBinder extends Binder {
2216 ActivityManagerService mActivityManagerService;
2217 GraphicsBinder(ActivityManagerService activityManagerService) {
2218 mActivityManagerService = activityManagerService;
2219 }
2220
2221 @Override
2222 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002223 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2224 != PackageManager.PERMISSION_GRANTED) {
2225 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2226 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2227 + " without permission " + android.Manifest.permission.DUMP);
2228 return;
2229 }
2230
Dianne Hackborne17aeb32011-04-07 15:11:57 -07002231 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07002232 }
2233 }
2234
Jeff Brown6754ba22011-12-14 20:20:01 -08002235 static class DbBinder extends Binder {
2236 ActivityManagerService mActivityManagerService;
2237 DbBinder(ActivityManagerService activityManagerService) {
2238 mActivityManagerService = activityManagerService;
2239 }
2240
2241 @Override
2242 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2243 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2244 != PackageManager.PERMISSION_GRANTED) {
2245 pw.println("Permission Denial: can't dump dbinfo from from pid="
2246 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2247 + " without permission " + android.Manifest.permission.DUMP);
2248 return;
2249 }
2250
2251 mActivityManagerService.dumpDbInfo(fd, pw, args);
2252 }
2253 }
2254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 static class CpuBinder extends Binder {
2256 ActivityManagerService mActivityManagerService;
2257 CpuBinder(ActivityManagerService activityManagerService) {
2258 mActivityManagerService = activityManagerService;
2259 }
2260
2261 @Override
2262 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002263 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2264 != PackageManager.PERMISSION_GRANTED) {
2265 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2266 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2267 + " without permission " + android.Manifest.permission.DUMP);
2268 return;
2269 }
2270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002272 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
2273 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
2274 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 }
2276 }
2277 }
2278
2279 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002280 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07002281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 File dataDir = Environment.getDataDirectory();
2283 File systemDir = new File(dataDir, "system");
2284 systemDir.mkdirs();
2285 mBatteryStatsService = new BatteryStatsService(new File(
2286 systemDir, "batterystats.bin").toString());
2287 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002288 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07002289 mOnBattery = DEBUG_POWER ? true
2290 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002291 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002293 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07002294 systemDir, "usagestats").toString());
Mike Lockwood3a74bd32011-08-12 13:55:22 -07002295 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296
Jack Palevichb90d28c2009-07-22 15:35:24 -07002297 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2298 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2299
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08002300 mConfiguration.setToDefaults();
2301 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08002302 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 mProcessStats.init();
2304
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002305 mCompatModePackages = new CompatModePackages(this, systemDir);
2306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 // Add ourself to the Watchdog monitors.
2308 Watchdog.getInstance().addMonitor(this);
2309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 mProcessStatsThread = new Thread("ProcessStats") {
2311 public void run() {
2312 while (true) {
2313 try {
2314 try {
2315 synchronized(this) {
2316 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002317 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002319 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 // + ", write delay=" + nextWriteDelay);
2321 if (nextWriteDelay < nextCpuDelay) {
2322 nextCpuDelay = nextWriteDelay;
2323 }
2324 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002325 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002326 this.wait(nextCpuDelay);
2327 }
2328 }
2329 } catch (InterruptedException e) {
2330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 updateCpuStatsNow();
2332 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002333 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 }
2335 }
2336 }
2337 };
2338 mProcessStatsThread.start();
2339 }
2340
2341 @Override
2342 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2343 throws RemoteException {
2344 try {
2345 return super.onTransact(code, data, reply, flags);
2346 } catch (RuntimeException e) {
2347 // The activity manager only throws security exceptions, so let's
2348 // log all others.
2349 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002350 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 }
2352 throw e;
2353 }
2354 }
2355
2356 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002357 final long now = SystemClock.uptimeMillis();
2358 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2359 return;
2360 }
2361 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
2362 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 mProcessStatsThread.notify();
2364 }
2365 }
2366 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 void updateCpuStatsNow() {
2369 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002370 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 final long now = SystemClock.uptimeMillis();
2372 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002375 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2376 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 haveNewCpuStats = true;
2378 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002379 //Slog.i(TAG, mProcessStats.printCurrentState());
2380 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 // + mProcessStats.getTotalCpuPercent() + "%");
2382
Joe Onorato8a9b2202010-02-26 18:56:32 -08002383 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 if ("true".equals(SystemProperties.get("events.cpu"))) {
2385 int user = mProcessStats.getLastUserTime();
2386 int system = mProcessStats.getLastSystemTime();
2387 int iowait = mProcessStats.getLastIoWaitTime();
2388 int irq = mProcessStats.getLastIrqTime();
2389 int softIrq = mProcessStats.getLastSoftIrqTime();
2390 int idle = mProcessStats.getLastIdleTime();
2391
2392 int total = user + system + iowait + irq + softIrq + idle;
2393 if (total == 0) total = 1;
2394
Doug Zongker2bec3d42009-12-04 12:52:44 -08002395 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 ((user+system+iowait+irq+softIrq) * 100) / total,
2397 (user * 100) / total,
2398 (system * 100) / total,
2399 (iowait * 100) / total,
2400 (irq * 100) / total,
2401 (softIrq * 100) / total);
2402 }
2403 }
2404
Amith Yamasanie43530a2009-08-21 13:11:37 -07002405 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07002406 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002407 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 synchronized(mPidsSelfLocked) {
2409 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002410 if (mOnBattery) {
2411 int perc = bstats.startAddingCpuLocked();
2412 int totalUTime = 0;
2413 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07002414 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002416 ProcessStats.Stats st = mProcessStats.getStats(i);
2417 if (!st.working) {
2418 continue;
2419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002420 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002421 int otherUTime = (st.rel_utime*perc)/100;
2422 int otherSTime = (st.rel_stime*perc)/100;
2423 totalUTime += otherUTime;
2424 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 if (pr != null) {
2426 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002427 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2428 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002429 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002430 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002431 } else {
2432 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07002433 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002434 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002435 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2436 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002437 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 }
2440 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002441 bstats.finishAddingCpuLocked(perc, totalUTime,
2442 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 }
2444 }
2445 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2448 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002449 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 }
2451 }
2452 }
2453 }
2454
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002455 @Override
2456 public void batteryNeedsCpuUpdate() {
2457 updateCpuStatsNow();
2458 }
2459
2460 @Override
2461 public void batteryPowerChanged(boolean onBattery) {
2462 // When plugging in, update the CPU stats first before changing
2463 // the plug state.
2464 updateCpuStatsNow();
2465 synchronized (this) {
2466 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002467 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002468 }
2469 }
2470 }
2471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 /**
2473 * Initialize the application bind args. These are passed to each
2474 * process when the bindApplication() IPC is sent to the process. They're
2475 * lazily setup to make sure the services are running when they're asked for.
2476 */
2477 private HashMap<String, IBinder> getCommonServicesLocked() {
2478 if (mAppBindArgs == null) {
2479 mAppBindArgs = new HashMap<String, IBinder>();
2480
2481 // Setup the application init args
2482 mAppBindArgs.put("package", ServiceManager.getService("package"));
2483 mAppBindArgs.put("window", ServiceManager.getService("window"));
2484 mAppBindArgs.put(Context.ALARM_SERVICE,
2485 ServiceManager.getService(Context.ALARM_SERVICE));
2486 }
2487 return mAppBindArgs;
2488 }
2489
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002490 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 if (mFocusedActivity != r) {
2492 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002493 if (r != null) {
2494 mWindowManager.setFocusedApp(r.appToken, true);
2495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496 }
2497 }
2498
Dianne Hackborn906497c2010-05-10 15:57:38 -07002499 private final void updateLruProcessInternalLocked(ProcessRecord app,
2500 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002502 int lrui = mLruProcesses.indexOf(app);
2503 if (lrui >= 0) mLruProcesses.remove(lrui);
2504
2505 int i = mLruProcesses.size()-1;
2506 int skipTop = 0;
2507
Dianne Hackborn906497c2010-05-10 15:57:38 -07002508 app.lruSeq = mLruSeq;
2509
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002510 // compute the new weight for this process.
2511 if (updateActivityTime) {
2512 app.lastActivityTime = SystemClock.uptimeMillis();
2513 }
2514 if (app.activities.size() > 0) {
2515 // If this process has activities, we more strongly want to keep
2516 // it around.
2517 app.lruWeight = app.lastActivityTime;
2518 } else if (app.pubProviders.size() > 0) {
2519 // If this process contains content providers, we want to keep
2520 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002521 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002522 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002523 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002524 } else {
2525 // If this process doesn't have activities, we less strongly
2526 // want to keep it around, and generally want to avoid getting
2527 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002528 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002529 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002530 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002531 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07002532
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002533 while (i >= 0) {
2534 ProcessRecord p = mLruProcesses.get(i);
2535 // If this app shouldn't be in front of the first N background
2536 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002537 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002538 skipTop--;
2539 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07002540 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002541 mLruProcesses.add(i+1, app);
2542 break;
2543 }
2544 i--;
2545 }
2546 if (i < 0) {
2547 mLruProcesses.add(0, app);
2548 }
2549
Dianne Hackborn906497c2010-05-10 15:57:38 -07002550 // If the app is currently using a content provider or service,
2551 // bump those processes as well.
2552 if (app.connections.size() > 0) {
2553 for (ConnectionRecord cr : app.connections) {
2554 if (cr.binding != null && cr.binding.service != null
2555 && cr.binding.service.app != null
2556 && cr.binding.service.app.lruSeq != mLruSeq) {
2557 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
2558 updateActivityTime, i+1);
2559 }
2560 }
2561 }
2562 if (app.conProviders.size() > 0) {
2563 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07002564 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
2565 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07002566 updateActivityTime, i+1);
2567 }
2568 }
2569 }
2570
Joe Onorato8a9b2202010-02-26 18:56:32 -08002571 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 if (oomAdj) {
2573 updateOomAdjLocked();
2574 }
2575 }
2576
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002577 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07002578 boolean oomAdj, boolean updateActivityTime) {
2579 mLruSeq++;
2580 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
2581 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002582
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002583 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 String processName, int uid) {
2585 if (uid == Process.SYSTEM_UID) {
2586 // The system gets to run in any process. If there are multiple
2587 // processes with the same uid, just pick the first (this
2588 // should never happen).
2589 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
2590 processName);
2591 return procs != null ? procs.valueAt(0) : null;
2592 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002593 // uid = applyUserId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002594 ProcessRecord proc = mProcessNames.get(processName, uid);
2595 return proc;
2596 }
2597
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002598 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002599 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07002600 try {
2601 if (pm.performDexOpt(packageName)) {
2602 mDidDexOpt = true;
2603 }
2604 } catch (RemoteException e) {
2605 }
2606 }
2607
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002608 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 int transit = mWindowManager.getPendingAppTransition();
2610 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2611 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
2612 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
2613 }
2614
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002615 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002617 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2618 boolean isolated) {
2619 ProcessRecord app;
2620 if (!isolated) {
2621 app = getProcessRecordLocked(processName, info.uid);
2622 } else {
2623 // If this is an isolated process, it can't re-use an existing process.
2624 app = null;
2625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002626 // We don't have to do anything more if:
2627 // (1) There is an existing application record; and
2628 // (2) The caller doesn't think it is dead, OR there is no thread
2629 // object attached to it so we know it couldn't have crashed; and
2630 // (3) There is a pid assigned to it, so it is either starting or
2631 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002632 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 + " app=" + app + " knownToBeDead=" + knownToBeDead
2634 + " thread=" + (app != null ? app.thread : null)
2635 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01002636 if (app != null && app.pid > 0) {
2637 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08002638 // We already have the app running, or are waiting for it to
2639 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002640 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002641 // If this is a new package in the process, add the package to the list
2642 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002643 return app;
2644 } else {
2645 // An application record is attached to a previous process,
2646 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002647 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002648 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002649 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002650 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 String hostingNameStr = hostingName != null
2653 ? hostingName.flattenToShortString() : null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002654
2655 if (!isolated) {
2656 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2657 // If we are in the background, then check to see if this process
2658 // is bad. If so, we will just silently fail.
2659 if (mBadProcesses.get(info.processName, info.uid) != null) {
2660 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2661 + "/" + info.processName);
2662 return null;
2663 }
2664 } else {
2665 // When the user is explicitly starting a process, then clear its
2666 // crash count so that we won't make it bad until they see at
2667 // least one crash dialog again, and make the process good again
2668 // if it had been bad.
2669 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002670 + "/" + info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002671 mProcessCrashTimes.remove(info.processName, info.uid);
2672 if (mBadProcesses.get(info.processName, info.uid) != null) {
2673 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
2674 info.processName);
2675 mBadProcesses.remove(info.processName, info.uid);
2676 if (app != null) {
2677 app.bad = false;
2678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 }
2680 }
2681 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002684 app = newProcessRecordLocked(null, info, processName, isolated);
2685 if (app == null) {
2686 Slog.w(TAG, "Failed making new process record for "
2687 + processName + "/" + info.uid + " isolated=" + isolated);
2688 return null;
2689 }
2690 mProcessNames.put(processName, app.uid, app);
2691 if (isolated) {
2692 mIsolatedProcesses.put(app.uid, app);
2693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 } else {
2695 // If this is a new package in the process, add the package to the list
2696 app.addPackage(info.packageName);
2697 }
2698
2699 // If the system is not ready yet, then hold off on starting this
2700 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002701 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002702 && !isAllowedWhileBooting(info)
2703 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 if (!mProcessesOnHold.contains(app)) {
2705 mProcessesOnHold.add(app);
2706 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002707 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 return app;
2709 }
2710
2711 startProcessLocked(app, hostingType, hostingNameStr);
2712 return (app.pid != 0) ? app : null;
2713 }
2714
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002715 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2716 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2717 }
2718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 private final void startProcessLocked(ProcessRecord app,
2720 String hostingType, String hostingNameStr) {
2721 if (app.pid > 0 && app.pid != MY_PID) {
2722 synchronized (mPidsSelfLocked) {
2723 mPidsSelfLocked.remove(app.pid);
2724 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2725 }
2726 app.pid = 0;
2727 }
2728
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002729 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2730 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 mProcessesOnHold.remove(app);
2732
2733 updateCpuStats();
2734
2735 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2736 mProcDeaths[0] = 0;
2737
2738 try {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002739 int uid = app.uid;
Amith Yamasani742a6712011-05-04 14:49:28 -07002740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002741 int[] gids = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002742 if (!app.isolated) {
2743 try {
2744 gids = mContext.getPackageManager().getPackageGids(
2745 app.info.packageName);
2746 } catch (PackageManager.NameNotFoundException e) {
2747 Slog.w(TAG, "Unable to retrieve gids", e);
2748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 }
2750 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2751 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2752 && mTopComponent != null
2753 && app.processName.equals(mTopComponent.getPackageName())) {
2754 uid = 0;
2755 }
2756 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2757 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2758 uid = 0;
2759 }
2760 }
2761 int debugFlags = 0;
2762 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2763 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07002764 // Also turn on CheckJNI for debuggable apps. It's quite
2765 // awkward to turn on otherwise.
2766 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08002768 // Run the app in safe mode if its manifest requests so or the
2769 // system is booted in safe mode.
2770 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2771 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08002772 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2775 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2776 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07002777 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2778 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002780 if ("1".equals(SystemProperties.get("debug.assert"))) {
2781 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2782 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07002783
2784 // Start the process. It will either succeed and return a result containing
2785 // the PID of the new process, or else throw a RuntimeException.
2786 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07002787 app.processName, uid, uid, gids, debugFlags,
2788 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002790 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2791 synchronized (bs) {
2792 if (bs.isOnBattery()) {
2793 app.batteryStats.incStartsLocked();
2794 }
2795 }
2796
Jeff Brown3f9dd282011-07-08 20:02:19 -07002797 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 app.processName, hostingType,
2799 hostingNameStr != null ? hostingNameStr : "");
2800
2801 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002802 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 }
2804
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002805 StringBuilder buf = mStringBuilder;
2806 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807 buf.append("Start proc ");
2808 buf.append(app.processName);
2809 buf.append(" for ");
2810 buf.append(hostingType);
2811 if (hostingNameStr != null) {
2812 buf.append(" ");
2813 buf.append(hostingNameStr);
2814 }
2815 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002816 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817 buf.append(" uid=");
2818 buf.append(uid);
2819 buf.append(" gids={");
2820 if (gids != null) {
2821 for (int gi=0; gi<gids.length; gi++) {
2822 if (gi != 0) buf.append(", ");
2823 buf.append(gids[gi]);
2824
2825 }
2826 }
2827 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002828 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002829 app.pid = startResult.pid;
2830 app.usingWrapper = startResult.usingWrapper;
2831 app.removed = false;
2832 synchronized (mPidsSelfLocked) {
2833 this.mPidsSelfLocked.put(startResult.pid, app);
2834 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2835 msg.obj = app;
2836 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2837 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 }
2839 } catch (RuntimeException e) {
2840 // XXX do better error recovery.
2841 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002842 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 }
2844 }
2845
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002846 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002847 if (resumed) {
2848 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2849 } else {
2850 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2851 }
2852 }
2853
Amith Yamasani742a6712011-05-04 14:49:28 -07002854 boolean startHomeActivityLocked(int userId) {
Mike Lockwooda8f767a2011-08-31 14:32:37 -04002855 if (mHeadless) {
2856 // Added because none of the other calls to ensureBootCompleted seem to fire
2857 // when running headless.
2858 ensureBootCompleted();
2859 return false;
2860 }
2861
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002862 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2863 && mTopAction == null) {
2864 // We are running in factory test mode, but unable to find
2865 // the factory test app, so just sit around displaying the
2866 // error message and don't try to start anything.
2867 return false;
2868 }
2869 Intent intent = new Intent(
2870 mTopAction,
2871 mTopData != null ? Uri.parse(mTopData) : null);
2872 intent.setComponent(mTopComponent);
2873 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2874 intent.addCategory(Intent.CATEGORY_HOME);
2875 }
2876 ActivityInfo aInfo =
2877 intent.resolveActivityInfo(mContext.getPackageManager(),
2878 STOCK_PM_FLAGS);
2879 if (aInfo != null) {
2880 intent.setComponent(new ComponentName(
2881 aInfo.applicationInfo.packageName, aInfo.name));
2882 // Don't do this if the home app is currently being
2883 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002884 aInfo = new ActivityInfo(aInfo);
2885 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002886 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2887 aInfo.applicationInfo.uid);
2888 if (app == null || app.instrumentationClass == null) {
2889 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002890 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002891 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002892 }
2893 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002894
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002895 return true;
2896 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002897
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002898 /**
2899 * Starts the "new version setup screen" if appropriate.
2900 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002901 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002902 // Only do this once per boot.
2903 if (mCheckedForSetup) {
2904 return;
2905 }
2906
2907 // We will show this screen if the current one is a different
2908 // version than the last one shown, and we are not running in
2909 // low-level factory test mode.
2910 final ContentResolver resolver = mContext.getContentResolver();
2911 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2912 Settings.Secure.getInt(resolver,
2913 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2914 mCheckedForSetup = true;
2915
2916 // See if we should be showing the platform update setup UI.
2917 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2918 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2919 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2920
2921 // We don't allow third party apps to replace this.
2922 ResolveInfo ri = null;
2923 for (int i=0; ris != null && i<ris.size(); i++) {
2924 if ((ris.get(i).activityInfo.applicationInfo.flags
2925 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2926 ri = ris.get(i);
2927 break;
2928 }
2929 }
2930
2931 if (ri != null) {
2932 String vers = ri.activityInfo.metaData != null
2933 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2934 : null;
2935 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2936 vers = ri.activityInfo.applicationInfo.metaData.getString(
2937 Intent.METADATA_SETUP_VERSION);
2938 }
2939 String lastVers = Settings.Secure.getString(
2940 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2941 if (vers != null && !vers.equals(lastVers)) {
2942 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2943 intent.setComponent(new ComponentName(
2944 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002945 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002946 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002947 }
2948 }
2949 }
2950 }
2951
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002952 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002953 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002954 }
2955
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002956 void enforceNotIsolatedCaller(String caller) {
2957 if (UserId.isIsolated(Binder.getCallingUid())) {
2958 throw new SecurityException("Isolated process not allowed to call " + caller);
2959 }
2960 }
2961
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002962 public int getFrontActivityScreenCompatMode() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002963 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002964 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002965 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2966 }
2967 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002968
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002969 public void setFrontActivityScreenCompatMode(int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002970 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2971 "setFrontActivityScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002972 synchronized (this) {
2973 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2974 }
2975 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002976
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002977 public int getPackageScreenCompatMode(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002978 enforceNotIsolatedCaller("getPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002979 synchronized (this) {
2980 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2981 }
2982 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002983
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002984 public void setPackageScreenCompatMode(String packageName, int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002985 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2986 "setPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002987 synchronized (this) {
2988 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002989 }
2990 }
2991
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002992 public boolean getPackageAskScreenCompat(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002993 enforceNotIsolatedCaller("getPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002994 synchronized (this) {
2995 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2996 }
2997 }
2998
2999 public void setPackageAskScreenCompat(String packageName, boolean ask) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003000 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3001 "setPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003002 synchronized (this) {
3003 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3004 }
3005 }
3006
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003007 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003008 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003009
3010 final int identHash = System.identityHashCode(r);
3011 updateUsageStats(r, true);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013
Jeff Sharkeya4620792011-05-20 15:29:23 -07003014 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
3015 int i = mProcessObservers.beginBroadcast();
3016 while (i > 0) {
3017 i--;
3018 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3019 if (observer != null) {
3020 try {
3021 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
3022 } catch (RemoteException e) {
3023 }
3024 }
3025 }
3026 mProcessObservers.finishBroadcast();
3027 }
3028
3029 private void dispatchProcessDied(int pid, int uid) {
3030 int i = mProcessObservers.beginBroadcast();
3031 while (i > 0) {
3032 i--;
3033 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3034 if (observer != null) {
3035 try {
3036 observer.onProcessDied(pid, uid);
3037 } catch (RemoteException e) {
3038 }
3039 }
3040 }
3041 mProcessObservers.finishBroadcast();
3042 }
3043
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003044 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003045 final int N = mPendingActivityLaunches.size();
3046 if (N <= 0) {
3047 return;
3048 }
3049 for (int i=0; i<N; i++) {
3050 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003051 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003052 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3053 doResume && i == (N-1));
3054 }
3055 mPendingActivityLaunches.clear();
3056 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003057
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003058 public final int startActivity(IApplicationThread caller,
3059 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3060 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003061 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3062 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003063 enforceNotIsolatedCaller("startActivity");
Amith Yamasani742a6712011-05-04 14:49:28 -07003064 int userId = 0;
3065 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
3066 // Requesting home, set the identity to the current user
3067 // HACK!
3068 userId = mCurrentUserId;
3069 } else {
3070 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
3071 // the current user's userId
3072 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
3073 userId = 0;
3074 } else {
3075 userId = Binder.getOrigCallingUser();
3076 }
3077 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003078 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -07003079 grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded,
3080 debug, profileFile, profileFd, autoStopProfiler, null, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003081 }
3082
3083 public final WaitResult startActivityAndWait(IApplicationThread caller,
3084 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3085 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003086 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3087 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003088 enforceNotIsolatedCaller("startActivityAndWait");
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003089 WaitResult res = new WaitResult();
Amith Yamasani742a6712011-05-04 14:49:28 -07003090 int userId = Binder.getOrigCallingUser();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003091 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003092 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003093 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
Amith Yamasani742a6712011-05-04 14:49:28 -07003094 res, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003095 return res;
3096 }
3097
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003098 public final int startActivityWithConfig(IApplicationThread caller,
3099 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3100 int grantedMode, IBinder resultTo,
3101 String resultWho, int requestCode, boolean onlyIfNeeded,
3102 boolean debug, Configuration config) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003103 enforceNotIsolatedCaller("startActivityWithConfig");
Amith Yamasani742a6712011-05-04 14:49:28 -07003104 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003105 grantedUriPermissions, grantedMode, resultTo, resultWho,
Amith Yamasani742a6712011-05-04 14:49:28 -07003106 requestCode, onlyIfNeeded,
3107 debug, null, null, false, null, config, Binder.getOrigCallingUser());
3108 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003109 }
3110
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003111 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003112 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003113 IBinder resultTo, String resultWho, int requestCode,
3114 int flagsMask, int flagsValues) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003115 enforceNotIsolatedCaller("startActivityIntentSender");
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003116 // Refuse possible leaked file descriptors
3117 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3118 throw new IllegalArgumentException("File descriptors passed in Intent");
3119 }
3120
3121 IIntentSender sender = intent.getTarget();
3122 if (!(sender instanceof PendingIntentRecord)) {
3123 throw new IllegalArgumentException("Bad PendingIntent object");
3124 }
3125
3126 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003127
3128 synchronized (this) {
3129 // If this is coming from the currently resumed activity, it is
3130 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003131 if (mMainStack.mResumedActivity != null
3132 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003133 Binder.getCallingUid()) {
3134 mAppSwitchesAllowedTime = 0;
3135 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003136 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003137 int ret = pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003138 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
Amith Yamasani742a6712011-05-04 14:49:28 -07003139 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003140 }
3141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003142 public boolean startNextMatchingActivity(IBinder callingActivity,
3143 Intent intent) {
3144 // Refuse possible leaked file descriptors
3145 if (intent != null && intent.hasFileDescriptors() == true) {
3146 throw new IllegalArgumentException("File descriptors passed in Intent");
3147 }
3148
3149 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003150 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
3151 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 return false;
3153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 if (r.app == null || r.app.thread == null) {
3155 // The caller is not running... d'oh!
3156 return false;
3157 }
3158 intent = new Intent(intent);
3159 // The caller is not allowed to change the data.
3160 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3161 // And we are resetting to find the next component...
3162 intent.setComponent(null);
3163
3164 ActivityInfo aInfo = null;
3165 try {
3166 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003167 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003168 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07003169 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003170
3171 // Look for the original activity in the list...
3172 final int N = resolves != null ? resolves.size() : 0;
3173 for (int i=0; i<N; i++) {
3174 ResolveInfo rInfo = resolves.get(i);
3175 if (rInfo.activityInfo.packageName.equals(r.packageName)
3176 && rInfo.activityInfo.name.equals(r.info.name)) {
3177 // We found the current one... the next matching is
3178 // after it.
3179 i++;
3180 if (i<N) {
3181 aInfo = resolves.get(i).activityInfo;
3182 }
3183 break;
3184 }
3185 }
3186 } catch (RemoteException e) {
3187 }
3188
3189 if (aInfo == null) {
3190 // Nobody who is next!
3191 return false;
3192 }
3193
3194 intent.setComponent(new ComponentName(
3195 aInfo.applicationInfo.packageName, aInfo.name));
3196 intent.setFlags(intent.getFlags()&~(
3197 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3198 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3199 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3200 Intent.FLAG_ACTIVITY_NEW_TASK));
3201
3202 // Okay now we need to start the new activity, replacing the
3203 // currently running activity. This is a little tricky because
3204 // we want to start the new one as if the current one is finished,
3205 // but not finish the current one first so that there is no flicker.
3206 // And thus...
3207 final boolean wasFinishing = r.finishing;
3208 r.finishing = true;
3209
3210 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003211 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003212 final String resultWho = r.resultWho;
3213 final int requestCode = r.requestCode;
3214 r.resultTo = null;
3215 if (resultTo != null) {
3216 resultTo.removeResultsLocked(r, resultWho, requestCode);
3217 }
3218
3219 final long origId = Binder.clearCallingIdentity();
3220 // XXX we are not dealing with propagating grantedUriPermissions...
3221 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003222 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003223 r.resolvedType, null, 0, aInfo,
3224 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003225 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 Binder.restoreCallingIdentity(origId);
3227
3228 r.finishing = wasFinishing;
3229 if (res != START_SUCCESS) {
3230 return false;
3231 }
3232 return true;
3233 }
3234 }
3235
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003236 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 Intent intent, String resolvedType, IBinder resultTo,
3238 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003239
3240 // This is so super not safe, that only the system (or okay root)
3241 // can do it.
Amith Yamasani742a6712011-05-04 14:49:28 -07003242 int userId = Binder.getOrigCallingUser();
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003243 final int callingUid = Binder.getCallingUid();
3244 if (callingUid != 0 && callingUid != Process.myUid()) {
3245 throw new SecurityException(
3246 "startActivityInPackage only available to the system");
3247 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248
Amith Yamasani742a6712011-05-04 14:49:28 -07003249 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003250 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
Amith Yamasani742a6712011-05-04 14:49:28 -07003251 null, null, false, null, null, userId);
3252 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003253 }
3254
3255 public final int startActivities(IApplicationThread caller,
3256 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003257 enforceNotIsolatedCaller("startActivities");
Amith Yamasani742a6712011-05-04 14:49:28 -07003258 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
3259 Binder.getOrigCallingUser());
3260 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003261 }
3262
3263 public final int startActivitiesInPackage(int uid,
3264 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
3265
3266 // This is so super not safe, that only the system (or okay root)
3267 // can do it.
3268 final int callingUid = Binder.getCallingUid();
3269 if (callingUid != 0 && callingUid != Process.myUid()) {
3270 throw new SecurityException(
3271 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003272 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003273 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
3274 UserId.getUserId(uid));
3275 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003276 }
3277
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003278 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08003280 // Quick case: check if the top-most recent task is the same.
3281 if (N > 0 && mRecentTasks.get(0) == task) {
3282 return;
3283 }
3284 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 for (int i=0; i<N; i++) {
3286 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07003287 if (task.userId == tr.userId
3288 && ((task.affinity != null && task.affinity.equals(tr.affinity))
3289 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003290 mRecentTasks.remove(i);
3291 i--;
3292 N--;
3293 if (task.intent == null) {
3294 // If the new recent task we are adding is not fully
3295 // specified, then replace it with the existing recent task.
3296 task = tr;
3297 }
3298 }
3299 }
3300 if (N >= MAX_RECENT_TASKS) {
3301 mRecentTasks.remove(N-1);
3302 }
3303 mRecentTasks.add(0, task);
3304 }
3305
3306 public void setRequestedOrientation(IBinder token,
3307 int requestedOrientation) {
3308 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003309 ActivityRecord r = mMainStack.isInStackLocked(token);
3310 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 return;
3312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003313 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003314 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003316 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003317 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 if (config != null) {
3319 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08003320 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003321 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 }
3323 }
3324 Binder.restoreCallingIdentity(origId);
3325 }
3326 }
3327
3328 public int getRequestedOrientation(IBinder token) {
3329 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003330 ActivityRecord r = mMainStack.isInStackLocked(token);
3331 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3333 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08003334 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 }
3336 }
3337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 /**
3339 * This is the internal entry point for handling Activity.finish().
3340 *
3341 * @param token The Binder token referencing the Activity we want to finish.
3342 * @param resultCode Result code, if any, from this Activity.
3343 * @param resultData Result data (Intent), if any, from this Activity.
3344 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11003345 * @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 -08003346 */
3347 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3348 // Refuse possible leaked file descriptors
3349 if (resultData != null && resultData.hasFileDescriptors() == true) {
3350 throw new IllegalArgumentException("File descriptors passed in Intent");
3351 }
3352
3353 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003354 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003356 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 if (next != null) {
3358 // ask watcher if this is allowed
3359 boolean resumeOK = true;
3360 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003361 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003363 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003364 }
3365
3366 if (!resumeOK) {
3367 return false;
3368 }
3369 }
3370 }
3371 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003372 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 resultData, "app-request");
3374 Binder.restoreCallingIdentity(origId);
3375 return res;
3376 }
3377 }
3378
Dianne Hackborn860755f2010-06-03 18:47:52 -07003379 public final void finishHeavyWeightApp() {
3380 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3381 != PackageManager.PERMISSION_GRANTED) {
3382 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3383 + Binder.getCallingPid()
3384 + ", uid=" + Binder.getCallingUid()
3385 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3386 Slog.w(TAG, msg);
3387 throw new SecurityException(msg);
3388 }
3389
3390 synchronized(this) {
3391 if (mHeavyWeightProcess == null) {
3392 return;
3393 }
3394
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003395 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07003396 mHeavyWeightProcess.activities);
3397 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003398 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003399 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003400 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003401 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003402 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07003403 null, "finish-heavy");
3404 }
3405 }
3406 }
3407
3408 mHeavyWeightProcess = null;
3409 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3410 }
3411 }
3412
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003413 public void crashApplication(int uid, int initialPid, String packageName,
3414 String message) {
3415 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3416 != PackageManager.PERMISSION_GRANTED) {
3417 String msg = "Permission Denial: crashApplication() from pid="
3418 + Binder.getCallingPid()
3419 + ", uid=" + Binder.getCallingUid()
3420 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3421 Slog.w(TAG, msg);
3422 throw new SecurityException(msg);
3423 }
3424
3425 synchronized(this) {
3426 ProcessRecord proc = null;
3427
3428 // Figure out which process to kill. We don't trust that initialPid
3429 // still has any relation to current pids, so must scan through the
3430 // list.
3431 synchronized (mPidsSelfLocked) {
3432 for (int i=0; i<mPidsSelfLocked.size(); i++) {
3433 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003434 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003435 continue;
3436 }
3437 if (p.pid == initialPid) {
3438 proc = p;
3439 break;
3440 }
3441 for (String str : p.pkgList) {
3442 if (str.equals(packageName)) {
3443 proc = p;
3444 }
3445 }
3446 }
3447 }
3448
3449 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07003450 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003451 + " initialPid=" + initialPid
3452 + " packageName=" + packageName);
3453 return;
3454 }
3455
3456 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07003457 if (proc.pid == Process.myPid()) {
3458 Log.w(TAG, "crashApplication: trying to crash self!");
3459 return;
3460 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003461 long ident = Binder.clearCallingIdentity();
3462 try {
3463 proc.thread.scheduleCrash(message);
3464 } catch (RemoteException e) {
3465 }
3466 Binder.restoreCallingIdentity(ident);
3467 }
3468 }
3469 }
3470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 public final void finishSubActivity(IBinder token, String resultWho,
3472 int requestCode) {
3473 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003474 ActivityRecord self = mMainStack.isInStackLocked(token);
3475 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003476 return;
3477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003478
3479 final long origId = Binder.clearCallingIdentity();
3480
3481 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003482 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3483 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 if (r.resultTo == self && r.requestCode == requestCode) {
3485 if ((r.resultWho == null && resultWho == null) ||
3486 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003487 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 Activity.RESULT_CANCELED, null, "request-sub");
3489 }
3490 }
3491 }
3492
3493 Binder.restoreCallingIdentity(origId);
3494 }
3495 }
3496
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003497 public boolean willActivityBeVisible(IBinder token) {
3498 synchronized(this) {
3499 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003500 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3501 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08003502 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003503 return true;
3504 }
3505 if (r.fullscreen && !r.finishing) {
3506 return false;
3507 }
3508 }
3509 return true;
3510 }
3511 }
3512
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003513 public void overridePendingTransition(IBinder token, String packageName,
3514 int enterAnim, int exitAnim) {
3515 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003516 ActivityRecord self = mMainStack.isInStackLocked(token);
3517 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003518 return;
3519 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003520
3521 final long origId = Binder.clearCallingIdentity();
3522
3523 if (self.state == ActivityState.RESUMED
3524 || self.state == ActivityState.PAUSING) {
3525 mWindowManager.overridePendingAppTransition(packageName,
3526 enterAnim, exitAnim);
3527 }
3528
3529 Binder.restoreCallingIdentity(origId);
3530 }
3531 }
3532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 * Main function for removing an existing process from the activity manager
3535 * as a result of that process going away. Clears out all connections
3536 * to the process.
3537 */
3538 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003539 boolean restarting, boolean allowRestart) {
3540 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003542 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 }
3544
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003545 if (mProfileProc == app) {
3546 clearProfilerLocked();
3547 }
3548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 // Just in case...
Dianne Hackborncbb722e2012-02-07 18:33:49 -08003550 mMainStack.appDiedLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551
3552 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003553 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554
3555 boolean atTop = true;
3556 boolean hasVisibleActivities = false;
3557
3558 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003559 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003560 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003561 TAG, "Removing app " + app + " from history with " + i + " entries");
3562 while (i > 0) {
3563 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003564 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003565 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3567 if (r.app == app) {
3568 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003569 if (ActivityStack.DEBUG_ADD_REMOVE) {
3570 RuntimeException here = new RuntimeException("here");
3571 here.fillInStackTrace();
3572 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
3573 + ": haveState=" + r.haveState
3574 + " stateNotNeeded=" + r.stateNotNeeded
3575 + " finishing=" + r.finishing
3576 + " state=" + r.state, here);
3577 }
3578 if (!r.finishing) {
3579 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08003580 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3581 System.identityHashCode(r),
3582 r.task.taskId, r.shortComponentName,
3583 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003584 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003585 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003586 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003587 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003588 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003589 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003590 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003592 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593
3594 } else {
3595 // We have the current state for this activity, so
3596 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003597 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 TAG, "Keeping entry, setting app to null");
3599 if (r.visible) {
3600 hasVisibleActivities = true;
3601 }
3602 r.app = null;
3603 r.nowVisible = false;
3604 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003605 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
3606 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 r.icicle = null;
3608 }
3609 }
3610
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003611 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 }
3613 atTop = false;
3614 }
3615
3616 app.activities.clear();
3617
3618 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003619 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 + " running instrumentation " + app.instrumentationClass);
3621 Bundle info = new Bundle();
3622 info.putString("shortMsg", "Process crashed.");
3623 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3624 }
3625
3626 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003627 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 // If there was nothing to resume, and we are not already
3629 // restarting this process, but there is a visible activity that
3630 // is hosted by the process... then make sure all visible
3631 // activities are running, taking care of restarting this
3632 // process.
3633 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003634 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 }
3636 }
3637 }
3638 }
3639
3640 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3641 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003643 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3644 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3646 return i;
3647 }
3648 }
3649 return -1;
3650 }
3651
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003652 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 IApplicationThread thread) {
3654 if (thread == null) {
3655 return null;
3656 }
3657
3658 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003659 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 }
3661
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003662 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 IApplicationThread thread) {
3664
3665 mProcDeaths[0]++;
3666
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003667 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3668 synchronized (stats) {
3669 stats.noteProcessDiedLocked(app.info.uid, pid);
3670 }
3671
Magnus Edlund7bb25812010-02-24 15:45:06 +01003672 // Clean up already done if the process has been re-started.
3673 if (app.pid == pid && app.thread != null &&
3674 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07003675 if (!app.killedBackground) {
3676 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3677 + ") has died.");
3678 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08003679 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003680 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 TAG, "Dying app: " + app + ", pid: " + pid
3682 + ", thread: " + thread.asBinder());
3683 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003684 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685
3686 if (doLowMem) {
3687 // If there are no longer any background processes running,
3688 // and the app that died was not running instrumentation,
3689 // then tell everyone we are now low on memory.
3690 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003691 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3692 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07003693 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 haveBg = true;
3695 break;
3696 }
3697 }
3698
3699 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003700 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003701 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003702 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3703 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07003704 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003705 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3706 // The low memory report is overriding any current
3707 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003708 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07003709 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003710 rec.lastRequestedGc = 0;
3711 } else {
3712 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003714 rec.reportLowMemory = true;
3715 rec.lastLowMemory = now;
3716 mProcessesToGc.remove(rec);
3717 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 }
3719 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003720 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003721 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 }
3723 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003724 } else if (app.pid != pid) {
3725 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003727 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08003728 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003729 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003730 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 + thread.asBinder());
3732 }
3733 }
3734
Dan Egnor42471dd2010-01-07 17:25:22 -08003735 /**
3736 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003737 * @param clearTraces causes the dump file to be erased prior to the new
3738 * traces being written, if true; when false, the new traces will be
3739 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003740 * @param firstPids of dalvik VM processes to dump stack traces for first
3741 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08003742 * @return file containing stack traces, or null if no dump file is configured
3743 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003744 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3745 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003746 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3747 if (tracesPath == null || tracesPath.length() == 0) {
3748 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003750
3751 File tracesFile = new File(tracesPath);
3752 try {
3753 File tracesDir = tracesFile.getParentFile();
3754 if (!tracesDir.exists()) tracesFile.mkdirs();
3755 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3756
Christopher Tate6ee412d2010-05-28 12:01:56 -07003757 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003758 tracesFile.createNewFile();
3759 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3760 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003761 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003762 return null;
3763 }
3764
3765 // Use a FileObserver to detect when traces finish writing.
3766 // The order of traces is considered important to maintain for legibility.
3767 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3768 public synchronized void onEvent(int event, String path) { notify(); }
3769 };
3770
3771 try {
3772 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003773
3774 // First collect all of the stacks of the most important pids.
3775 try {
3776 int num = firstPids.size();
3777 for (int i = 0; i < num; i++) {
3778 synchronized (observer) {
3779 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3780 observer.wait(200); // Wait for write-close, give up after 200msec
3781 }
3782 }
3783 } catch (InterruptedException e) {
3784 Log.wtf(TAG, e);
3785 }
3786
3787 // Next measure CPU usage.
3788 if (processStats != null) {
3789 processStats.init();
3790 System.gc();
3791 processStats.update();
3792 try {
3793 synchronized (processStats) {
3794 processStats.wait(500); // measure over 1/2 second.
3795 }
3796 } catch (InterruptedException e) {
3797 }
3798 processStats.update();
3799
3800 // We'll take the stack crawls of just the top apps using CPU.
3801 final int N = processStats.countWorkingStats();
3802 int numProcs = 0;
3803 for (int i=0; i<N && numProcs<5; i++) {
3804 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3805 if (lastPids.indexOfKey(stats.pid) >= 0) {
3806 numProcs++;
3807 try {
3808 synchronized (observer) {
3809 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3810 observer.wait(200); // Wait for write-close, give up after 200msec
3811 }
3812 } catch (InterruptedException e) {
3813 Log.wtf(TAG, e);
3814 }
3815
3816 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003817 }
3818 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003819
3820 return tracesFile;
3821
Dan Egnor42471dd2010-01-07 17:25:22 -08003822 } finally {
3823 observer.stopWatching();
3824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 }
3826
Jeff Brown4d94a762010-09-23 11:33:28 -07003827 private final class AppNotResponding implements Runnable {
3828 private final ProcessRecord mApp;
3829 private final String mAnnotation;
3830
3831 public AppNotResponding(ProcessRecord app, String annotation) {
3832 mApp = app;
3833 mAnnotation = annotation;
3834 }
3835
3836 @Override
3837 public void run() {
3838 appNotResponding(mApp, null, null, mAnnotation);
3839 }
3840 }
3841
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003842 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3843 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003844 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3845 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3846
Dianne Hackborn287952c2010-09-22 22:34:31 -07003847 if (mController != null) {
3848 try {
3849 // 0 == continue, -1 = kill process immediately
3850 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3851 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3852 } catch (RemoteException e) {
3853 mController = null;
3854 }
3855 }
3856
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003857 long anrTime = SystemClock.uptimeMillis();
3858 if (MONITOR_CPU_USAGE) {
3859 updateCpuStatsNow();
3860 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003861
3862 synchronized (this) {
3863 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3864 if (mShuttingDown) {
3865 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3866 return;
3867 } else if (app.notResponding) {
3868 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3869 return;
3870 } else if (app.crashing) {
3871 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3872 return;
3873 }
3874
3875 // In case we come through here for the same app before completing
3876 // this one, mark as anring now so we will bail out.
3877 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003878
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003879 // Log the ANR to the event log.
3880 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3881 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003882
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003883 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003884 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003885
3886 int parentPid = app.pid;
3887 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003888 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003889
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003890 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003891
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003892 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3893 ProcessRecord r = mLruProcesses.get(i);
3894 if (r != null && r.thread != null) {
3895 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003896 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3897 if (r.persistent) {
3898 firstPids.add(pid);
3899 } else {
3900 lastPids.put(pid, Boolean.TRUE);
3901 }
3902 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003903 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 }
3905 }
3906
Dan Egnor42471dd2010-01-07 17:25:22 -08003907 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003908 StringBuilder info = mStringBuilder;
3909 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003910 info.append("ANR in ").append(app.processName);
3911 if (activity != null && activity.shortComponentName != null) {
3912 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003913 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003914 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003916 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003918 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003919 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921
Dianne Hackborn287952c2010-09-22 22:34:31 -07003922 final ProcessStats processStats = new ProcessStats(true);
3923
3924 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3925
Dan Egnor42471dd2010-01-07 17:25:22 -08003926 String cpuInfo = null;
3927 if (MONITOR_CPU_USAGE) {
3928 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003929 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003930 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003931 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003932 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003933 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003934 }
3935
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003936 info.append(processStats.printCurrentState(anrTime));
3937
Joe Onorato8a9b2202010-02-26 18:56:32 -08003938 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003939 if (tracesFile == null) {
3940 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3941 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3942 }
3943
Jeff Sharkeya353d262011-10-28 11:12:06 -07003944 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3945 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003946
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003947 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003949 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3950 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003952 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3953 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 }
3955 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003956 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 }
3958 }
3959
Dan Egnor42471dd2010-01-07 17:25:22 -08003960 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3961 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3962 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003963
3964 synchronized (this) {
3965 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003966 Slog.w(TAG, "Killing " + app + ": background ANR");
3967 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3968 app.processName, app.setAdj, "background ANR");
3969 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003970 return;
3971 }
3972
3973 // Set the app's notResponding state, and look up the errorReportReceiver
3974 makeAppNotRespondingLocked(app,
3975 activity != null ? activity.shortComponentName : null,
3976 annotation != null ? "ANR " + annotation : "ANR",
3977 info.toString());
3978
3979 // Bring up the infamous App Not Responding dialog
3980 Message msg = Message.obtain();
3981 HashMap map = new HashMap();
3982 msg.what = SHOW_NOT_RESPONDING_MSG;
3983 msg.obj = map;
3984 map.put("app", app);
3985 if (activity != null) {
3986 map.put("activity", activity);
3987 }
3988
3989 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 }
3992
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003993 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3994 if (!mLaunchWarningShown) {
3995 mLaunchWarningShown = true;
3996 mHandler.post(new Runnable() {
3997 @Override
3998 public void run() {
3999 synchronized (ActivityManagerService.this) {
4000 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4001 d.show();
4002 mHandler.postDelayed(new Runnable() {
4003 @Override
4004 public void run() {
4005 synchronized (ActivityManagerService.this) {
4006 d.dismiss();
4007 mLaunchWarningShown = false;
4008 }
4009 }
4010 }, 4000);
4011 }
4012 }
4013 });
4014 }
4015 }
4016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 public boolean clearApplicationUserData(final String packageName,
Amith Yamasani742a6712011-05-04 14:49:28 -07004018 final IPackageDataObserver observer, final int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004019 enforceNotIsolatedCaller("clearApplicationUserData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004020 int uid = Binder.getCallingUid();
4021 int pid = Binder.getCallingPid();
4022 long callingId = Binder.clearCallingIdentity();
4023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004024 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 int pkgUid = -1;
4026 synchronized(this) {
4027 try {
4028 pkgUid = pm.getPackageUid(packageName);
4029 } catch (RemoteException e) {
4030 }
4031 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004032 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 return false;
4034 }
4035 if (uid == pkgUid || checkComponentPermission(
4036 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004037 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004038 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004039 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004040 } else {
4041 throw new SecurityException(pid+" does not have permission:"+
4042 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4043 "for process:"+packageName);
4044 }
4045 }
4046
4047 try {
4048 //clear application user data
4049 pm.clearApplicationUserData(packageName, observer);
4050 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4051 Uri.fromParts("package", packageName, null));
4052 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004053 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07004054 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 } catch (RemoteException e) {
4056 }
4057 } finally {
4058 Binder.restoreCallingIdentity(callingId);
4059 }
4060 return true;
4061 }
4062
Dianne Hackborn03abb812010-01-04 18:43:19 -08004063 public void killBackgroundProcesses(final String packageName) {
4064 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4065 != PackageManager.PERMISSION_GRANTED &&
4066 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4067 != PackageManager.PERMISSION_GRANTED) {
4068 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004069 + Binder.getCallingPid()
4070 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08004071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004072 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 throw new SecurityException(msg);
4074 }
4075
4076 long callingId = Binder.clearCallingIdentity();
4077 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004078 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 int pkgUid = -1;
4080 synchronized(this) {
4081 try {
4082 pkgUid = pm.getPackageUid(packageName);
4083 } catch (RemoteException e) {
4084 }
4085 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004086 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 return;
4088 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004089 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004090 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4091 }
4092 } finally {
4093 Binder.restoreCallingIdentity(callingId);
4094 }
4095 }
4096
4097 public void killAllBackgroundProcesses() {
4098 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4099 != PackageManager.PERMISSION_GRANTED) {
4100 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4101 + Binder.getCallingPid()
4102 + ", uid=" + Binder.getCallingUid()
4103 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4104 Slog.w(TAG, msg);
4105 throw new SecurityException(msg);
4106 }
4107
4108 long callingId = Binder.clearCallingIdentity();
4109 try {
4110 synchronized(this) {
4111 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4112 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4113 final int NA = apps.size();
4114 for (int ia=0; ia<NA; ia++) {
4115 ProcessRecord app = apps.valueAt(ia);
4116 if (app.persistent) {
4117 // we don't kill persistent processes
4118 continue;
4119 }
4120 if (app.removed) {
4121 procs.add(app);
4122 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
4123 app.removed = true;
4124 procs.add(app);
4125 }
4126 }
4127 }
4128
4129 int N = procs.size();
4130 for (int i=0; i<N; i++) {
4131 removeProcessLocked(procs.get(i), false, true, "kill all background");
4132 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004133 }
4134 } finally {
4135 Binder.restoreCallingIdentity(callingId);
4136 }
4137 }
4138
4139 public void forceStopPackage(final String packageName) {
4140 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4141 != PackageManager.PERMISSION_GRANTED) {
4142 String msg = "Permission Denial: forceStopPackage() from pid="
4143 + Binder.getCallingPid()
4144 + ", uid=" + Binder.getCallingUid()
4145 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004146 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004147 throw new SecurityException(msg);
4148 }
Amith Yamasani742a6712011-05-04 14:49:28 -07004149 final int userId = Binder.getOrigCallingUser();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004150 long callingId = Binder.clearCallingIdentity();
4151 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004152 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004153 int pkgUid = -1;
4154 synchronized(this) {
4155 try {
4156 pkgUid = pm.getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07004157 // Convert the uid to the one for the calling user
4158 pkgUid = UserId.getUid(userId, pkgUid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004159 } catch (RemoteException e) {
4160 }
4161 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004162 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004163 return;
4164 }
4165 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004166 try {
4167 pm.setPackageStoppedState(packageName, true);
4168 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08004169 } catch (IllegalArgumentException e) {
4170 Slog.w(TAG, "Failed trying to unstop package "
4171 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004173 }
4174 } finally {
4175 Binder.restoreCallingIdentity(callingId);
4176 }
4177 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004178
4179 /*
4180 * The pkg name and uid have to be specified.
4181 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4182 */
4183 public void killApplicationWithUid(String pkg, int uid) {
4184 if (pkg == null) {
4185 return;
4186 }
4187 // Make sure the uid is valid.
4188 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004189 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004190 return;
4191 }
4192 int callerUid = Binder.getCallingUid();
4193 // Only the system server can kill an application
4194 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07004195 // Post an aysnc message to kill the application
4196 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4197 msg.arg1 = uid;
4198 msg.arg2 = 0;
4199 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07004200 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004201 } else {
4202 throw new SecurityException(callerUid + " cannot kill pkg: " +
4203 pkg);
4204 }
4205 }
4206
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004207 public void closeSystemDialogs(String reason) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004208 enforceNotIsolatedCaller("closeSystemDialogs");
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004209 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004210 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004211 if (reason != null) {
4212 intent.putExtra("reason", reason);
4213 }
4214
4215 final int uid = Binder.getCallingUid();
4216 final long origId = Binder.clearCallingIdentity();
4217 synchronized (this) {
Dianne Hackbornffa42482009-09-23 22:20:11 -07004218 mWindowManager.closeSystemDialogs(reason);
4219
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08004220 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004221 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004222 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004223 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07004224 Activity.RESULT_CANCELED, null, "close-sys");
4225 }
4226 }
4227
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004228 broadcastIntentLocked(null, null, intent, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004229 null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004230 }
4231 Binder.restoreCallingIdentity(origId);
4232 }
4233
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004234 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004235 throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004236 enforceNotIsolatedCaller("getProcessMemoryInfo");
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004237 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4238 for (int i=pids.length-1; i>=0; i--) {
4239 infos[i] = new Debug.MemoryInfo();
4240 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004241 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004242 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004243 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07004244
Dianne Hackbornb437e092011-08-05 17:50:29 -07004245 public long[] getProcessPss(int[] pids) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004246 enforceNotIsolatedCaller("getProcessPss");
Dianne Hackbornb437e092011-08-05 17:50:29 -07004247 long[] pss = new long[pids.length];
4248 for (int i=pids.length-1; i>=0; i--) {
4249 pss[i] = Debug.getPss(pids[i]);
4250 }
4251 return pss;
4252 }
4253
Christopher Tate5e1ab332009-09-01 20:32:49 -07004254 public void killApplicationProcess(String processName, int uid) {
4255 if (processName == null) {
4256 return;
4257 }
4258
4259 int callerUid = Binder.getCallingUid();
4260 // Only the system server can kill an application
4261 if (callerUid == Process.SYSTEM_UID) {
4262 synchronized (this) {
4263 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07004264 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07004265 try {
4266 app.thread.scheduleSuicide();
4267 } catch (RemoteException e) {
4268 // If the other end already died, then our work here is done.
4269 }
4270 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004271 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07004272 + processName + " / " + uid);
4273 }
4274 }
4275 } else {
4276 throw new SecurityException(callerUid + " cannot kill app process: " +
4277 processName);
4278 }
4279 }
4280
Dianne Hackborn03abb812010-01-04 18:43:19 -08004281 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004282 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4284 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004285 if (!mProcessesReady) {
4286 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 intent.putExtra(Intent.EXTRA_UID, uid);
4289 broadcastIntentLocked(null, null, intent,
4290 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004291 false, false,
4292 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 }
4294
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004295 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004296 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004297 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004298 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299
Dianne Hackborn03abb812010-01-04 18:43:19 -08004300 // Remove all processes this package may have touched: all with the
4301 // same UID (except for the system or root user), and all whose name
4302 // matches the package name.
4303 final String procNamePrefix = packageName + ":";
4304 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4305 final int NA = apps.size();
4306 for (int ia=0; ia<NA; ia++) {
4307 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07004308 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07004309 // we don't kill persistent processes
4310 continue;
4311 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004312 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004313 if (doit) {
4314 procs.add(app);
4315 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004316 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
4317 || app.processName.equals(packageName)
4318 || app.processName.startsWith(procNamePrefix)) {
4319 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004320 if (!doit) {
4321 return true;
4322 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004323 app.removed = true;
4324 procs.add(app);
4325 }
4326 }
4327 }
4328 }
4329
4330 int N = procs.size();
4331 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004332 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004333 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004334 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08004335 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004336
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004337 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004338 boolean callerWillRestart, boolean purgeCache, boolean doit,
4339 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004340 int i;
4341 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 if (uid < 0) {
4344 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004345 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004346 } catch (RemoteException e) {
4347 }
4348 }
4349
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004350 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004351 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004352
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004353 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
4354 while (badApps.hasNext()) {
4355 SparseArray<Long> ba = badApps.next();
4356 if (ba.get(uid) != null) {
4357 badApps.remove();
4358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 }
4360 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004361
4362 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004363 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004364
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004365 TaskRecord lastTask = null;
4366 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004367 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004368 final boolean samePackage = r.packageName.equals(name);
4369 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07004370 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004371 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07004372 if (r.finishing) {
4373 // If this activity is just finishing, then it is not
4374 // interesting as far as something to stop.
4375 continue;
4376 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004377 return true;
4378 }
4379 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004380 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004381 if (samePackage) {
4382 if (r.app != null) {
4383 r.app.removed = true;
4384 }
4385 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004387 lastTask = r.task;
4388 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
4389 null, "force-stop")) {
4390 i--;
4391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004392 }
4393 }
4394
4395 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07004396 int userId = UserId.getUserId(uid);
4397 for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
Christopher Tate064d8422011-07-26 15:38:07 -07004398 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07004399 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004400 if (!doit) {
4401 return true;
4402 }
4403 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004404 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 if (service.app != null) {
4406 service.app.removed = true;
4407 }
4408 service.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004409 service.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 services.add(service);
4411 }
4412 }
4413
4414 N = services.size();
4415 for (i=0; i<N; i++) {
4416 bringDownServiceLocked(services.get(i), true);
4417 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07004418
4419 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
Amith Yamasani37ce3a82012-02-06 12:04:42 -08004420 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(-1).values()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07004421 if (provider.info.packageName.equals(name)
4422 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
4423 if (!doit) {
4424 return true;
4425 }
4426 didSomething = true;
4427 providers.add(provider);
4428 }
4429 }
4430
4431 N = providers.size();
4432 for (i=0; i<N; i++) {
4433 removeDyingProviderLocked(null, providers.get(i));
4434 }
4435
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004436 if (doit) {
4437 if (purgeCache) {
4438 AttributeCache ac = AttributeCache.instance();
4439 if (ac != null) {
4440 ac.removePackage(name);
4441 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004442 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004443 if (mBooted) {
4444 mMainStack.resumeTopActivityLocked(null);
4445 mMainStack.scheduleIdleLocked();
4446 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004447 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004448
4449 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 }
4451
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004452 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004453 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004454 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004455 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004456 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004457 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 + "/" + uid + ")");
4459
4460 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004461 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004462 if (mHeavyWeightProcess == app) {
4463 mHeavyWeightProcess = null;
4464 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 boolean needRestart = false;
4467 if (app.pid > 0 && app.pid != MY_PID) {
4468 int pid = app.pid;
4469 synchronized (mPidsSelfLocked) {
4470 mPidsSelfLocked.remove(pid);
4471 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4472 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004473 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004474 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004475 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004476 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004478 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004480 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 } else {
4482 needRestart = true;
4483 }
4484 }
4485 } else {
4486 mRemovedProcesses.add(app);
4487 }
4488
4489 return needRestart;
4490 }
4491
4492 private final void processStartTimedOutLocked(ProcessRecord app) {
4493 final int pid = app.pid;
4494 boolean gone = false;
4495 synchronized (mPidsSelfLocked) {
4496 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4497 if (knownApp != null && knownApp.thread == null) {
4498 mPidsSelfLocked.remove(pid);
4499 gone = true;
4500 }
4501 }
4502
4503 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004504 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004505 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004506 app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004507 mProcessNames.remove(app.processName, app.uid);
4508 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004509 if (mHeavyWeightProcess == app) {
4510 mHeavyWeightProcess = null;
4511 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4512 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004513 // Take care of any launching providers waiting for this process.
4514 checkAppInLaunchingProvidersLocked(app, true);
4515 // Take care of any services that are waiting for the process.
4516 for (int i=0; i<mPendingServices.size(); i++) {
4517 ServiceRecord sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004518 if ((app.uid == sr.appInfo.uid
4519 && app.processName.equals(sr.processName))
4520 || sr.isolatedProc == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004521 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004522 sr.isolatedProc = null;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004523 mPendingServices.remove(i);
4524 i--;
4525 bringDownServiceLocked(sr, true);
4526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004527 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004528 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4529 app.processName, app.setAdj, "start timeout");
4530 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07004531 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004532 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07004533 try {
4534 IBackupManager bm = IBackupManager.Stub.asInterface(
4535 ServiceManager.getService(Context.BACKUP_SERVICE));
4536 bm.agentDisconnected(app.info.packageName);
4537 } catch (RemoteException e) {
4538 // Can't happen; the backup manager is local
4539 }
4540 }
Christopher Tatef46723b2012-01-26 14:19:24 -08004541 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004542 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08004543 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004546 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004547 }
4548 }
4549
4550 private final boolean attachApplicationLocked(IApplicationThread thread,
4551 int pid) {
4552
4553 // Find the application record that is being attached... either via
4554 // the pid if we are running in multiple processes, or just pull the
4555 // next app record if we are emulating process with anonymous threads.
4556 ProcessRecord app;
4557 if (pid != MY_PID && pid >= 0) {
4558 synchronized (mPidsSelfLocked) {
4559 app = mPidsSelfLocked.get(pid);
4560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 } else {
4562 app = null;
4563 }
4564
4565 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004566 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08004568 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004570 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 } else {
4572 try {
4573 thread.scheduleExit();
4574 } catch (Exception e) {
4575 // Ignore exceptions.
4576 }
4577 }
4578 return false;
4579 }
4580
4581 // If this application record is still attached to a previous
4582 // process, clean it up now.
4583 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004584 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004585 }
4586
4587 // Tell the process all about itself.
4588
Joe Onorato8a9b2202010-02-26 18:56:32 -08004589 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 TAG, "Binding process pid " + pid + " to record " + app);
4591
4592 String processName = app.processName;
4593 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004594 AppDeathRecipient adr = new AppDeathRecipient(
4595 app, pid, thread);
4596 thread.asBinder().linkToDeath(adr, 0);
4597 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 } catch (RemoteException e) {
4599 app.resetPackageList();
4600 startProcessLocked(app, "link fail", processName);
4601 return false;
4602 }
4603
Doug Zongker2bec3d42009-12-04 12:52:44 -08004604 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605
4606 app.thread = thread;
4607 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08004608 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4609 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 app.forcingToForeground = null;
4611 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07004612 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 app.debugging = false;
4614
4615 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4616
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004617 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004618 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004620 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004621 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004622 }
4623
Joe Onorato8a9b2202010-02-26 18:56:32 -08004624 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 TAG, "New app record " + app
4626 + " thread=" + thread.asBinder() + " pid=" + pid);
4627 try {
4628 int testMode = IApplicationThread.DEBUG_OFF;
4629 if (mDebugApp != null && mDebugApp.equals(processName)) {
4630 testMode = mWaitForDebugger
4631 ? IApplicationThread.DEBUG_WAIT
4632 : IApplicationThread.DEBUG_ON;
4633 app.debugging = true;
4634 if (mDebugTransient) {
4635 mDebugApp = mOrigDebugApp;
4636 mWaitForDebugger = mOrigWaitForDebugger;
4637 }
4638 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004639 String profileFile = app.instrumentationProfileFile;
4640 ParcelFileDescriptor profileFd = null;
4641 boolean profileAutoStop = false;
4642 if (mProfileApp != null && mProfileApp.equals(processName)) {
4643 mProfileProc = app;
4644 profileFile = mProfileFile;
4645 profileFd = mProfileFd;
4646 profileAutoStop = mAutoStopProfiler;
4647 }
4648
Christopher Tate181fafa2009-05-14 11:12:14 -07004649 // If the app is being launched for restore or full backup, set it up specially
4650 boolean isRestrictedBackupMode = false;
4651 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4652 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004653 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004654 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4655 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004656
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004657 ensurePackageDexOpt(app.instrumentationInfo != null
4658 ? app.instrumentationInfo.packageName
4659 : app.info.packageName);
4660 if (app.instrumentationClass != null) {
4661 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004662 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004663 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004664 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004665 ApplicationInfo appInfo = app.instrumentationInfo != null
4666 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004667 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004668 if (profileFd != null) {
4669 profileFd = profileFd.dup();
4670 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004671 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004672 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004673 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004674 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004675 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004676 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004677 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004678 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 } catch (Exception e) {
4680 // todo: Yikes! What should we do? For now we will try to
4681 // start another process, but that could easily get us in
4682 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004683 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684
4685 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004686 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 startProcessLocked(app, "bind fail", processName);
4688 return false;
4689 }
4690
4691 // Remove this record from the list of starting applications.
4692 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004693 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4694 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 mProcessesOnHold.remove(app);
4696
4697 boolean badApp = false;
4698 boolean didSomething = false;
4699
4700 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004701 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004702 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004703 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 && processName.equals(hr.processName)) {
4705 try {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004706 if (mHeadless) {
4707 Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4708 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 didSomething = true;
4710 }
4711 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004712 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 + hr.intent.getComponent().flattenToShortString(), e);
4714 badApp = true;
4715 }
4716 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004717 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 }
4719 }
4720
4721 // Find any services that should be running in this process...
4722 if (!badApp && mPendingServices.size() > 0) {
4723 ServiceRecord sr = null;
4724 try {
4725 for (int i=0; i<mPendingServices.size(); i++) {
4726 sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004727 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4728 || !processName.equals(sr.processName))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 continue;
4730 }
4731
4732 mPendingServices.remove(i);
4733 i--;
4734 realStartServiceLocked(sr, app);
4735 didSomething = true;
4736 }
4737 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004738 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 + sr.shortName, e);
4740 badApp = true;
4741 }
4742 }
4743
Christopher Tatef46723b2012-01-26 14:19:24 -08004744 // Check if a next-broadcast receiver is in this process...
4745 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004746 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004747 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004749 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 }
4752 }
4753
Christopher Tate181fafa2009-05-14 11:12:14 -07004754 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004755 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004756 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004757 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004758 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004759 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4760 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4761 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004762 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004763 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004764 e.printStackTrace();
4765 }
4766 }
4767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004768 if (badApp) {
4769 // todo: Also need to kill application to deal with all
4770 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004771 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004772 return false;
4773 }
4774
4775 if (!didSomething) {
4776 updateOomAdjLocked();
4777 }
4778
4779 return true;
4780 }
4781
4782 public final void attachApplication(IApplicationThread thread) {
4783 synchronized (this) {
4784 int callingPid = Binder.getCallingPid();
4785 final long origId = Binder.clearCallingIdentity();
4786 attachApplicationLocked(thread, callingPid);
4787 Binder.restoreCallingIdentity(origId);
4788 }
4789 }
4790
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004791 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004793 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4794 if (stopProfiling) {
4795 synchronized (this) {
4796 if (mProfileProc == r.app) {
4797 if (mProfileFd != null) {
4798 try {
4799 mProfileFd.close();
4800 } catch (IOException e) {
4801 }
4802 clearProfilerLocked();
4803 }
4804 }
4805 }
4806 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 Binder.restoreCallingIdentity(origId);
4808 }
4809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004810 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004811 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004812 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 mWindowManager.enableScreenAfterBoot();
4814 }
4815
Dianne Hackborn661cd522011-08-22 00:26:20 -07004816 public void showBootMessage(final CharSequence msg, final boolean always) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004817 enforceNotIsolatedCaller("showBootMessage");
Dianne Hackborn661cd522011-08-22 00:26:20 -07004818 mWindowManager.showBootMessage(msg, always);
4819 }
4820
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004821 public void dismissKeyguardOnNextActivity() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004822 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004823 synchronized (this) {
4824 mMainStack.dismissKeyguardOnNextActivityLocked();
4825 }
4826 }
4827
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004828 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004829 IntentFilter pkgFilter = new IntentFilter();
4830 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4831 pkgFilter.addDataScheme("package");
4832 mContext.registerReceiver(new BroadcastReceiver() {
4833 @Override
4834 public void onReceive(Context context, Intent intent) {
4835 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4836 if (pkgs != null) {
4837 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004838 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004839 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004840 setResultCode(Activity.RESULT_OK);
4841 return;
4842 }
4843 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004844 }
4845 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004846 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004847 }, pkgFilter);
4848
4849 synchronized (this) {
4850 // Ensure that any processes we had put on hold are now started
4851 // up.
4852 final int NP = mProcessesOnHold.size();
4853 if (NP > 0) {
4854 ArrayList<ProcessRecord> procs =
4855 new ArrayList<ProcessRecord>(mProcessesOnHold);
4856 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004857 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4858 + procs.get(ip));
4859 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004860 }
4861 }
4862
4863 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004864 // Start looking for apps that are abusing wake locks.
4865 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004866 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004867 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004868 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004869 SystemProperties.set("dev.bootcomplete", "1");
Amith Yamasani742a6712011-05-04 14:49:28 -07004870 /* TODO: Send this to all users that are to be logged in on startup */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004871 broadcastIntentLocked(null, null,
4872 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4873 null, null, 0, null, null,
4874 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Amith Yamasani742a6712011-05-04 14:49:28 -07004875 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004876 }
4877 }
4878 }
4879
4880 final void ensureBootCompleted() {
4881 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004882 boolean enableScreen;
4883 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004884 booting = mBooting;
4885 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004886 enableScreen = !mBooted;
4887 mBooted = true;
4888 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004889
4890 if (booting) {
4891 finishBooting();
4892 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004893
4894 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004895 enableScreenAfterBoot();
4896 }
4897 }
4898
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004899 public final void activityPaused(IBinder token) {
4900 final long origId = Binder.clearCallingIdentity();
4901 mMainStack.activityPaused(token, false);
4902 Binder.restoreCallingIdentity(origId);
4903 }
4904
4905 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4906 CharSequence description) {
4907 if (localLOGV) Slog.v(
4908 TAG, "Activity stopped: token=" + token);
4909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 // Refuse possible leaked file descriptors
4911 if (icicle != null && icicle.hasFileDescriptors()) {
4912 throw new IllegalArgumentException("File descriptors passed in Bundle");
4913 }
4914
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004915 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916
4917 final long origId = Binder.clearCallingIdentity();
4918
4919 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004920 r = mMainStack.isInStackLocked(token);
4921 if (r != null) {
4922 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923 }
4924 }
4925
4926 if (r != null) {
4927 sendPendingThumbnail(r, null, null, null, false);
4928 }
4929
4930 trimApplications();
4931
4932 Binder.restoreCallingIdentity(origId);
4933 }
4934
4935 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004936 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004937 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 }
4939
4940 public String getCallingPackage(IBinder token) {
4941 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004942 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004943 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004944 }
4945 }
4946
4947 public ComponentName getCallingActivity(IBinder token) {
4948 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004949 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950 return r != null ? r.intent.getComponent() : null;
4951 }
4952 }
4953
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004954 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004955 ActivityRecord r = mMainStack.isInStackLocked(token);
4956 if (r == null) {
4957 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004959 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004960 }
4961
4962 public ComponentName getActivityClassForToken(IBinder token) {
4963 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004964 ActivityRecord r = mMainStack.isInStackLocked(token);
4965 if (r == null) {
4966 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004967 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004968 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 }
4970 }
4971
4972 public String getPackageForToken(IBinder token) {
4973 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004974 ActivityRecord r = mMainStack.isInStackLocked(token);
4975 if (r == null) {
4976 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004977 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004978 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004979 }
4980 }
4981
4982 public IIntentSender getIntentSender(int type,
4983 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004984 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004985 enforceNotIsolatedCaller("getIntentSender");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004987 if (intents != null) {
4988 if (intents.length < 1) {
4989 throw new IllegalArgumentException("Intents array length must be >= 1");
4990 }
4991 for (int i=0; i<intents.length; i++) {
4992 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004993 if (intent != null) {
4994 if (intent.hasFileDescriptors()) {
4995 throw new IllegalArgumentException("File descriptors passed in Intent");
4996 }
4997 if (type == INTENT_SENDER_BROADCAST &&
4998 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4999 throw new IllegalArgumentException(
5000 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5001 }
5002 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005003 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005004 }
5005 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005006 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005007 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005008 }
5009 }
5010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 synchronized(this) {
5012 int callingUid = Binder.getCallingUid();
5013 try {
Jeff Brown10e89712011-07-08 18:52:57 -07005014 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005015 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005016 .getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07005017 if (UserId.getAppId(callingUid) != uid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005018 String msg = "Permission Denial: getIntentSender() from pid="
5019 + Binder.getCallingPid()
5020 + ", uid=" + Binder.getCallingUid()
5021 + ", (need uid=" + uid + ")"
5022 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005023 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 throw new SecurityException(msg);
5025 }
5026 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005027
Amith Yamasani742a6712011-05-04 14:49:28 -07005028 if (DEBUG_MU)
5029 Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
5030 + Binder.getOrigCallingUid());
5031 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005032 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005034 } catch (RemoteException e) {
5035 throw new SecurityException(e);
5036 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005037 }
5038 }
5039
5040 IIntentSender getIntentSenderLocked(int type,
5041 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005042 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07005043 if (DEBUG_MU)
5044 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005045 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07005046 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005047 activity = mMainStack.isInStackLocked(token);
5048 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005049 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005050 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005051 if (activity.finishing) {
5052 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005054 }
5055
5056 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5057 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5058 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5059 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5060 |PendingIntent.FLAG_UPDATE_CURRENT);
5061
5062 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5063 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005064 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005065 WeakReference<PendingIntentRecord> ref;
5066 ref = mIntentSenderRecords.get(key);
5067 PendingIntentRecord rec = ref != null ? ref.get() : null;
5068 if (rec != null) {
5069 if (!cancelCurrent) {
5070 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005071 if (rec.key.requestIntent != null) {
5072 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
5073 }
5074 if (intents != null) {
5075 intents[intents.length-1] = rec.key.requestIntent;
5076 rec.key.allIntents = intents;
5077 rec.key.allResolvedTypes = resolvedTypes;
5078 } else {
5079 rec.key.allIntents = null;
5080 rec.key.allResolvedTypes = null;
5081 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005083 return rec;
5084 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005085 rec.canceled = true;
5086 mIntentSenderRecords.remove(key);
5087 }
5088 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005089 return rec;
5090 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005091 rec = new PendingIntentRecord(this, key, callingUid);
5092 mIntentSenderRecords.put(key, rec.ref);
5093 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5094 if (activity.pendingResults == null) {
5095 activity.pendingResults
5096 = new HashSet<WeakReference<PendingIntentRecord>>();
5097 }
5098 activity.pendingResults.add(rec.ref);
5099 }
5100 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005101 }
5102
5103 public void cancelIntentSender(IIntentSender sender) {
5104 if (!(sender instanceof PendingIntentRecord)) {
5105 return;
5106 }
5107 synchronized(this) {
5108 PendingIntentRecord rec = (PendingIntentRecord)sender;
5109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005110 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005111 .getPackageUid(rec.key.packageName);
5112 if (uid != Binder.getCallingUid()) {
5113 String msg = "Permission Denial: cancelIntentSender() from pid="
5114 + Binder.getCallingPid()
5115 + ", uid=" + Binder.getCallingUid()
5116 + " is not allowed to cancel packges "
5117 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005118 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005119 throw new SecurityException(msg);
5120 }
5121 } catch (RemoteException e) {
5122 throw new SecurityException(e);
5123 }
5124 cancelIntentSenderLocked(rec, true);
5125 }
5126 }
5127
5128 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5129 rec.canceled = true;
5130 mIntentSenderRecords.remove(rec.key);
5131 if (cleanActivity && rec.key.activity != null) {
5132 rec.key.activity.pendingResults.remove(rec.ref);
5133 }
5134 }
5135
5136 public String getPackageForIntentSender(IIntentSender pendingResult) {
5137 if (!(pendingResult instanceof PendingIntentRecord)) {
5138 return null;
5139 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07005140 try {
5141 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5142 return res.key.packageName;
5143 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005144 }
5145 return null;
5146 }
5147
Dianne Hackborn6c418d52011-06-29 14:05:33 -07005148 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5149 if (!(pendingResult instanceof PendingIntentRecord)) {
5150 return false;
5151 }
5152 try {
5153 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5154 if (res.key.allIntents == null) {
5155 return false;
5156 }
5157 for (int i=0; i<res.key.allIntents.length; i++) {
5158 Intent intent = res.key.allIntents[i];
5159 if (intent.getPackage() != null && intent.getComponent() != null) {
5160 return false;
5161 }
5162 }
5163 return true;
5164 } catch (ClassCastException e) {
5165 }
5166 return false;
5167 }
5168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005169 public void setProcessLimit(int max) {
5170 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5171 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005172 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005173 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005174 mProcessLimitOverride = max;
5175 }
5176 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005177 }
5178
5179 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005180 synchronized (this) {
5181 return mProcessLimitOverride;
5182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183 }
5184
5185 void foregroundTokenDied(ForegroundToken token) {
5186 synchronized (ActivityManagerService.this) {
5187 synchronized (mPidsSelfLocked) {
5188 ForegroundToken cur
5189 = mForegroundProcesses.get(token.pid);
5190 if (cur != token) {
5191 return;
5192 }
5193 mForegroundProcesses.remove(token.pid);
5194 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5195 if (pr == null) {
5196 return;
5197 }
5198 pr.forcingToForeground = null;
5199 pr.foregroundServices = false;
5200 }
5201 updateOomAdjLocked();
5202 }
5203 }
5204
5205 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5206 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5207 "setProcessForeground()");
5208 synchronized(this) {
5209 boolean changed = false;
5210
5211 synchronized (mPidsSelfLocked) {
5212 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005213 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005214 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 return;
5216 }
5217 ForegroundToken oldToken = mForegroundProcesses.get(pid);
5218 if (oldToken != null) {
5219 oldToken.token.unlinkToDeath(oldToken, 0);
5220 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005221 if (pr != null) {
5222 pr.forcingToForeground = null;
5223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 changed = true;
5225 }
5226 if (isForeground && token != null) {
5227 ForegroundToken newToken = new ForegroundToken() {
5228 public void binderDied() {
5229 foregroundTokenDied(this);
5230 }
5231 };
5232 newToken.pid = pid;
5233 newToken.token = token;
5234 try {
5235 token.linkToDeath(newToken, 0);
5236 mForegroundProcesses.put(pid, newToken);
5237 pr.forcingToForeground = token;
5238 changed = true;
5239 } catch (RemoteException e) {
5240 // If the process died while doing this, we will later
5241 // do the cleanup with the process death link.
5242 }
5243 }
5244 }
5245
5246 if (changed) {
5247 updateOomAdjLocked();
5248 }
5249 }
5250 }
5251
5252 // =========================================================
5253 // PERMISSIONS
5254 // =========================================================
5255
5256 static class PermissionController extends IPermissionController.Stub {
5257 ActivityManagerService mActivityManagerService;
5258 PermissionController(ActivityManagerService activityManagerService) {
5259 mActivityManagerService = activityManagerService;
5260 }
5261
5262 public boolean checkPermission(String permission, int pid, int uid) {
5263 return mActivityManagerService.checkPermission(permission, pid,
5264 uid) == PackageManager.PERMISSION_GRANTED;
5265 }
5266 }
5267
5268 /**
5269 * This can be called with or without the global lock held.
5270 */
5271 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005272 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005273 // We might be performing an operation on behalf of an indirect binder
5274 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
5275 // client identity accordingly before proceeding.
5276 Identity tlsIdentity = sCallerIdentity.get();
5277 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005278 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5280 uid = tlsIdentity.uid;
5281 pid = tlsIdentity.pid;
5282 }
5283
5284 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005285 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005286 return PackageManager.PERMISSION_GRANTED;
5287 }
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005288 // Isolated processes don't get any permissions.
5289 if (UserId.isIsolated(uid)) {
5290 return PackageManager.PERMISSION_DENIED;
5291 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005292 // If there is a uid that owns whatever is being accessed, it has
5293 // blanket access to it regardless of the permissions it requires.
Amith Yamasani742a6712011-05-04 14:49:28 -07005294 if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005295 return PackageManager.PERMISSION_GRANTED;
5296 }
5297 // If the target is not exported, then nobody else can get to it.
5298 if (!exported) {
5299 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005300 return PackageManager.PERMISSION_DENIED;
5301 }
5302 if (permission == null) {
5303 return PackageManager.PERMISSION_GRANTED;
5304 }
5305 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005306 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 .checkUidPermission(permission, uid);
5308 } catch (RemoteException e) {
5309 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08005310 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 }
5312 return PackageManager.PERMISSION_DENIED;
5313 }
5314
5315 /**
5316 * As the only public entry point for permissions checking, this method
5317 * can enforce the semantic that requesting a check on a null global
5318 * permission is automatically denied. (Internally a null permission
5319 * string is used when calling {@link #checkComponentPermission} in cases
5320 * when only uid-based security is needed.)
5321 *
5322 * This can be called with or without the global lock held.
5323 */
5324 public int checkPermission(String permission, int pid, int uid) {
5325 if (permission == null) {
5326 return PackageManager.PERMISSION_DENIED;
5327 }
Amith Yamasani742a6712011-05-04 14:49:28 -07005328 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 }
5330
5331 /**
5332 * Binder IPC calls go through the public entry point.
5333 * This can be called with or without the global lock held.
5334 */
5335 int checkCallingPermission(String permission) {
5336 return checkPermission(permission,
5337 Binder.getCallingPid(),
Amith Yamasani742a6712011-05-04 14:49:28 -07005338 UserId.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005339 }
5340
5341 /**
5342 * This can be called with or without the global lock held.
5343 */
5344 void enforceCallingPermission(String permission, String func) {
5345 if (checkCallingPermission(permission)
5346 == PackageManager.PERMISSION_GRANTED) {
5347 return;
5348 }
5349
5350 String msg = "Permission Denial: " + func + " from pid="
5351 + Binder.getCallingPid()
5352 + ", uid=" + Binder.getCallingUid()
5353 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005354 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 throw new SecurityException(msg);
5356 }
5357
5358 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07005359 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5360 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5361 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5362 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5363 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07005365 // Is the component private from the target uid?
5366 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
5367
5368 // Acceptable if the there is no read permission needed from the
5369 // target or the target is holding the read permission.
5370 if (!readPerm) {
5371 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005373 == PackageManager.PERMISSION_GRANTED)) {
5374 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 }
5376 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005377
5378 // Acceptable if the there is no write permission needed from the
5379 // target or the target is holding the read permission.
5380 if (!writePerm) {
5381 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005383 == PackageManager.PERMISSION_GRANTED)) {
5384 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005385 }
5386 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005387
5388 // Acceptable if there is a path permission matching the URI that
5389 // the target holds the permission on.
5390 PathPermission[] pps = pi.pathPermissions;
5391 if (pps != null && (!readPerm || !writePerm)) {
5392 final String path = uri.getPath();
5393 int i = pps.length;
5394 while (i > 0 && (!readPerm || !writePerm)) {
5395 i--;
5396 PathPermission pp = pps[i];
5397 if (!readPerm) {
5398 final String pprperm = pp.getReadPermission();
5399 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5400 + pprperm + " for " + pp.getPath()
5401 + ": match=" + pp.match(path)
5402 + " check=" + pm.checkUidPermission(pprperm, uid));
5403 if (pprperm != null && pp.match(path) &&
5404 (pm.checkUidPermission(pprperm, uid)
5405 == PackageManager.PERMISSION_GRANTED)) {
5406 readPerm = true;
5407 }
5408 }
5409 if (!writePerm) {
5410 final String ppwperm = pp.getWritePermission();
5411 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5412 + ppwperm + " for " + pp.getPath()
5413 + ": match=" + pp.match(path)
5414 + " check=" + pm.checkUidPermission(ppwperm, uid));
5415 if (ppwperm != null && pp.match(path) &&
5416 (pm.checkUidPermission(ppwperm, uid)
5417 == PackageManager.PERMISSION_GRANTED)) {
5418 writePerm = true;
5419 }
5420 }
5421 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 } catch (RemoteException e) {
5424 return false;
5425 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005426
5427 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 }
5429
5430 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5431 int modeFlags) {
5432 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005433 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 return true;
5435 }
5436 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5437 if (perms == null) return false;
5438 UriPermission perm = perms.get(uri);
5439 if (perm == null) return false;
5440 return (modeFlags&perm.modeFlags) == modeFlags;
5441 }
5442
5443 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005444 enforceNotIsolatedCaller("checkUriPermission");
5445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 // Another redirected-binder-call permissions check as in
5447 // {@link checkComponentPermission}.
5448 Identity tlsIdentity = sCallerIdentity.get();
5449 if (tlsIdentity != null) {
5450 uid = tlsIdentity.uid;
5451 pid = tlsIdentity.pid;
5452 }
5453
Amith Yamasani742a6712011-05-04 14:49:28 -07005454 uid = UserId.getAppId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005455 // Our own process gets to do everything.
5456 if (pid == MY_PID) {
5457 return PackageManager.PERMISSION_GRANTED;
5458 }
5459 synchronized(this) {
5460 return checkUriPermissionLocked(uri, uid, modeFlags)
5461 ? PackageManager.PERMISSION_GRANTED
5462 : PackageManager.PERMISSION_DENIED;
5463 }
5464 }
5465
Dianne Hackborn39792d22010-08-19 18:01:52 -07005466 /**
5467 * Check if the targetPkg can be granted permission to access uri by
5468 * the callingUid using the given modeFlags. Throws a security exception
5469 * if callingUid is not allowed to do this. Returns the uid of the target
5470 * if the URI permission grant should be performed; returns -1 if it is not
5471 * needed (for example targetPkg already has permission to access the URI).
5472 */
5473 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5474 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5476 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5477 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005478 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 }
5480
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005481 if (targetPkg != null) {
5482 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5483 "Checking grant " + targetPkg + " permission to " + uri);
5484 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005485
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005486 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487
5488 // If this is not a content: uri, we can't do anything with it.
5489 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005490 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005491 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005492 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 }
5494
5495 String name = uri.getAuthority();
5496 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005497 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5498 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005499 if (cpr != null) {
5500 pi = cpr.info;
5501 } else {
5502 try {
5503 pi = pm.resolveContentProvider(name,
5504 PackageManager.GET_URI_PERMISSION_PATTERNS);
5505 } catch (RemoteException ex) {
5506 }
5507 }
5508 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005509 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07005510 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005511 }
5512
5513 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005514 if (targetPkg != null) {
5515 try {
5516 targetUid = pm.getPackageUid(targetPkg);
5517 if (targetUid < 0) {
5518 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5519 "Can't grant URI permission no uid for: " + targetPkg);
5520 return -1;
5521 }
5522 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005523 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005524 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005525 } else {
5526 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005527 }
5528
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005529 if (targetUid >= 0) {
5530 // First... does the target actually need this permission?
5531 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5532 // No need to grant the target this permission.
5533 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5534 "Target " + targetPkg + " already has full permission to " + uri);
5535 return -1;
5536 }
5537 } else {
5538 // First... there is no target package, so can anyone access it?
5539 boolean allowed = pi.exported;
5540 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5541 if (pi.readPermission != null) {
5542 allowed = false;
5543 }
5544 }
5545 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5546 if (pi.writePermission != null) {
5547 allowed = false;
5548 }
5549 }
5550 if (allowed) {
5551 return -1;
5552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005553 }
5554
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005555 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005556 if (!pi.grantUriPermissions) {
5557 throw new SecurityException("Provider " + pi.packageName
5558 + "/" + pi.name
5559 + " does not allow granting of Uri permissions (uri "
5560 + uri + ")");
5561 }
5562 if (pi.uriPermissionPatterns != null) {
5563 final int N = pi.uriPermissionPatterns.length;
5564 boolean allowed = false;
5565 for (int i=0; i<N; i++) {
5566 if (pi.uriPermissionPatterns[i] != null
5567 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5568 allowed = true;
5569 break;
5570 }
5571 }
5572 if (!allowed) {
5573 throw new SecurityException("Provider " + pi.packageName
5574 + "/" + pi.name
5575 + " does not allow granting of permission to path of Uri "
5576 + uri);
5577 }
5578 }
5579
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005580 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005582 if (callingUid != Process.myUid()) {
5583 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5584 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5585 throw new SecurityException("Uid " + callingUid
5586 + " does not have permission to uri " + uri);
5587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005588 }
5589 }
5590
Dianne Hackborn39792d22010-08-19 18:01:52 -07005591 return targetUid;
5592 }
5593
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005594 public int checkGrantUriPermission(int callingUid, String targetPkg,
5595 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005596 enforceNotIsolatedCaller("checkGrantUriPermission");
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005597 synchronized(this) {
5598 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5599 }
5600 }
5601
Dianne Hackborn39792d22010-08-19 18:01:52 -07005602 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5603 Uri uri, int modeFlags, UriPermissionOwner owner) {
5604 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5605 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5606 if (modeFlags == 0) {
5607 return;
5608 }
5609
5610 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005611 // to the uri, and the target doesn't. Let's now give this to
5612 // the target.
5613
Joe Onorato8a9b2202010-02-26 18:56:32 -08005614 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005615 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 HashMap<Uri, UriPermission> targetUris
5618 = mGrantedUriPermissions.get(targetUid);
5619 if (targetUris == null) {
5620 targetUris = new HashMap<Uri, UriPermission>();
5621 mGrantedUriPermissions.put(targetUid, targetUris);
5622 }
5623
5624 UriPermission perm = targetUris.get(uri);
5625 if (perm == null) {
5626 perm = new UriPermission(targetUid, uri);
5627 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005631 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005632 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005633 } else {
5634 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5635 perm.readOwners.add(owner);
5636 owner.addReadPermission(perm);
5637 }
5638 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5639 perm.writeOwners.add(owner);
5640 owner.addWritePermission(perm);
5641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005642 }
5643 }
5644
Dianne Hackborn39792d22010-08-19 18:01:52 -07005645 void grantUriPermissionLocked(int callingUid,
5646 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005647 if (targetPkg == null) {
5648 throw new NullPointerException("targetPkg");
5649 }
5650
Dianne Hackborn39792d22010-08-19 18:01:52 -07005651 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5652 if (targetUid < 0) {
5653 return;
5654 }
5655
5656 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5657 }
5658
5659 /**
5660 * Like checkGrantUriPermissionLocked, but takes an Intent.
5661 */
5662 int checkGrantUriPermissionFromIntentLocked(int callingUid,
5663 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005664 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005665 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005666 + " from " + intent + "; flags=0x"
5667 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5668
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005669 if (targetPkg == null) {
5670 throw new NullPointerException("targetPkg");
5671 }
5672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005674 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 }
5676 Uri data = intent.getData();
5677 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005678 return -1;
5679 }
5680 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5681 intent.getFlags());
5682 }
5683
5684 /**
5685 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5686 */
5687 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
5688 String targetPkg, Intent intent, UriPermissionOwner owner) {
5689 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
5690 intent.getFlags(), owner);
5691 }
5692
5693 void grantUriPermissionFromIntentLocked(int callingUid,
5694 String targetPkg, Intent intent, UriPermissionOwner owner) {
5695 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
5696 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 return;
5698 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005699
5700 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005701 }
5702
5703 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5704 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005705 enforceNotIsolatedCaller("grantUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 synchronized(this) {
5707 final ProcessRecord r = getRecordForAppLocked(caller);
5708 if (r == null) {
5709 throw new SecurityException("Unable to find app for caller "
5710 + caller
5711 + " when granting permission to uri " + uri);
5712 }
5713 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005714 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005715 }
5716 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005717 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 }
5719
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005720 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 null);
5722 }
5723 }
5724
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005725 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5727 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5728 HashMap<Uri, UriPermission> perms
5729 = mGrantedUriPermissions.get(perm.uid);
5730 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005731 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005732 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005733 perms.remove(perm.uri);
5734 if (perms.size() == 0) {
5735 mGrantedUriPermissions.remove(perm.uid);
5736 }
5737 }
5738 }
5739 }
5740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5742 int modeFlags) {
5743 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5744 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5745 if (modeFlags == 0) {
5746 return;
5747 }
5748
Joe Onorato8a9b2202010-02-26 18:56:32 -08005749 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005750 "Revoking all granted permissions to " + uri);
5751
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005752 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753
5754 final String authority = uri.getAuthority();
5755 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005756 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority,
5757 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758 if (cpr != null) {
5759 pi = cpr.info;
5760 } else {
5761 try {
5762 pi = pm.resolveContentProvider(authority,
5763 PackageManager.GET_URI_PERMISSION_PATTERNS);
5764 } catch (RemoteException ex) {
5765 }
5766 }
5767 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005768 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005769 return;
5770 }
5771
5772 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005773 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 // Right now, if you are not the original owner of the permission,
5775 // you are not allowed to revoke it.
5776 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5777 throw new SecurityException("Uid " + callingUid
5778 + " does not have permission to uri " + uri);
5779 //}
5780 }
5781
5782 // Go through all of the permissions and remove any that match.
5783 final List<String> SEGMENTS = uri.getPathSegments();
5784 if (SEGMENTS != null) {
5785 final int NS = SEGMENTS.size();
5786 int N = mGrantedUriPermissions.size();
5787 for (int i=0; i<N; i++) {
5788 HashMap<Uri, UriPermission> perms
5789 = mGrantedUriPermissions.valueAt(i);
5790 Iterator<UriPermission> it = perms.values().iterator();
5791 toploop:
5792 while (it.hasNext()) {
5793 UriPermission perm = it.next();
5794 Uri targetUri = perm.uri;
5795 if (!authority.equals(targetUri.getAuthority())) {
5796 continue;
5797 }
5798 List<String> targetSegments = targetUri.getPathSegments();
5799 if (targetSegments == null) {
5800 continue;
5801 }
5802 if (targetSegments.size() < NS) {
5803 continue;
5804 }
5805 for (int j=0; j<NS; j++) {
5806 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5807 continue toploop;
5808 }
5809 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005810 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005811 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 perm.clearModes(modeFlags);
5813 if (perm.modeFlags == 0) {
5814 it.remove();
5815 }
5816 }
5817 if (perms.size() == 0) {
5818 mGrantedUriPermissions.remove(
5819 mGrantedUriPermissions.keyAt(i));
5820 N--;
5821 i--;
5822 }
5823 }
5824 }
5825 }
5826
5827 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5828 int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005829 enforceNotIsolatedCaller("revokeUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 synchronized(this) {
5831 final ProcessRecord r = getRecordForAppLocked(caller);
5832 if (r == null) {
5833 throw new SecurityException("Unable to find app for caller "
5834 + caller
5835 + " when revoking permission to uri " + uri);
5836 }
5837 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005838 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 return;
5840 }
5841
5842 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5843 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5844 if (modeFlags == 0) {
5845 return;
5846 }
5847
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005848 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005849
5850 final String authority = uri.getAuthority();
5851 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005852 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005853 if (cpr != null) {
5854 pi = cpr.info;
5855 } else {
5856 try {
5857 pi = pm.resolveContentProvider(authority,
5858 PackageManager.GET_URI_PERMISSION_PATTERNS);
5859 } catch (RemoteException ex) {
5860 }
5861 }
5862 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005863 Slog.w(TAG, "No content provider found for permission revoke: "
5864 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 return;
5866 }
5867
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005868 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 }
5870 }
5871
Dianne Hackborn7e269642010-08-25 19:50:20 -07005872 @Override
5873 public IBinder newUriPermissionOwner(String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005874 enforceNotIsolatedCaller("newUriPermissionOwner");
Dianne Hackborn7e269642010-08-25 19:50:20 -07005875 synchronized(this) {
5876 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5877 return owner.getExternalTokenLocked();
5878 }
5879 }
5880
5881 @Override
5882 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5883 Uri uri, int modeFlags) {
5884 synchronized(this) {
5885 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5886 if (owner == null) {
5887 throw new IllegalArgumentException("Unknown owner: " + token);
5888 }
5889 if (fromUid != Binder.getCallingUid()) {
5890 if (Binder.getCallingUid() != Process.myUid()) {
5891 // Only system code can grant URI permissions on behalf
5892 // of other users.
5893 throw new SecurityException("nice try");
5894 }
5895 }
5896 if (targetPkg == null) {
5897 throw new IllegalArgumentException("null target");
5898 }
5899 if (uri == null) {
5900 throw new IllegalArgumentException("null uri");
5901 }
5902
5903 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5904 }
5905 }
5906
5907 @Override
5908 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5909 synchronized(this) {
5910 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5911 if (owner == null) {
5912 throw new IllegalArgumentException("Unknown owner: " + token);
5913 }
5914
5915 if (uri == null) {
5916 owner.removeUriPermissionsLocked(mode);
5917 } else {
5918 owner.removeUriPermissionLocked(uri, mode);
5919 }
5920 }
5921 }
5922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005923 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5924 synchronized (this) {
5925 ProcessRecord app =
5926 who != null ? getRecordForAppLocked(who) : null;
5927 if (app == null) return;
5928
5929 Message msg = Message.obtain();
5930 msg.what = WAIT_FOR_DEBUGGER_MSG;
5931 msg.obj = app;
5932 msg.arg1 = waiting ? 1 : 0;
5933 mHandler.sendMessage(msg);
5934 }
5935 }
5936
5937 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005938 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5939 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005940 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005941 outInfo.threshold = homeAppMem;
5942 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5943 outInfo.hiddenAppThreshold = hiddenAppMem;
5944 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005945 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005946 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5947 ProcessList.VISIBLE_APP_ADJ);
5948 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5949 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 }
5951
5952 // =========================================================
5953 // TASK MANAGEMENT
5954 // =========================================================
5955
5956 public List getTasks(int maxNum, int flags,
5957 IThumbnailReceiver receiver) {
5958 ArrayList list = new ArrayList();
5959
5960 PendingThumbnailsRecord pending = null;
5961 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005962 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005963
5964 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005965 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005966 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5967 + ", receiver=" + receiver);
5968
5969 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5970 != PackageManager.PERMISSION_GRANTED) {
5971 if (receiver != null) {
5972 // If the caller wants to wait for pending thumbnails,
5973 // it ain't gonna get them.
5974 try {
5975 receiver.finished();
5976 } catch (RemoteException ex) {
5977 }
5978 }
5979 String msg = "Permission Denial: getTasks() from pid="
5980 + Binder.getCallingPid()
5981 + ", uid=" + Binder.getCallingUid()
5982 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005983 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005984 throw new SecurityException(msg);
5985 }
5986
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005987 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005988 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005989 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005990 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005991 TaskRecord curTask = null;
5992 int numActivities = 0;
5993 int numRunning = 0;
5994 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005995 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005997 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005998
5999 // Initialize state for next task if needed.
6000 if (top == null ||
6001 (top.state == ActivityState.INITIALIZING
6002 && top.task == r.task)) {
6003 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006004 curTask = r.task;
6005 numActivities = numRunning = 0;
6006 }
6007
6008 // Add 'r' into the current task.
6009 numActivities++;
6010 if (r.app != null && r.app.thread != null) {
6011 numRunning++;
6012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006013
Joe Onorato8a9b2202010-02-26 18:56:32 -08006014 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006015 TAG, r.intent.getComponent().flattenToShortString()
6016 + ": task=" + r.task);
6017
6018 // If the next one is a different task, generate a new
6019 // TaskInfo entry for what we have.
6020 if (next == null || next.task != curTask) {
6021 ActivityManager.RunningTaskInfo ci
6022 = new ActivityManager.RunningTaskInfo();
6023 ci.id = curTask.taskId;
6024 ci.baseActivity = r.intent.getComponent();
6025 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006026 if (top.thumbHolder != null) {
6027 ci.description = top.thumbHolder.lastDescription;
6028 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006029 ci.numActivities = numActivities;
6030 ci.numRunning = numRunning;
6031 //System.out.println(
6032 // "#" + maxNum + ": " + " descr=" + ci.description);
6033 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006034 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006035 TAG, "State=" + top.state + "Idle=" + top.idle
6036 + " app=" + top.app
6037 + " thr=" + (top.app != null ? top.app.thread : null));
6038 if (top.state == ActivityState.RESUMED
6039 || top.state == ActivityState.PAUSING) {
6040 if (top.idle && top.app != null
6041 && top.app.thread != null) {
6042 topRecord = top;
6043 topThumbnail = top.app.thread;
6044 } else {
6045 top.thumbnailNeeded = true;
6046 }
6047 }
6048 if (pending == null) {
6049 pending = new PendingThumbnailsRecord(receiver);
6050 }
6051 pending.pendingRecords.add(top);
6052 }
6053 list.add(ci);
6054 maxNum--;
6055 top = null;
6056 }
6057 }
6058
6059 if (pending != null) {
6060 mPendingThumbnails.add(pending);
6061 }
6062 }
6063
Joe Onorato8a9b2202010-02-26 18:56:32 -08006064 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006065
6066 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006067 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08006069 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006071 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006072 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006073 }
6074 }
6075
6076 if (pending == null && receiver != null) {
6077 // In this case all thumbnails were available and the client
6078 // is being asked to be told when the remaining ones come in...
6079 // which is unusually, since the top-most currently running
6080 // activity should never have a canned thumbnail! Oh well.
6081 try {
6082 receiver.finished();
6083 } catch (RemoteException ex) {
6084 }
6085 }
6086
6087 return list;
6088 }
6089
6090 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6091 int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006092 final int callingUid = Binder.getCallingUid();
6093 // If it's the system uid asking, then use the current user id.
6094 // TODO: Make sure that there aren't any other legitimate calls from the system uid that
6095 // require the entire list.
6096 final int callingUserId = callingUid == Process.SYSTEM_UID
6097 ? mCurrentUserId : UserId.getUserId(callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 synchronized (this) {
6099 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6100 "getRecentTasks()");
6101
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006102 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104 final int N = mRecentTasks.size();
6105 ArrayList<ActivityManager.RecentTaskInfo> res
6106 = new ArrayList<ActivityManager.RecentTaskInfo>(
6107 maxNum < N ? maxNum : N);
6108 for (int i=0; i<N && maxNum > 0; i++) {
6109 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006110 // Only add calling user's recent tasks
6111 if (tr.userId != callingUserId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07006112 // Return the entry if desired by the caller. We always return
6113 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07006114 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07006115 // not supplied RECENT_WITH_EXCLUDED and there is some reason
6116 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07006117
Dianne Hackborn905577f2011-09-07 18:31:28 -07006118 if (i == 0
6119 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 || (tr.intent == null)
6121 || ((tr.intent.getFlags()
6122 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6123 ActivityManager.RecentTaskInfo rti
6124 = new ActivityManager.RecentTaskInfo();
6125 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006126 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006127 rti.baseIntent = new Intent(
6128 tr.intent != null ? tr.intent : tr.affinityIntent);
6129 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08006130 rti.description = tr.lastDescription;
6131
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006132 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6133 // Check whether this activity is currently available.
6134 try {
6135 if (rti.origActivity != null) {
6136 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
6137 continue;
6138 }
6139 } else if (rti.baseIntent != null) {
6140 if (pm.queryIntentActivities(rti.baseIntent,
6141 null, 0) == null) {
6142 continue;
6143 }
6144 }
6145 } catch (RemoteException e) {
6146 // Will never happen.
6147 }
6148 }
6149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 res.add(rti);
6151 maxNum--;
6152 }
6153 }
6154 return res;
6155 }
6156 }
6157
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006158 private TaskRecord taskForIdLocked(int id) {
6159 final int N = mRecentTasks.size();
6160 for (int i=0; i<N; i++) {
6161 TaskRecord tr = mRecentTasks.get(i);
6162 if (tr.taskId == id) {
6163 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006164 }
6165 }
6166 return null;
6167 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006168
6169 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6170 synchronized (this) {
6171 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6172 "getTaskThumbnails()");
6173 TaskRecord tr = taskForIdLocked(id);
6174 if (tr != null) {
6175 return mMainStack.getTaskThumbnailsLocked(tr);
6176 }
6177 }
6178 return null;
6179 }
6180
6181 public boolean removeSubTask(int taskId, int subTaskIndex) {
6182 synchronized (this) {
6183 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6184 "removeSubTask()");
6185 long ident = Binder.clearCallingIdentity();
6186 try {
6187 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
6188 } finally {
6189 Binder.restoreCallingIdentity(ident);
6190 }
6191 }
6192 }
6193
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006194 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006195 TaskRecord tr = root.task;
6196 Intent baseIntent = new Intent(
6197 tr.intent != null ? tr.intent : tr.affinityIntent);
6198 ComponentName component = baseIntent.getComponent();
6199 if (component == null) {
6200 Slog.w(TAG, "Now component for base intent of task: " + tr);
6201 return;
6202 }
6203
6204 // Find any running services associated with this app.
6205 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07006206 for (ServiceRecord sr : mServiceMap.getAllServices(root.userId)) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006207 if (sr.packageName.equals(component.getPackageName())) {
6208 services.add(sr);
6209 }
6210 }
6211
6212 // Take care of any running services associated with the app.
6213 for (int i=0; i<services.size(); i++) {
6214 ServiceRecord sr = services.get(i);
6215 if (sr.startRequested) {
6216 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006217 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006218 stopServiceLocked(sr);
6219 } else {
6220 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
6221 sr.makeNextStartId(), baseIntent, -1));
6222 if (sr.app != null && sr.app.thread != null) {
6223 sendServiceArgsLocked(sr, false);
6224 }
6225 }
6226 }
6227 }
6228
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006229 if (killProcesses) {
6230 // Find any running processes associated with this app.
6231 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6232 SparseArray<ProcessRecord> appProcs
6233 = mProcessNames.getMap().get(component.getPackageName());
6234 if (appProcs != null) {
6235 for (int i=0; i<appProcs.size(); i++) {
6236 procs.add(appProcs.valueAt(i));
6237 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006238 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006239
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006240 // Kill the running processes.
6241 for (int i=0; i<procs.size(); i++) {
6242 ProcessRecord pr = procs.get(i);
6243 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6244 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
6245 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
6246 pr.processName, pr.setAdj, "remove task");
6247 Process.killProcessQuiet(pr.pid);
6248 } else {
6249 pr.waitingToKill = "remove task";
6250 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006251 }
6252 }
6253 }
6254
6255 public boolean removeTask(int taskId, int flags) {
6256 synchronized (this) {
6257 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6258 "removeTask()");
6259 long ident = Binder.clearCallingIdentity();
6260 try {
6261 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
6262 if (r != null) {
6263 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006264 cleanUpRemovedTaskLocked(r,
6265 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006266 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07006267 } else {
6268 TaskRecord tr = null;
6269 int i=0;
6270 while (i < mRecentTasks.size()) {
6271 TaskRecord t = mRecentTasks.get(i);
6272 if (t.taskId == taskId) {
6273 tr = t;
6274 break;
6275 }
6276 i++;
6277 }
6278 if (tr != null) {
6279 if (tr.numActivities <= 0) {
6280 // Caller is just removing a recent task that is
6281 // not actively running. That is easy!
6282 mRecentTasks.remove(i);
6283 } else {
6284 Slog.w(TAG, "removeTask: task " + taskId
6285 + " does not have activities to remove, "
6286 + " but numActivities=" + tr.numActivities
6287 + ": " + tr);
6288 }
6289 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006290 }
6291 } finally {
6292 Binder.restoreCallingIdentity(ident);
6293 }
6294 }
6295 return false;
6296 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08006297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6299 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006300 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 TaskRecord jt = startTask;
6302
6303 // First look backwards
6304 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006305 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 if (r.task != jt) {
6307 jt = r.task;
6308 if (affinity.equals(jt.affinity)) {
6309 return j;
6310 }
6311 }
6312 }
6313
6314 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006315 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 jt = startTask;
6317 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006318 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 if (r.task != jt) {
6320 if (affinity.equals(jt.affinity)) {
6321 return j;
6322 }
6323 jt = r.task;
6324 }
6325 }
6326
6327 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006328 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006329 return N-1;
6330 }
6331
6332 return -1;
6333 }
6334
6335 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006336 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006338 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6340 "moveTaskToFront()");
6341
6342 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006343 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6344 Binder.getCallingUid(), "Task to front")) {
6345 return;
6346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006347 final long origId = Binder.clearCallingIdentity();
6348 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006349 TaskRecord tr = taskForIdLocked(task);
6350 if (tr != null) {
6351 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6352 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006353 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006354 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6355 // Caller wants the home activity moved with it. To accomplish this,
6356 // we'll just move the home task to the top first.
6357 mMainStack.moveHomeToFrontLocked();
6358 }
6359 mMainStack.moveTaskToFrontLocked(tr, null);
6360 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006361 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006362 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6363 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006364 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08006365 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6366 mMainStack.mUserLeaving = true;
6367 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006368 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6369 // Caller wants the home activity moved with it. To accomplish this,
6370 // we'll just move the home task to the top first.
6371 mMainStack.moveHomeToFrontLocked();
6372 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006373 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 return;
6375 }
6376 }
6377 } finally {
6378 Binder.restoreCallingIdentity(origId);
6379 }
6380 }
6381 }
6382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 public void moveTaskToBack(int task) {
6384 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6385 "moveTaskToBack()");
6386
6387 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006388 if (mMainStack.mResumedActivity != null
6389 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006390 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6391 Binder.getCallingUid(), "Task to back")) {
6392 return;
6393 }
6394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006396 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006397 Binder.restoreCallingIdentity(origId);
6398 }
6399 }
6400
6401 /**
6402 * Moves an activity, and all of the other activities within the same task, to the bottom
6403 * of the history stack. The activity's order within the task is unchanged.
6404 *
6405 * @param token A reference to the activity we wish to move
6406 * @param nonRoot If false then this only works if the activity is the root
6407 * of a task; if true it will work for any activity in a task.
6408 * @return Returns true if the move completed, false if not.
6409 */
6410 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006411 enforceNotIsolatedCaller("moveActivityTaskToBack");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006412 synchronized(this) {
6413 final long origId = Binder.clearCallingIdentity();
6414 int taskId = getTaskForActivityLocked(token, !nonRoot);
6415 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006416 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 }
6418 Binder.restoreCallingIdentity(origId);
6419 }
6420 return false;
6421 }
6422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006423 public void moveTaskBackwards(int task) {
6424 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6425 "moveTaskBackwards()");
6426
6427 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006428 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6429 Binder.getCallingUid(), "Task backwards")) {
6430 return;
6431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 final long origId = Binder.clearCallingIdentity();
6433 moveTaskBackwardsLocked(task);
6434 Binder.restoreCallingIdentity(origId);
6435 }
6436 }
6437
6438 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006439 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006440 }
6441
6442 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6443 synchronized(this) {
6444 return getTaskForActivityLocked(token, onlyRoot);
6445 }
6446 }
6447
6448 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006449 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 TaskRecord lastTask = null;
6451 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006452 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006453 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 if (!onlyRoot || lastTask != r.task) {
6455 return r.task.taskId;
6456 }
6457 return -1;
6458 }
6459 lastTask = r.task;
6460 }
6461
6462 return -1;
6463 }
6464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006465 // =========================================================
6466 // THUMBNAILS
6467 // =========================================================
6468
6469 public void reportThumbnail(IBinder token,
6470 Bitmap thumbnail, CharSequence description) {
6471 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6472 final long origId = Binder.clearCallingIdentity();
6473 sendPendingThumbnail(null, token, thumbnail, description, true);
6474 Binder.restoreCallingIdentity(origId);
6475 }
6476
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006477 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 Bitmap thumbnail, CharSequence description, boolean always) {
6479 TaskRecord task = null;
6480 ArrayList receivers = null;
6481
6482 //System.out.println("Send pending thumbnail: " + r);
6483
6484 synchronized(this) {
6485 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006486 r = mMainStack.isInStackLocked(token);
6487 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006488 return;
6489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006490 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006491 if (thumbnail == null && r.thumbHolder != null) {
6492 thumbnail = r.thumbHolder.lastThumbnail;
6493 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006494 }
6495 if (thumbnail == null && !always) {
6496 // If there is no thumbnail, and this entry is not actually
6497 // going away, then abort for now and pick up the next
6498 // thumbnail we get.
6499 return;
6500 }
6501 task = r.task;
6502
6503 int N = mPendingThumbnails.size();
6504 int i=0;
6505 while (i<N) {
6506 PendingThumbnailsRecord pr =
6507 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6508 //System.out.println("Looking in " + pr.pendingRecords);
6509 if (pr.pendingRecords.remove(r)) {
6510 if (receivers == null) {
6511 receivers = new ArrayList();
6512 }
6513 receivers.add(pr);
6514 if (pr.pendingRecords.size() == 0) {
6515 pr.finished = true;
6516 mPendingThumbnails.remove(i);
6517 N--;
6518 continue;
6519 }
6520 }
6521 i++;
6522 }
6523 }
6524
6525 if (receivers != null) {
6526 final int N = receivers.size();
6527 for (int i=0; i<N; i++) {
6528 try {
6529 PendingThumbnailsRecord pr =
6530 (PendingThumbnailsRecord)receivers.get(i);
6531 pr.receiver.newThumbnail(
6532 task != null ? task.taskId : -1, thumbnail, description);
6533 if (pr.finished) {
6534 pr.receiver.finished();
6535 }
6536 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006537 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 }
6539 }
6540 }
6541 }
6542
6543 // =========================================================
6544 // CONTENT PROVIDERS
6545 // =========================================================
6546
Jeff Brown10e89712011-07-08 18:52:57 -07006547 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6548 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006549 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006550 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006551 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006552 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006553 } catch (RemoteException ex) {
6554 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006555 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006556 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6557 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 if (providers != null) {
6559 final int N = providers.size();
6560 for (int i=0; i<N; i++) {
6561 ProviderInfo cpi =
6562 (ProviderInfo)providers.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006563
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006564 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006565 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006566 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006567 cpr = new ContentProviderRecord(cpi, app.info, comp);
Amith Yamasani742a6712011-05-04 14:49:28 -07006568 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006570 if (DEBUG_MU)
6571 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006572 app.pubProviders.put(cpi.name, cpr);
6573 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006574 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006575 }
6576 }
6577 return providers;
6578 }
6579
6580 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006581 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006582 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006583 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006584 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006585 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006586 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006587 return null;
6588 }
6589 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006590 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006591 == PackageManager.PERMISSION_GRANTED) {
6592 return null;
6593 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006594
6595 PathPermission[] pps = cpi.pathPermissions;
6596 if (pps != null) {
6597 int i = pps.length;
6598 while (i > 0) {
6599 i--;
6600 PathPermission pp = pps[i];
6601 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006602 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006603 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006604 return null;
6605 }
6606 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006607 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006608 == PackageManager.PERMISSION_GRANTED) {
6609 return null;
6610 }
6611 }
6612 }
6613
Dianne Hackbornb424b632010-08-18 15:59:05 -07006614 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6615 if (perms != null) {
6616 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6617 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6618 return null;
6619 }
6620 }
6621 }
6622
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006623 String msg;
6624 if (!cpi.exported) {
6625 msg = "Permission Denial: opening provider " + cpi.name
6626 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6627 + ", uid=" + callingUid + ") that is not exported from uid "
6628 + cpi.applicationInfo.uid;
6629 } else {
6630 msg = "Permission Denial: opening provider " + cpi.name
6631 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6632 + ", uid=" + callingUid + ") requires "
6633 + cpi.readPermission + " or " + cpi.writePermission;
6634 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006635 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 return msg;
6637 }
6638
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006639 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6640 if (r != null) {
6641 Integer cnt = r.conProviders.get(cpr);
6642 if (DEBUG_PROVIDER) Slog.v(TAG,
6643 "Adding provider requested by "
6644 + r.processName + " from process "
6645 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6646 + " cnt=" + (cnt == null ? 1 : cnt));
6647 if (cnt == null) {
6648 cpr.clients.add(r);
6649 r.conProviders.put(cpr, new Integer(1));
6650 return true;
6651 } else {
6652 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
6653 }
6654 } else {
6655 cpr.externals++;
6656 }
6657 return false;
6658 }
6659
6660 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6661 if (r != null) {
6662 Integer cnt = r.conProviders.get(cpr);
6663 if (DEBUG_PROVIDER) Slog.v(TAG,
6664 "Removing provider requested by "
6665 + r.processName + " from process "
6666 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6667 + " cnt=" + cnt);
6668 if (cnt == null || cnt.intValue() <= 1) {
6669 cpr.clients.remove(r);
6670 r.conProviders.remove(cpr);
6671 return true;
6672 } else {
6673 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
6674 }
6675 } else {
6676 cpr.externals++;
6677 }
6678 return false;
6679 }
6680
Amith Yamasani742a6712011-05-04 14:49:28 -07006681 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6682 String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006683 ContentProviderRecord cpr;
6684 ProviderInfo cpi = null;
6685
6686 synchronized(this) {
6687 ProcessRecord r = null;
6688 if (caller != null) {
6689 r = getRecordForAppLocked(caller);
6690 if (r == null) {
6691 throw new SecurityException(
6692 "Unable to find app for caller " + caller
6693 + " (pid=" + Binder.getCallingPid()
6694 + ") when getting content provider " + name);
6695 }
6696 }
6697
6698 // First check if this content provider has been published...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006699 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
Amith Yamasani742a6712011-05-04 14:49:28 -07006700 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006701 boolean providerRunning = cpr != null;
6702 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006704 String msg;
6705 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6706 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006707 }
6708
6709 if (r != null && cpr.canRunHere(r)) {
6710 // This provider has been published or is in the process
6711 // of being published... but it is also allowed to run
6712 // in the caller's process, so don't make a connection
6713 // and just let the caller instantiate its own instance.
6714 if (cpr.provider != null) {
6715 // don't give caller the provider object, it needs
6716 // to make its own.
6717 cpr = new ContentProviderRecord(cpr);
6718 }
6719 return cpr;
6720 }
6721
6722 final long origId = Binder.clearCallingIdentity();
6723
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006724 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006725 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006726 final boolean countChanged = incProviderCount(r, cpr);
6727 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006728 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006729 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006730 // make sure to count it as being accessed and thus
6731 // back up on the LRU list. This is good because
6732 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006733 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006734 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006735 }
6736
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006737 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006738 if (false) {
6739 if (cpr.name.flattenToShortString().equals(
6740 "com.android.providers.calendar/.CalendarProvider2")) {
6741 Slog.v(TAG, "****************** KILLING "
6742 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006743 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006744 }
6745 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006746 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006747 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6748 // NOTE: there is still a race here where a signal could be
6749 // pending on the process even though we managed to update its
6750 // adj level. Not sure what to do about this, but at least
6751 // the race is now smaller.
6752 if (!success) {
6753 // Uh oh... it looks like the provider's process
6754 // has been killed on us. We need to wait for a new
6755 // process to be started, and make sure its death
6756 // doesn't kill our process.
6757 Slog.i(TAG,
6758 "Existing provider " + cpr.name.flattenToShortString()
6759 + " is crashing; detaching " + r);
6760 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006761 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006762 if (!lastRef) {
6763 // This wasn't the last ref our process had on
6764 // the provider... we have now been killed, bail.
6765 return null;
6766 }
6767 providerRunning = false;
6768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 }
6770
6771 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006772 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006773
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006774 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006775 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006776 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006777 resolveContentProvider(name,
6778 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 } catch (RemoteException ex) {
6780 }
6781 if (cpi == null) {
6782 return null;
6783 }
6784
Amith Yamasani742a6712011-05-04 14:49:28 -07006785 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo,
6786 Binder.getOrigCallingUser());
6787
Dianne Hackbornb424b632010-08-18 15:59:05 -07006788 String msg;
6789 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6790 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 }
6792
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006793 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006794 && !cpi.processName.equals("system")) {
6795 // If this content provider does not run in the system
6796 // process, and the system is not yet ready to run other
6797 // processes, then fail fast instead of hanging.
6798 throw new IllegalArgumentException(
6799 "Attempt to launch content provider before system ready");
6800 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006801
6802 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006803 cpr = mProviderMap.getProviderByClass(comp, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804 final boolean firstClass = cpr == null;
6805 if (firstClass) {
6806 try {
6807 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006808 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006809 getApplicationInfo(
6810 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006811 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006813 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 + cpi.name);
6815 return null;
6816 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006817 ai = getAppInfoForUser(ai, Binder.getOrigCallingUser());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006818 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 } catch (RemoteException ex) {
6820 // pm is in same process, this will never happen.
6821 }
6822 }
6823
6824 if (r != null && cpr.canRunHere(r)) {
6825 // If this is a multiprocess provider, then just return its
6826 // info and allow the caller to instantiate it. Only do
6827 // this if the provider is the same user as the caller's
6828 // process, or can run as root (so can be in any process).
6829 return cpr;
6830 }
6831
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006832 if (DEBUG_PROVIDER) {
6833 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006834 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006835 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006836 }
6837
6838 // This is single process, and our app is now connecting to it.
6839 // See if we are already in the process of launching this
6840 // provider.
6841 final int N = mLaunchingProviders.size();
6842 int i;
6843 for (i=0; i<N; i++) {
6844 if (mLaunchingProviders.get(i) == cpr) {
6845 break;
6846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 }
6848
6849 // If the provider is not already being launched, then get it
6850 // started.
6851 if (i >= N) {
6852 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006853
6854 try {
6855 // Content provider is now in use, its package can't be stopped.
6856 try {
6857 AppGlobals.getPackageManager().setPackageStoppedState(
6858 cpr.appInfo.packageName, false);
6859 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006860 } catch (IllegalArgumentException e) {
6861 Slog.w(TAG, "Failed trying to unstop package "
6862 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006863 }
6864
6865 ProcessRecord proc = startProcessLocked(cpi.processName,
6866 cpr.appInfo, false, 0, "content provider",
6867 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006868 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006869 if (proc == null) {
6870 Slog.w(TAG, "Unable to launch app "
6871 + cpi.applicationInfo.packageName + "/"
6872 + cpi.applicationInfo.uid + " for provider "
6873 + name + ": process is bad");
6874 return null;
6875 }
6876 cpr.launchingApp = proc;
6877 mLaunchingProviders.add(cpr);
6878 } finally {
6879 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 }
6882
6883 // Make sure the provider is published (the same provider class
6884 // may be published under multiple names).
6885 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006886 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006888 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006889 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 }
6891 }
6892
6893 // Wait for the provider to be published...
6894 synchronized (cpr) {
6895 while (cpr.provider == null) {
6896 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006897 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006898 + cpi.applicationInfo.packageName + "/"
6899 + cpi.applicationInfo.uid + " for provider "
6900 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006901 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 cpi.applicationInfo.packageName,
6903 cpi.applicationInfo.uid, name);
6904 return null;
6905 }
6906 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006907 if (DEBUG_MU) {
6908 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6909 + cpr.launchingApp);
6910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 cpr.wait();
6912 } catch (InterruptedException ex) {
6913 }
6914 }
6915 }
6916 return cpr;
6917 }
6918
6919 public final ContentProviderHolder getContentProvider(
6920 IApplicationThread caller, String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006921 enforceNotIsolatedCaller("getContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 if (caller == null) {
6923 String msg = "null IApplicationThread when getting content provider "
6924 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006925 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 throw new SecurityException(msg);
6927 }
6928
Amith Yamasani742a6712011-05-04 14:49:28 -07006929 ContentProviderHolder contentProvider = getContentProviderImpl(caller, name);
6930 return contentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 }
6932
6933 private ContentProviderHolder getContentProviderExternal(String name) {
6934 return getContentProviderImpl(null, name);
6935 }
6936
6937 /**
6938 * Drop a content provider from a ProcessRecord's bookkeeping
6939 * @param cpr
6940 */
6941 public void removeContentProvider(IApplicationThread caller, String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006942 enforceNotIsolatedCaller("removeContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006943 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006944 int userId = UserId.getUserId(Binder.getCallingUid());
6945 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006947 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006948 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006949 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 return;
6951 }
6952 final ProcessRecord r = getRecordForAppLocked(caller);
6953 if (r == null) {
6954 throw new SecurityException(
6955 "Unable to find app for caller " + caller +
6956 " when removing content provider " + name);
6957 }
6958 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006959 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006960 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6961 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
6962 + r.info.processName + " from process "
6963 + localCpr.appInfo.processName);
6964 if (localCpr.launchingApp == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006965 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006966 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006967 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 return;
6969 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006970 if (decProviderCount(r, localCpr)) {
6971 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006974 }
6975 }
6976
6977 private void removeContentProviderExternal(String name) {
6978 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006979 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6980 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006981 if(cpr == null) {
6982 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006983 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984 return;
6985 }
6986
6987 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006988 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006989 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6990 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 localCpr.externals--;
6992 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006993 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006994 }
6995 updateOomAdjLocked();
6996 }
6997 }
6998
6999 public final void publishContentProviders(IApplicationThread caller,
7000 List<ContentProviderHolder> providers) {
7001 if (providers == null) {
7002 return;
7003 }
7004
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007005 enforceNotIsolatedCaller("publishContentProviders");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007006 synchronized(this) {
7007 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07007008 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007009 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 if (r == null) {
7011 throw new SecurityException(
7012 "Unable to find app for caller " + caller
7013 + " (pid=" + Binder.getCallingPid()
7014 + ") when publishing content providers");
7015 }
7016
7017 final long origId = Binder.clearCallingIdentity();
7018
7019 final int N = providers.size();
7020 for (int i=0; i<N; i++) {
7021 ContentProviderHolder src = providers.get(i);
7022 if (src == null || src.info == null || src.provider == null) {
7023 continue;
7024 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07007025 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007026 if (DEBUG_MU)
7027 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007028 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007029 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007030 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 String names[] = dst.info.authority.split(";");
7032 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007033 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007034 }
7035
7036 int NL = mLaunchingProviders.size();
7037 int j;
7038 for (j=0; j<NL; j++) {
7039 if (mLaunchingProviders.get(j) == dst) {
7040 mLaunchingProviders.remove(j);
7041 j--;
7042 NL--;
7043 }
7044 }
7045 synchronized (dst) {
7046 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07007047 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007048 dst.notifyAll();
7049 }
7050 updateOomAdjLocked(r);
7051 }
7052 }
7053
7054 Binder.restoreCallingIdentity(origId);
7055 }
7056 }
7057
7058 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07007059 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06007060 synchronized (mSelf) {
7061 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7062 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08007063 if (providers != null) {
7064 for (int i=providers.size()-1; i>=0; i--) {
7065 ProviderInfo pi = (ProviderInfo)providers.get(i);
7066 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7067 Slog.w(TAG, "Not installing system proc provider " + pi.name
7068 + ": not system .apk");
7069 providers.remove(i);
7070 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08007071 }
7072 }
7073 }
Josh Bartel2ecce342010-02-25 10:55:48 -06007074 if (providers != null) {
7075 mSystemThread.installSystemProviders(providers);
7076 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08007077
7078 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01007079
7080 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 }
7082
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007083 /**
7084 * Allows app to retrieve the MIME type of a URI without having permission
7085 * to access its content provider.
7086 *
7087 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7088 *
7089 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7090 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7091 */
7092 public String getProviderMimeType(Uri uri) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007093 enforceNotIsolatedCaller("getProviderMimeType");
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007094 final String name = uri.getAuthority();
7095 final long ident = Binder.clearCallingIdentity();
7096 ContentProviderHolder holder = null;
7097
7098 try {
7099 holder = getContentProviderExternal(name);
7100 if (holder != null) {
7101 return holder.provider.getType(uri);
7102 }
7103 } catch (RemoteException e) {
7104 Log.w(TAG, "Content provider dead retrieving " + uri, e);
7105 return null;
7106 } finally {
7107 if (holder != null) {
7108 removeContentProviderExternal(name);
7109 }
7110 Binder.restoreCallingIdentity(ident);
7111 }
7112
7113 return null;
7114 }
7115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 // =========================================================
7117 // GLOBAL MANAGEMENT
7118 // =========================================================
7119
7120 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007121 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007122 String proc = customProcess != null ? customProcess : info.processName;
7123 BatteryStatsImpl.Uid.Proc ps = null;
7124 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007125 int uid = info.uid;
7126 if (isolated) {
7127 int userId = UserId.getUserId(uid);
7128 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7129 uid = 0;
7130 while (true) {
7131 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7132 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7133 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7134 }
7135 uid = UserId.getUid(userId, mNextIsolatedProcessUid);
7136 mNextIsolatedProcessUid++;
7137 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7138 // No process for this uid, use it.
7139 break;
7140 }
7141 stepsLeft--;
7142 if (stepsLeft <= 0) {
7143 return null;
7144 }
7145 }
7146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007147 synchronized (stats) {
7148 ps = stats.getProcessStatsLocked(info.uid, proc);
7149 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007150 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007151 }
7152
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007153 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7154 ProcessRecord app;
7155 if (!isolated) {
7156 app = getProcessRecordLocked(info.processName, info.uid);
7157 } else {
7158 app = null;
7159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007160
7161 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007162 app = newProcessRecordLocked(null, info, null, isolated);
7163 mProcessNames.put(info.processName, app.uid, app);
7164 if (isolated) {
7165 mIsolatedProcesses.put(app.uid, app);
7166 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007167 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007168 }
7169
Dianne Hackborne7f97212011-02-24 14:40:20 -08007170 // This package really, really can not be stopped.
7171 try {
7172 AppGlobals.getPackageManager().setPackageStoppedState(
7173 info.packageName, false);
7174 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08007175 } catch (IllegalArgumentException e) {
7176 Slog.w(TAG, "Failed trying to unstop package "
7177 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08007178 }
7179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007180 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7181 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7182 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007183 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 }
7185 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7186 mPersistentStartingProcesses.add(app);
7187 startProcessLocked(app, "added application", app.processName);
7188 }
7189
7190 return app;
7191 }
7192
7193 public void unhandledBack() {
7194 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7195 "unhandledBack()");
7196
7197 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007198 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007199 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007200 TAG, "Performing unhandledBack(): stack size = " + count);
7201 if (count > 1) {
7202 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007203 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7205 Binder.restoreCallingIdentity(origId);
7206 }
7207 }
7208 }
7209
7210 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007211 enforceNotIsolatedCaller("openContentUri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 String name = uri.getAuthority();
7213 ContentProviderHolder cph = getContentProviderExternal(name);
7214 ParcelFileDescriptor pfd = null;
7215 if (cph != null) {
7216 // We record the binder invoker's uid in thread-local storage before
7217 // going to the content provider to open the file. Later, in the code
7218 // that handles all permissions checks, we look for this uid and use
7219 // that rather than the Activity Manager's own uid. The effect is that
7220 // we do the check against the caller's permissions even though it looks
7221 // to the content provider like the Activity Manager itself is making
7222 // the request.
7223 sCallerIdentity.set(new Identity(
7224 Binder.getCallingPid(), Binder.getCallingUid()));
7225 try {
7226 pfd = cph.provider.openFile(uri, "r");
7227 } catch (FileNotFoundException e) {
7228 // do nothing; pfd will be returned null
7229 } finally {
7230 // Ensure that whatever happens, we clean up the identity state
7231 sCallerIdentity.remove();
7232 }
7233
7234 // We've got the fd now, so we're done with the provider.
7235 removeContentProviderExternal(name);
7236 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007237 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007238 }
7239 return pfd;
7240 }
7241
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007242 // Actually is sleeping or shutting down or whatever else in the future
7243 // is an inactive state.
7244 public boolean isSleeping() {
7245 return mSleeping || mShuttingDown;
7246 }
7247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007248 public void goingToSleep() {
7249 synchronized(this) {
7250 mSleeping = true;
7251 mWindowManager.setEventDispatching(false);
7252
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007253 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007254
7255 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07007256 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007257 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7258 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007259 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007260 }
7261 }
7262
Dianne Hackborn55280a92009-05-07 15:53:46 -07007263 public boolean shutdown(int timeout) {
7264 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7265 != PackageManager.PERMISSION_GRANTED) {
7266 throw new SecurityException("Requires permission "
7267 + android.Manifest.permission.SHUTDOWN);
7268 }
7269
7270 boolean timedout = false;
7271
7272 synchronized(this) {
7273 mShuttingDown = true;
7274 mWindowManager.setEventDispatching(false);
7275
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007276 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007277 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07007278 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007279 while (mMainStack.mResumedActivity != null
Dianne Hackborncbb722e2012-02-07 18:33:49 -08007280 || mMainStack.mPausingActivities.size() > 0) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07007281 long delay = endTime - System.currentTimeMillis();
7282 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007283 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07007284 timedout = true;
7285 break;
7286 }
7287 try {
7288 this.wait();
7289 } catch (InterruptedException e) {
7290 }
7291 }
7292 }
7293 }
7294
7295 mUsageStatsService.shutdown();
7296 mBatteryStatsService.shutdown();
7297
7298 return timedout;
7299 }
7300
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007301 public final void activitySlept(IBinder token) {
7302 if (localLOGV) Slog.v(
7303 TAG, "Activity slept: token=" + token);
7304
7305 ActivityRecord r = null;
7306
7307 final long origId = Binder.clearCallingIdentity();
7308
7309 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007310 r = mMainStack.isInStackLocked(token);
7311 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007312 mMainStack.activitySleptLocked(r);
7313 }
7314 }
7315
7316 Binder.restoreCallingIdentity(origId);
7317 }
7318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007319 public void wakingUp() {
7320 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007321 mWindowManager.setEventDispatching(true);
7322 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007323 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007324 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007325 }
7326 }
7327
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007328 public void stopAppSwitches() {
7329 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7330 != PackageManager.PERMISSION_GRANTED) {
7331 throw new SecurityException("Requires permission "
7332 + android.Manifest.permission.STOP_APP_SWITCHES);
7333 }
7334
7335 synchronized(this) {
7336 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7337 + APP_SWITCH_DELAY_TIME;
7338 mDidAppSwitch = false;
7339 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7340 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7341 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7342 }
7343 }
7344
7345 public void resumeAppSwitches() {
7346 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7347 != PackageManager.PERMISSION_GRANTED) {
7348 throw new SecurityException("Requires permission "
7349 + android.Manifest.permission.STOP_APP_SWITCHES);
7350 }
7351
7352 synchronized(this) {
7353 // Note that we don't execute any pending app switches... we will
7354 // let those wait until either the timeout, or the next start
7355 // activity request.
7356 mAppSwitchesAllowedTime = 0;
7357 }
7358 }
7359
7360 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7361 String name) {
7362 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7363 return true;
7364 }
7365
7366 final int perm = checkComponentPermission(
7367 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007368 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007369 if (perm == PackageManager.PERMISSION_GRANTED) {
7370 return true;
7371 }
7372
Joe Onorato8a9b2202010-02-26 18:56:32 -08007373 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007374 return false;
7375 }
7376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007377 public void setDebugApp(String packageName, boolean waitForDebugger,
7378 boolean persistent) {
7379 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7380 "setDebugApp()");
7381
7382 // Note that this is not really thread safe if there are multiple
7383 // callers into it at the same time, but that's not a situation we
7384 // care about.
7385 if (persistent) {
7386 final ContentResolver resolver = mContext.getContentResolver();
7387 Settings.System.putString(
7388 resolver, Settings.System.DEBUG_APP,
7389 packageName);
7390 Settings.System.putInt(
7391 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7392 waitForDebugger ? 1 : 0);
7393 }
7394
7395 synchronized (this) {
7396 if (!persistent) {
7397 mOrigDebugApp = mDebugApp;
7398 mOrigWaitForDebugger = mWaitForDebugger;
7399 }
7400 mDebugApp = packageName;
7401 mWaitForDebugger = waitForDebugger;
7402 mDebugTransient = !persistent;
7403 if (packageName != null) {
7404 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07007405 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 Binder.restoreCallingIdentity(origId);
7407 }
7408 }
7409 }
7410
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007411 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7412 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7413 synchronized (this) {
7414 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7415 if (!isDebuggable) {
7416 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7417 throw new SecurityException("Process not debuggable: " + app.packageName);
7418 }
7419 }
7420 mProfileApp = processName;
7421 mProfileFile = profileFile;
7422 if (mProfileFd != null) {
7423 try {
7424 mProfileFd.close();
7425 } catch (IOException e) {
7426 }
7427 mProfileFd = null;
7428 }
7429 mProfileFd = profileFd;
7430 mProfileType = 0;
7431 mAutoStopProfiler = autoStopProfiler;
7432 }
7433 }
7434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007435 public void setAlwaysFinish(boolean enabled) {
7436 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7437 "setAlwaysFinish()");
7438
7439 Settings.System.putInt(
7440 mContext.getContentResolver(),
7441 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7442
7443 synchronized (this) {
7444 mAlwaysFinishActivities = enabled;
7445 }
7446 }
7447
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007448 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007449 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007450 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007451 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007452 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 }
7454 }
7455
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007456 public boolean isUserAMonkey() {
7457 // For now the fact that there is a controller implies
7458 // we have a monkey.
7459 synchronized (this) {
7460 return mController != null;
7461 }
7462 }
7463
Jeff Sharkeya4620792011-05-20 15:29:23 -07007464 public void registerProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007465 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7466 "registerProcessObserver()");
7467 synchronized (this) {
7468 mProcessObservers.register(observer);
7469 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007470 }
7471
7472 public void unregisterProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007473 synchronized (this) {
7474 mProcessObservers.unregister(observer);
7475 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007476 }
7477
Daniel Sandler69a48172010-06-23 16:29:36 -04007478 public void setImmersive(IBinder token, boolean immersive) {
7479 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007480 ActivityRecord r = mMainStack.isInStackLocked(token);
7481 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007482 throw new IllegalArgumentException();
7483 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007484 r.immersive = immersive;
7485 }
7486 }
7487
7488 public boolean isImmersive(IBinder token) {
7489 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007490 ActivityRecord r = mMainStack.isInStackLocked(token);
7491 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007492 throw new IllegalArgumentException();
7493 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007494 return r.immersive;
7495 }
7496 }
7497
7498 public boolean isTopActivityImmersive() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007499 enforceNotIsolatedCaller("startActivity");
Daniel Sandler69a48172010-06-23 16:29:36 -04007500 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007501 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007502 return (r != null) ? r.immersive : false;
7503 }
7504 }
7505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007506 public final void enterSafeMode() {
7507 synchronized(this) {
7508 // It only makes sense to do this before the system is ready
7509 // and started launching other packages.
7510 if (!mSystemReady) {
7511 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007512 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 } catch (RemoteException e) {
7514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007515 }
7516 }
7517 }
7518
Jeff Brownb09abc12011-01-13 21:08:27 -08007519 public final void showSafeModeOverlay() {
7520 View v = LayoutInflater.from(mContext).inflate(
7521 com.android.internal.R.layout.safe_mode, null);
7522 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7523 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7524 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7525 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7526 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7527 lp.format = v.getBackground().getOpacity();
7528 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7529 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7530 ((WindowManager)mContext.getSystemService(
7531 Context.WINDOW_SERVICE)).addView(v, lp);
7532 }
7533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007534 public void noteWakeupAlarm(IIntentSender sender) {
7535 if (!(sender instanceof PendingIntentRecord)) {
7536 return;
7537 }
7538 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7539 synchronized (stats) {
7540 if (mBatteryStatsService.isOnBattery()) {
7541 mBatteryStatsService.enforceCallingPermission();
7542 PendingIntentRecord rec = (PendingIntentRecord)sender;
7543 int MY_UID = Binder.getCallingUid();
7544 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7545 BatteryStatsImpl.Uid.Pkg pkg =
7546 stats.getPackageStatsLocked(uid, rec.key.packageName);
7547 pkg.incWakeupsLocked();
7548 }
7549 }
7550 }
7551
Dianne Hackborn64825172011-03-02 21:32:58 -08007552 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007553 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007554 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007556 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007557 // XXX Note: don't acquire main activity lock here, because the window
7558 // manager calls in with its locks held.
7559
7560 boolean killed = false;
7561 synchronized (mPidsSelfLocked) {
7562 int[] types = new int[pids.length];
7563 int worstType = 0;
7564 for (int i=0; i<pids.length; i++) {
7565 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7566 if (proc != null) {
7567 int type = proc.setAdj;
7568 types[i] = type;
7569 if (type > worstType) {
7570 worstType = type;
7571 }
7572 }
7573 }
7574
Dianne Hackborn64825172011-03-02 21:32:58 -08007575 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007576 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007577 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7578 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007579 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007581
7582 // If this is not a secure call, don't let it kill processes that
7583 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007584 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7585 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007586 }
7587
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007588 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 for (int i=0; i<pids.length; i++) {
7590 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7591 if (proc == null) {
7592 continue;
7593 }
7594 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007595 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007596 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007597 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7598 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007599 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007600 proc.killedBackground = true;
7601 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007602 }
7603 }
7604 }
7605 return killed;
7606 }
7607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007608 public final void startRunning(String pkg, String cls, String action,
7609 String data) {
7610 synchronized(this) {
7611 if (mStartRunning) {
7612 return;
7613 }
7614 mStartRunning = true;
7615 mTopComponent = pkg != null && cls != null
7616 ? new ComponentName(pkg, cls) : null;
7617 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7618 mTopData = data;
7619 if (!mSystemReady) {
7620 return;
7621 }
7622 }
7623
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007624 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 }
7626
7627 private void retrieveSettings() {
7628 final ContentResolver resolver = mContext.getContentResolver();
7629 String debugApp = Settings.System.getString(
7630 resolver, Settings.System.DEBUG_APP);
7631 boolean waitForDebugger = Settings.System.getInt(
7632 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7633 boolean alwaysFinishActivities = Settings.System.getInt(
7634 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7635
7636 Configuration configuration = new Configuration();
7637 Settings.System.getConfiguration(resolver, configuration);
7638
7639 synchronized (this) {
7640 mDebugApp = mOrigDebugApp = debugApp;
7641 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7642 mAlwaysFinishActivities = alwaysFinishActivities;
7643 // This happens before any activities are started, so we can
7644 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007645 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007646 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007647 }
7648 }
7649
7650 public boolean testIsSystemReady() {
7651 // no need to synchronize(this) just to read & return the value
7652 return mSystemReady;
7653 }
7654
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007655 private static File getCalledPreBootReceiversFile() {
7656 File dataDir = Environment.getDataDirectory();
7657 File systemDir = new File(dataDir, "system");
7658 File fname = new File(systemDir, "called_pre_boots.dat");
7659 return fname;
7660 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007661
7662 static final int LAST_DONE_VERSION = 10000;
7663
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007664 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7665 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7666 File file = getCalledPreBootReceiversFile();
7667 FileInputStream fis = null;
7668 try {
7669 fis = new FileInputStream(file);
7670 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007671 int fvers = dis.readInt();
7672 if (fvers == LAST_DONE_VERSION) {
7673 String vers = dis.readUTF();
7674 String codename = dis.readUTF();
7675 String build = dis.readUTF();
7676 if (android.os.Build.VERSION.RELEASE.equals(vers)
7677 && android.os.Build.VERSION.CODENAME.equals(codename)
7678 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7679 int num = dis.readInt();
7680 while (num > 0) {
7681 num--;
7682 String pkg = dis.readUTF();
7683 String cls = dis.readUTF();
7684 lastDoneReceivers.add(new ComponentName(pkg, cls));
7685 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007686 }
7687 }
7688 } catch (FileNotFoundException e) {
7689 } catch (IOException e) {
7690 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7691 } finally {
7692 if (fis != null) {
7693 try {
7694 fis.close();
7695 } catch (IOException e) {
7696 }
7697 }
7698 }
7699 return lastDoneReceivers;
7700 }
7701
7702 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7703 File file = getCalledPreBootReceiversFile();
7704 FileOutputStream fos = null;
7705 DataOutputStream dos = null;
7706 try {
7707 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7708 fos = new FileOutputStream(file);
7709 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007710 dos.writeInt(LAST_DONE_VERSION);
7711 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007712 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007713 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007714 dos.writeInt(list.size());
7715 for (int i=0; i<list.size(); i++) {
7716 dos.writeUTF(list.get(i).getPackageName());
7717 dos.writeUTF(list.get(i).getClassName());
7718 }
7719 } catch (IOException e) {
7720 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7721 file.delete();
7722 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007723 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007724 if (dos != null) {
7725 try {
7726 dos.close();
7727 } catch (IOException e) {
7728 // TODO Auto-generated catch block
7729 e.printStackTrace();
7730 }
7731 }
7732 }
7733 }
7734
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007735 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 synchronized(this) {
7737 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007738 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007739 return;
7740 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007741
7742 // Check to see if there are any update receivers to run.
7743 if (!mDidUpdate) {
7744 if (mWaitingUpdate) {
7745 return;
7746 }
7747 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7748 List<ResolveInfo> ris = null;
7749 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007750 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007751 intent, null, 0);
7752 } catch (RemoteException e) {
7753 }
7754 if (ris != null) {
7755 for (int i=ris.size()-1; i>=0; i--) {
7756 if ((ris.get(i).activityInfo.applicationInfo.flags
7757 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7758 ris.remove(i);
7759 }
7760 }
7761 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007762
7763 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7764
7765 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007766 for (int i=0; i<ris.size(); i++) {
7767 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007768 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7769 if (lastDoneReceivers.contains(comp)) {
7770 ris.remove(i);
7771 i--;
7772 }
7773 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007774
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007775 for (int i=0; i<ris.size(); i++) {
7776 ActivityInfo ai = ris.get(i).activityInfo;
7777 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7778 doneReceivers.add(comp);
7779 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007780 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08007781 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007782 finisher = new IIntentReceiver.Stub() {
7783 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07007784 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007785 boolean sticky) {
7786 // The raw IIntentReceiver interface is called
7787 // with the AM lock held, so redispatch to
7788 // execute our code without the lock.
7789 mHandler.post(new Runnable() {
7790 public void run() {
7791 synchronized (ActivityManagerService.this) {
7792 mDidUpdate = true;
7793 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007794 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007795 showBootMessage(mContext.getText(
7796 R.string.android_upgrading_complete),
7797 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007798 systemReady(goingCallback);
7799 }
7800 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007801 }
7802 };
7803 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007804 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Amith Yamasani742a6712011-05-04 14:49:28 -07007805 /* TODO: Send this to all users */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007806 broadcastIntentLocked(null, null, intent, null, finisher,
Amith Yamasani742a6712011-05-04 14:49:28 -07007807 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7808 Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08007809 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007810 mWaitingUpdate = true;
7811 }
7812 }
7813 }
7814 if (mWaitingUpdate) {
7815 return;
7816 }
7817 mDidUpdate = true;
7818 }
7819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007820 mSystemReady = true;
7821 if (!mStartRunning) {
7822 return;
7823 }
7824 }
7825
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007826 ArrayList<ProcessRecord> procsToKill = null;
7827 synchronized(mPidsSelfLocked) {
7828 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7829 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7830 if (!isAllowedWhileBooting(proc.info)){
7831 if (procsToKill == null) {
7832 procsToKill = new ArrayList<ProcessRecord>();
7833 }
7834 procsToKill.add(proc);
7835 }
7836 }
7837 }
7838
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007839 synchronized(this) {
7840 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007841 for (int i=procsToKill.size()-1; i>=0; i--) {
7842 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007843 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007844 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007845 }
7846 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007847
7848 // Now that we have cleaned up any update processes, we
7849 // are ready to start launching real processes and know that
7850 // we won't trample on them any more.
7851 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007852 }
7853
Joe Onorato8a9b2202010-02-26 18:56:32 -08007854 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007855 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007856 SystemClock.uptimeMillis());
7857
7858 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007859 // Make sure we have no pre-ready processes sitting around.
7860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007861 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7862 ResolveInfo ri = mContext.getPackageManager()
7863 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007864 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865 CharSequence errorMsg = null;
7866 if (ri != null) {
7867 ActivityInfo ai = ri.activityInfo;
7868 ApplicationInfo app = ai.applicationInfo;
7869 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7870 mTopAction = Intent.ACTION_FACTORY_TEST;
7871 mTopData = null;
7872 mTopComponent = new ComponentName(app.packageName,
7873 ai.name);
7874 } else {
7875 errorMsg = mContext.getResources().getText(
7876 com.android.internal.R.string.factorytest_not_system);
7877 }
7878 } else {
7879 errorMsg = mContext.getResources().getText(
7880 com.android.internal.R.string.factorytest_no_action);
7881 }
7882 if (errorMsg != null) {
7883 mTopAction = null;
7884 mTopData = null;
7885 mTopComponent = null;
7886 Message msg = Message.obtain();
7887 msg.what = SHOW_FACTORY_ERROR_MSG;
7888 msg.getData().putCharSequence("msg", errorMsg);
7889 mHandler.sendMessage(msg);
7890 }
7891 }
7892 }
7893
7894 retrieveSettings();
7895
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007896 if (goingCallback != null) goingCallback.run();
7897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007898 synchronized (this) {
7899 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7900 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007901 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007902 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007903 if (apps != null) {
7904 int N = apps.size();
7905 int i;
7906 for (i=0; i<N; i++) {
7907 ApplicationInfo info
7908 = (ApplicationInfo)apps.get(i);
7909 if (info != null &&
7910 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007911 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007912 }
7913 }
7914 }
7915 } catch (RemoteException ex) {
7916 // pm is in same process, this will never happen.
7917 }
7918 }
7919
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007920 // Start up initial activity.
7921 mBooting = true;
7922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007923 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007924 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 Message msg = Message.obtain();
7926 msg.what = SHOW_UID_ERROR_MSG;
7927 mHandler.sendMessage(msg);
7928 }
7929 } catch (RemoteException e) {
7930 }
7931
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007932 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 }
7934 }
7935
Dan Egnorb7f03672009-12-09 16:22:32 -08007936 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007937 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007938 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007939 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007940 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007941 startAppProblemLocked(app);
7942 app.stopFreezingAllLocked();
7943 return handleAppCrashLocked(app);
7944 }
7945
Dan Egnorb7f03672009-12-09 16:22:32 -08007946 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007947 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007949 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007950 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7951 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007952 startAppProblemLocked(app);
7953 app.stopFreezingAllLocked();
7954 }
7955
7956 /**
7957 * Generate a process error record, suitable for attachment to a ProcessRecord.
7958 *
7959 * @param app The ProcessRecord in which the error occurred.
7960 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7961 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007962 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007963 * @param shortMsg Short message describing the crash.
7964 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007965 * @param stackTrace Full crash stack trace, may be null.
7966 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 * @return Returns a fully-formed AppErrorStateInfo record.
7968 */
7969 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007970 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007971 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007973 report.condition = condition;
7974 report.processName = app.processName;
7975 report.pid = app.pid;
7976 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007977 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007978 report.shortMsg = shortMsg;
7979 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007980 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007981
7982 return report;
7983 }
7984
Dan Egnor42471dd2010-01-07 17:25:22 -08007985 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 synchronized (this) {
7987 app.crashing = false;
7988 app.crashingReport = null;
7989 app.notResponding = false;
7990 app.notRespondingReport = null;
7991 if (app.anrDialog == fromDialog) {
7992 app.anrDialog = null;
7993 }
7994 if (app.waitDialog == fromDialog) {
7995 app.waitDialog = null;
7996 }
7997 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007998 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007999 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07008000 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
8001 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008002 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 }
8005 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008006
Dan Egnorb7f03672009-12-09 16:22:32 -08008007 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008008 long now = SystemClock.uptimeMillis();
8009
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008010 Long crashTime;
8011 if (!app.isolated) {
8012 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8013 } else {
8014 crashTime = null;
8015 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07008016 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008017 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008018 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008019 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08008020 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008021 app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008022 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8023 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008025 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008027 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 }
8029 }
8030 if (!app.persistent) {
8031 // We don't want to start this process again until the user
8032 // explicitly does so... but for persistent process, we really
8033 // need to keep it running. If a persistent process is actually
8034 // repeatedly crashing, then badness for everyone.
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008035 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008037 if (!app.isolated) {
8038 // XXX We don't have a way to mark isolated processes
8039 // as bad, since they don't have a peristent identity.
8040 mBadProcesses.put(app.info.processName, app.uid, now);
8041 mProcessCrashTimes.remove(app.info.processName, app.uid);
8042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008044 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07008045 // Don't let services in this process be restarted and potentially
8046 // annoy the user repeatedly. Unless it is persistent, since those
8047 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08008048 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08008049 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008050 return false;
8051 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08008052 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008053 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008054 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008055 if (r.app == app) {
8056 // If the top running activity is from this crashing
8057 // process, then terminate it to avoid getting in a loop.
8058 Slog.w(TAG, " Force finishing activity "
8059 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08008060 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008061 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008062 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08008063 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008064 // stopped, to avoid a situation where one will get
8065 // re-start our crashing activity once it gets resumed again.
8066 index--;
8067 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008068 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008069 if (r.state == ActivityState.RESUMED
8070 || r.state == ActivityState.PAUSING
8071 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008072 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008073 Slog.w(TAG, " Force finishing activity "
8074 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008075 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008076 Activity.RESULT_CANCELED, null, "crashed");
8077 }
8078 }
8079 }
8080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008081 }
8082
8083 // Bump up the crash count of any services currently running in the proc.
8084 if (app.services.size() != 0) {
8085 // Any services running in the application need to be placed
8086 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008087 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008089 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008090 sr.crashCount++;
8091 }
8092 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02008093
8094 // If the crashing process is what we consider to be the "home process" and it has been
8095 // replaced by a third-party app, clear the package preferred activities from packages
8096 // with a home activity running in the process to prevent a repeatedly crashing app
8097 // from blocking the user to manually clear the list.
8098 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8099 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8100 Iterator it = mHomeProcess.activities.iterator();
8101 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07008102 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02008103 if (r.isHomeActivity) {
8104 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8105 try {
8106 ActivityThread.getPackageManager()
8107 .clearPackagePreferredActivities(r.packageName);
8108 } catch (RemoteException c) {
8109 // pm is in same process, this will never happen.
8110 }
8111 }
8112 }
8113 }
8114
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008115 if (!app.isolated) {
8116 // XXX Can't keep track of crash times for isolated processes,
8117 // because they don't have a perisistent identity.
8118 mProcessCrashTimes.put(app.info.processName, app.uid, now);
8119 }
8120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008121 return true;
8122 }
8123
8124 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08008125 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8126 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008127 skipCurrentReceiverLocked(app);
8128 }
8129
8130 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08008131 for (BroadcastQueue queue : mBroadcastQueues) {
8132 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008133 }
8134 }
8135
Dan Egnor60d87622009-12-16 16:32:58 -08008136 /**
8137 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8138 * The application process will exit immediately after this call returns.
8139 * @param app object of the crashing app, null for the system server
8140 * @param crashInfo describing the exception
8141 */
8142 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008143 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008144 final String processName = app == null ? "system_server"
8145 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008146
8147 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008148 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008149 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008150 crashInfo.exceptionClassName,
8151 crashInfo.exceptionMessage,
8152 crashInfo.throwFileName,
8153 crashInfo.throwLineNumber);
8154
Jeff Sharkeya353d262011-10-28 11:12:06 -07008155 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008156
8157 crashApplication(r, crashInfo);
8158 }
8159
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008160 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008161 IBinder app,
8162 int violationMask,
8163 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008164 ProcessRecord r = findAppProcess(app, "StrictMode");
8165 if (r == null) {
8166 return;
8167 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008168
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008169 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08008170 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008171 boolean logIt = true;
8172 synchronized (mAlreadyLoggedViolatedStacks) {
8173 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8174 logIt = false;
8175 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008176 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008177 // the relative pain numbers, without logging all
8178 // the stack traces repeatedly. We'd want to do
8179 // likewise in the client code, which also does
8180 // dup suppression, before the Binder call.
8181 } else {
8182 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8183 mAlreadyLoggedViolatedStacks.clear();
8184 }
8185 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8186 }
8187 }
8188 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008189 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008190 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008191 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008192
8193 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8194 AppErrorResult result = new AppErrorResult();
8195 synchronized (this) {
8196 final long origId = Binder.clearCallingIdentity();
8197
8198 Message msg = Message.obtain();
8199 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8200 HashMap<String, Object> data = new HashMap<String, Object>();
8201 data.put("result", result);
8202 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008203 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008204 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008205 msg.obj = data;
8206 mHandler.sendMessage(msg);
8207
8208 Binder.restoreCallingIdentity(origId);
8209 }
8210 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07008211 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008212 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008213 }
8214
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008215 // Depending on the policy in effect, there could be a bunch of
8216 // these in quick succession so we try to batch these together to
8217 // minimize disk writes, number of dropbox entries, and maximize
8218 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008219 private void logStrictModeViolationToDropBox(
8220 ProcessRecord process,
8221 StrictMode.ViolationInfo info) {
8222 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008223 return;
8224 }
8225 final boolean isSystemApp = process == null ||
8226 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8227 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008228 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008229 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8230 final DropBoxManager dbox = (DropBoxManager)
8231 mContext.getSystemService(Context.DROPBOX_SERVICE);
8232
8233 // Exit early if the dropbox isn't configured to accept this report type.
8234 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8235
8236 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008237 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008238 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8239 synchronized (sb) {
8240 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008241 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008242 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8243 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008244 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8245 if (info.violationNumThisLoop != 0) {
8246 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8247 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07008248 if (info.numAnimationsRunning != 0) {
8249 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8250 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07008251 if (info.broadcastIntentAction != null) {
8252 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8253 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008254 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008255 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008256 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08008257 if (info.numInstances != -1) {
8258 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8259 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008260 if (info.tags != null) {
8261 for (String tag : info.tags) {
8262 sb.append("Span-Tag: ").append(tag).append("\n");
8263 }
8264 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008265 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008266 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8267 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008268 }
8269 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008270
8271 // Only buffer up to ~64k. Various logging bits truncate
8272 // things at 128k.
8273 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008274 }
8275
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008276 // Flush immediately if the buffer's grown too large, or this
8277 // is a non-system app. Non-system apps are isolated with a
8278 // different tag & policy and not batched.
8279 //
8280 // Batching is useful during internal testing with
8281 // StrictMode settings turned up high. Without batching,
8282 // thousands of separate files could be created on boot.
8283 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008284 new Thread("Error dump: " + dropboxTag) {
8285 @Override
8286 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008287 String report;
8288 synchronized (sb) {
8289 report = sb.toString();
8290 sb.delete(0, sb.length());
8291 sb.trimToSize();
8292 }
8293 if (report.length() != 0) {
8294 dbox.addText(dropboxTag, report);
8295 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008296 }
8297 }.start();
8298 return;
8299 }
8300
8301 // System app batching:
8302 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008303 // An existing dropbox-writing thread is outstanding, so
8304 // we don't need to start it up. The existing thread will
8305 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008306 return;
8307 }
8308
8309 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8310 // (After this point, we shouldn't access AMS internal data structures.)
8311 new Thread("Error dump: " + dropboxTag) {
8312 @Override
8313 public void run() {
8314 // 5 second sleep to let stacks arrive and be batched together
8315 try {
8316 Thread.sleep(5000); // 5 seconds
8317 } catch (InterruptedException e) {}
8318
8319 String errorReport;
8320 synchronized (mStrictModeBuffer) {
8321 errorReport = mStrictModeBuffer.toString();
8322 if (errorReport.length() == 0) {
8323 return;
8324 }
8325 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8326 mStrictModeBuffer.trimToSize();
8327 }
8328 dbox.addText(dropboxTag, errorReport);
8329 }
8330 }.start();
8331 }
8332
Dan Egnor60d87622009-12-16 16:32:58 -08008333 /**
8334 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8335 * @param app object of the crashing app, null for the system server
8336 * @param tag reported by the caller
8337 * @param crashInfo describing the context of the error
8338 * @return true if the process should exit immediately (WTF is fatal)
8339 */
8340 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008341 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008342 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008343 final String processName = app == null ? "system_server"
8344 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008345
8346 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008347 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008348 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008349 tag, crashInfo.exceptionMessage);
8350
Jeff Sharkeya353d262011-10-28 11:12:06 -07008351 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008352
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008353 if (r != null && r.pid != Process.myPid() &&
8354 Settings.Secure.getInt(mContext.getContentResolver(),
8355 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008356 crashApplication(r, crashInfo);
8357 return true;
8358 } else {
8359 return false;
8360 }
8361 }
8362
8363 /**
8364 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8365 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8366 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008367 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008368 if (app == null) {
8369 return null;
8370 }
8371
8372 synchronized (this) {
8373 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8374 final int NA = apps.size();
8375 for (int ia=0; ia<NA; ia++) {
8376 ProcessRecord p = apps.valueAt(ia);
8377 if (p.thread != null && p.thread.asBinder() == app) {
8378 return p;
8379 }
8380 }
8381 }
8382
Dianne Hackborncb44d962011-03-10 17:02:27 -08008383 Slog.w(TAG, "Can't find mystery application for " + reason
8384 + " from pid=" + Binder.getCallingPid()
8385 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008386 return null;
8387 }
8388 }
8389
8390 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008391 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8392 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008393 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008394 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8395 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008396 // Watchdog thread ends up invoking this function (with
8397 // a null ProcessRecord) to add the stack file to dropbox.
8398 // Do not acquire a lock on this (am) in such cases, as it
8399 // could cause a potential deadlock, if and when watchdog
8400 // is invoked due to unavailability of lock on am and it
8401 // would prevent watchdog from killing system_server.
8402 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008403 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008404 return;
8405 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008406 // Note: ProcessRecord 'process' is guarded by the service
8407 // instance. (notably process.pkgList, which could otherwise change
8408 // concurrently during execution of this method)
8409 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008410 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008411 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008412 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008413 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8414 for (String pkg : process.pkgList) {
8415 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008416 try {
Dan Egnora455d192010-03-12 08:52:28 -08008417 PackageInfo pi = pm.getPackageInfo(pkg, 0);
8418 if (pi != null) {
8419 sb.append(" v").append(pi.versionCode);
8420 if (pi.versionName != null) {
8421 sb.append(" (").append(pi.versionName).append(")");
8422 }
8423 }
8424 } catch (RemoteException e) {
8425 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008426 }
Dan Egnora455d192010-03-12 08:52:28 -08008427 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008428 }
Dan Egnora455d192010-03-12 08:52:28 -08008429 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008430 }
8431
8432 private static String processClass(ProcessRecord process) {
8433 if (process == null || process.pid == MY_PID) {
8434 return "system_server";
8435 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8436 return "system_app";
8437 } else {
8438 return "data_app";
8439 }
8440 }
8441
8442 /**
8443 * Write a description of an error (crash, WTF, ANR) to the drop box.
8444 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8445 * @param process which caused the error, null means the system server
8446 * @param activity which triggered the error, null if unknown
8447 * @param parent activity related to the error, null if unknown
8448 * @param subject line related to the error, null if absent
8449 * @param report in long form describing the error, null if absent
8450 * @param logFile to include in the report, null if none
8451 * @param crashInfo giving an application stack trace, null if absent
8452 */
8453 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008454 ProcessRecord process, String processName, ActivityRecord activity,
8455 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008456 final String report, final File logFile,
8457 final ApplicationErrorReport.CrashInfo crashInfo) {
8458 // NOTE -- this must never acquire the ActivityManagerService lock,
8459 // otherwise the watchdog may be prevented from resetting the system.
8460
8461 final String dropboxTag = processClass(process) + "_" + eventType;
8462 final DropBoxManager dbox = (DropBoxManager)
8463 mContext.getSystemService(Context.DROPBOX_SERVICE);
8464
8465 // Exit early if the dropbox isn't configured to accept this report type.
8466 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8467
8468 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008469 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008470 if (activity != null) {
8471 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8472 }
8473 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8474 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8475 }
8476 if (parent != null && parent != activity) {
8477 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8478 }
8479 if (subject != null) {
8480 sb.append("Subject: ").append(subject).append("\n");
8481 }
8482 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008483 if (Debug.isDebuggerConnected()) {
8484 sb.append("Debugger: Connected\n");
8485 }
Dan Egnora455d192010-03-12 08:52:28 -08008486 sb.append("\n");
8487
8488 // Do the rest in a worker thread to avoid blocking the caller on I/O
8489 // (After this point, we shouldn't access AMS internal data structures.)
8490 Thread worker = new Thread("Error dump: " + dropboxTag) {
8491 @Override
8492 public void run() {
8493 if (report != null) {
8494 sb.append(report);
8495 }
8496 if (logFile != null) {
8497 try {
8498 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8499 } catch (IOException e) {
8500 Slog.e(TAG, "Error reading " + logFile, e);
8501 }
8502 }
8503 if (crashInfo != null && crashInfo.stackTrace != null) {
8504 sb.append(crashInfo.stackTrace);
8505 }
8506
8507 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8508 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8509 if (lines > 0) {
8510 sb.append("\n");
8511
8512 // Merge several logcat streams, and take the last N lines
8513 InputStreamReader input = null;
8514 try {
8515 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8516 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8517 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8518
8519 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8520 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8521 input = new InputStreamReader(logcat.getInputStream());
8522
8523 int num;
8524 char[] buf = new char[8192];
8525 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8526 } catch (IOException e) {
8527 Slog.e(TAG, "Error running logcat", e);
8528 } finally {
8529 if (input != null) try { input.close(); } catch (IOException e) {}
8530 }
8531 }
8532
8533 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008534 }
Dan Egnora455d192010-03-12 08:52:28 -08008535 };
8536
8537 if (process == null || process.pid == MY_PID) {
8538 worker.run(); // We may be about to die -- need to run this synchronously
8539 } else {
8540 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008541 }
8542 }
8543
8544 /**
8545 * Bring up the "unexpected error" dialog box for a crashing app.
8546 * Deal with edge cases (intercepts from instrumented applications,
8547 * ActivityController, error intent receivers, that sort of thing).
8548 * @param r the application crashing
8549 * @param crashInfo describing the failure
8550 */
8551 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008552 long timeMillis = System.currentTimeMillis();
8553 String shortMsg = crashInfo.exceptionClassName;
8554 String longMsg = crashInfo.exceptionMessage;
8555 String stackTrace = crashInfo.stackTrace;
8556 if (shortMsg != null && longMsg != null) {
8557 longMsg = shortMsg + ": " + longMsg;
8558 } else if (shortMsg != null) {
8559 longMsg = shortMsg;
8560 }
8561
Dan Egnor60d87622009-12-16 16:32:58 -08008562 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008564 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008565 try {
8566 String name = r != null ? r.processName : null;
8567 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008568 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008569 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008570 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008571 + " at watcher's request");
8572 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008573 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008574 }
8575 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008576 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008577 }
8578 }
8579
8580 final long origId = Binder.clearCallingIdentity();
8581
8582 // If this process is running instrumentation, finish it.
8583 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008584 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008586 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8587 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008588 Bundle info = new Bundle();
8589 info.putString("shortMsg", shortMsg);
8590 info.putString("longMsg", longMsg);
8591 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8592 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008593 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 }
8595
Dan Egnor60d87622009-12-16 16:32:58 -08008596 // If we can't identify the process or it's already exceeded its crash quota,
8597 // quit right away without showing a crash dialog.
8598 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008599 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008600 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 }
8602
8603 Message msg = Message.obtain();
8604 msg.what = SHOW_ERROR_MSG;
8605 HashMap data = new HashMap();
8606 data.put("result", result);
8607 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 msg.obj = data;
8609 mHandler.sendMessage(msg);
8610
8611 Binder.restoreCallingIdentity(origId);
8612 }
8613
8614 int res = result.get();
8615
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008616 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008617 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008618 if (r != null && !r.isolated) {
8619 // XXX Can't keep track of crash time for isolated processes,
8620 // since they don't have a persistent identity.
8621 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008622 SystemClock.uptimeMillis());
8623 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008624 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008625 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008626 }
8627 }
8628
8629 if (appErrorIntent != null) {
8630 try {
8631 mContext.startActivity(appErrorIntent);
8632 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008633 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008635 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008636 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008637
8638 Intent createAppErrorIntentLocked(ProcessRecord r,
8639 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8640 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008641 if (report == null) {
8642 return null;
8643 }
8644 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8645 result.setComponent(r.errorReportReceiver);
8646 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8647 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8648 return result;
8649 }
8650
Dan Egnorb7f03672009-12-09 16:22:32 -08008651 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8652 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008653 if (r.errorReportReceiver == null) {
8654 return null;
8655 }
8656
8657 if (!r.crashing && !r.notResponding) {
8658 return null;
8659 }
8660
Dan Egnorb7f03672009-12-09 16:22:32 -08008661 ApplicationErrorReport report = new ApplicationErrorReport();
8662 report.packageName = r.info.packageName;
8663 report.installerPackageName = r.errorReportReceiver.getPackageName();
8664 report.processName = r.processName;
8665 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008666 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008667
Dan Egnorb7f03672009-12-09 16:22:32 -08008668 if (r.crashing) {
8669 report.type = ApplicationErrorReport.TYPE_CRASH;
8670 report.crashInfo = crashInfo;
8671 } else if (r.notResponding) {
8672 report.type = ApplicationErrorReport.TYPE_ANR;
8673 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008674
Dan Egnorb7f03672009-12-09 16:22:32 -08008675 report.anrInfo.activity = r.notRespondingReport.tag;
8676 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8677 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008678 }
8679
Dan Egnorb7f03672009-12-09 16:22:32 -08008680 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008681 }
8682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008683 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008684 enforceNotIsolatedCaller("getProcessesInErrorState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008685 // assume our apps are happy - lazy create the list
8686 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8687
8688 synchronized (this) {
8689
8690 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008691 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8692 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008693 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8694 // This one's in trouble, so we'll generate a report for it
8695 // crashes are higher priority (in case there's a crash *and* an anr)
8696 ActivityManager.ProcessErrorStateInfo report = null;
8697 if (app.crashing) {
8698 report = app.crashingReport;
8699 } else if (app.notResponding) {
8700 report = app.notRespondingReport;
8701 }
8702
8703 if (report != null) {
8704 if (errList == null) {
8705 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8706 }
8707 errList.add(report);
8708 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008709 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008710 " crashing = " + app.crashing +
8711 " notResponding = " + app.notResponding);
8712 }
8713 }
8714 }
8715 }
8716
8717 return errList;
8718 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008719
8720 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008721 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008722 if (currApp != null) {
8723 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8724 }
8725 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008726 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8727 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008728 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8729 if (currApp != null) {
8730 currApp.lru = 0;
8731 }
8732 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008733 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008734 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8735 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8736 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8737 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8738 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8739 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8740 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8741 } else {
8742 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8743 }
8744 }
8745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008746 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008747 enforceNotIsolatedCaller("getRunningAppProcesses");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008748 // Lazy instantiation of list
8749 List<ActivityManager.RunningAppProcessInfo> runList = null;
8750 synchronized (this) {
8751 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008752 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8753 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008754 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8755 // Generate process state info for running application
8756 ActivityManager.RunningAppProcessInfo currApp =
8757 new ActivityManager.RunningAppProcessInfo(app.processName,
8758 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07008759 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008760 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07008761 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008762 }
Dianne Hackborn42499172010-10-15 18:45:07 -07008763 if (app.persistent) {
8764 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008766 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008767 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008768 currApp.importanceReasonCode = app.adjTypeCode;
8769 if (app.adjSource instanceof ProcessRecord) {
8770 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008771 currApp.importanceReasonImportance = oomAdjToImportance(
8772 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008773 } else if (app.adjSource instanceof ActivityRecord) {
8774 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008775 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8776 }
8777 if (app.adjTarget instanceof ComponentName) {
8778 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8779 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008780 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008781 // + " lru=" + currApp.lru);
8782 if (runList == null) {
8783 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8784 }
8785 runList.add(currApp);
8786 }
8787 }
8788 }
8789 return runList;
8790 }
8791
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008792 public List<ApplicationInfo> getRunningExternalApplications() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008793 enforceNotIsolatedCaller("getRunningExternalApplications");
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008794 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8795 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8796 if (runningApps != null && runningApps.size() > 0) {
8797 Set<String> extList = new HashSet<String>();
8798 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8799 if (app.pkgList != null) {
8800 for (String pkg : app.pkgList) {
8801 extList.add(pkg);
8802 }
8803 }
8804 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008805 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008806 for (String pkg : extList) {
8807 try {
8808 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
8809 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8810 retList.add(info);
8811 }
8812 } catch (RemoteException e) {
8813 }
8814 }
8815 }
8816 return retList;
8817 }
8818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008819 @Override
8820 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008821 if (checkCallingPermission(android.Manifest.permission.DUMP)
8822 != PackageManager.PERMISSION_GRANTED) {
8823 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8824 + Binder.getCallingPid()
8825 + ", uid=" + Binder.getCallingUid()
8826 + " without permission "
8827 + android.Manifest.permission.DUMP);
8828 return;
8829 }
8830
8831 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008832 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008833 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008834
8835 int opti = 0;
8836 while (opti < args.length) {
8837 String opt = args[opti];
8838 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8839 break;
8840 }
8841 opti++;
8842 if ("-a".equals(opt)) {
8843 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008844 } else if ("-c".equals(opt)) {
8845 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008846 } else if ("-h".equals(opt)) {
8847 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008848 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008849 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008850 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008851 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8852 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8853 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008854 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008855 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008856 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008857 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008858 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008859 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008860 pw.println(" all: dump all activities");
8861 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008862 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008863 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8864 pw.println(" a partial substring in a component name, a");
8865 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008866 pw.println(" -a: include all available server state.");
8867 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008868 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008869 } else {
8870 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008871 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008872 }
8873
8874 // Is the caller requesting to dump a particular piece of data?
8875 if (opti < args.length) {
8876 String cmd = args[opti];
8877 opti++;
8878 if ("activities".equals(cmd) || "a".equals(cmd)) {
8879 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008880 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008882 return;
8883 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008884 String[] newArgs;
8885 String name;
8886 if (opti >= args.length) {
8887 name = null;
8888 newArgs = EMPTY_STRING_ARRAY;
8889 } else {
8890 name = args[opti];
8891 opti++;
8892 newArgs = new String[args.length - opti];
8893 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8894 args.length - opti);
8895 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008896 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008897 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008898 }
8899 return;
8900 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008901 String[] newArgs;
8902 String name;
8903 if (opti >= args.length) {
8904 name = null;
8905 newArgs = EMPTY_STRING_ARRAY;
8906 } else {
8907 name = args[opti];
8908 opti++;
8909 newArgs = new String[args.length - opti];
8910 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8911 args.length - opti);
8912 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008913 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008914 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008915 }
8916 return;
8917 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008918 String[] newArgs;
8919 String name;
8920 if (opti >= args.length) {
8921 name = null;
8922 newArgs = EMPTY_STRING_ARRAY;
8923 } else {
8924 name = args[opti];
8925 opti++;
8926 newArgs = new String[args.length - opti];
8927 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8928 args.length - opti);
8929 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008930 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008931 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008932 }
8933 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008934 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8935 synchronized (this) {
8936 dumpOomLocked(fd, pw, args, opti, true);
8937 }
8938 return;
Marco Nelissen18cb2872011-11-15 11:19:53 -08008939 } else if ("provider".equals(cmd)) {
8940 String[] newArgs;
8941 String name;
8942 if (opti >= args.length) {
8943 name = null;
8944 newArgs = EMPTY_STRING_ARRAY;
8945 } else {
8946 name = args[opti];
8947 opti++;
8948 newArgs = new String[args.length - opti];
8949 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8950 }
8951 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8952 pw.println("No providers match: " + name);
8953 pw.println("Use -h for help.");
8954 }
8955 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008956 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8957 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008958 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008959 }
8960 return;
8961 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008962 String[] newArgs;
8963 String name;
8964 if (opti >= args.length) {
8965 name = null;
8966 newArgs = EMPTY_STRING_ARRAY;
8967 } else {
8968 name = args[opti];
8969 opti++;
8970 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008971 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8972 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008973 }
8974 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8975 pw.println("No services match: " + name);
8976 pw.println("Use -h for help.");
8977 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008978 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008979 } else if ("package".equals(cmd)) {
8980 String[] newArgs;
8981 if (opti >= args.length) {
8982 pw.println("package: no package name specified");
8983 pw.println("Use -h for help.");
8984 return;
8985 } else {
8986 dumpPackage = args[opti];
8987 opti++;
8988 newArgs = new String[args.length - opti];
8989 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8990 args.length - opti);
8991 args = newArgs;
8992 opti = 0;
8993 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008994 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8995 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008996 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008997 }
8998 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008999 } else {
9000 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009001 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9002 pw.println("Bad activity command, or no activities match: " + cmd);
9003 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009004 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009005 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009006 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009007 }
9008
9009 // No piece of data specified, dump everything.
9010 synchronized (this) {
9011 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009012 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009013 if (needSep) {
9014 pw.println(" ");
9015 }
9016 if (dumpAll) {
9017 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009018 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009019 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009020 if (needSep) {
9021 pw.println(" ");
9022 }
9023 if (dumpAll) {
9024 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009025 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009026 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009027 if (needSep) {
9028 pw.println(" ");
9029 }
9030 if (dumpAll) {
9031 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009032 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009033 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009034 if (needSep) {
9035 pw.println(" ");
9036 }
9037 if (dumpAll) {
9038 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009039 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009040 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009041 if (needSep) {
9042 pw.println(" ");
9043 }
9044 if (dumpAll) {
9045 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009046 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009047 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009048 }
9049 }
9050
9051 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009052 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009053 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9054 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009055 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
9056 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009057 pw.println(" ");
9058 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009059 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
9060 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009061 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009062 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009063 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009064 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009065 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009066 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009067 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009068 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009069 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009070 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009071 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009072 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009073 if (mMainStack.mGoingToSleepActivities.size() > 0) {
9074 pw.println(" ");
9075 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009076 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009077 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009078 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009079 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009080 pw.println(" ");
9081 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009082 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009083 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009085
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009086 pw.println(" ");
Dianne Hackborncbb722e2012-02-07 18:33:49 -08009087 if (mMainStack.mPausingActivities.size() > 0) {
9088 pw.println(" mPausingActivities: " + Arrays.toString(
9089 mMainStack.mPausingActivities.toArray()));
9090 }
9091 if (mMainStack.mInputPausedActivities.size() > 0) {
9092 pw.println(" mInputPausedActivities: " + Arrays.toString(
9093 mMainStack.mInputPausedActivities.toArray()));
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009094 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009095 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009096 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009097 if (dumpAll) {
9098 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9099 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009100 pw.println(" mDismissKeyguardOnNextActivity: "
9101 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009103
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009104 if (mRecentTasks.size() > 0) {
9105 pw.println();
9106 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009107
9108 final int N = mRecentTasks.size();
9109 for (int i=0; i<N; i++) {
9110 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009111 if (dumpPackage != null) {
9112 if (tr.realActivity == null ||
9113 !dumpPackage.equals(tr.realActivity)) {
9114 continue;
9115 }
9116 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009117 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
9118 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009119 if (dumpAll) {
9120 mRecentTasks.get(i).dump(pw, " ");
9121 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009122 }
9123 }
9124
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009125 if (dumpAll) {
9126 pw.println(" ");
9127 pw.println(" mCurTask: " + mCurTask);
9128 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009129
9130 return true;
9131 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009132
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009133 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009134 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009135 boolean needSep = false;
9136 int numPers = 0;
9137
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009138 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9139
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009140 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009141 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9142 final int NA = procs.size();
9143 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009144 ProcessRecord r = procs.valueAt(ia);
9145 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9146 continue;
9147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009148 if (!needSep) {
9149 pw.println(" All known processes:");
9150 needSep = true;
9151 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009152 pw.print(r.persistent ? " *PERS*" : " *APP*");
9153 pw.print(" UID "); pw.print(procs.keyAt(ia));
9154 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009155 r.dump(pw, " ");
9156 if (r.persistent) {
9157 numPers++;
9158 }
9159 }
9160 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009161 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08009162
9163 if (mIsolatedProcesses.size() > 0) {
9164 if (needSep) pw.println(" ");
9165 needSep = true;
9166 pw.println(" Isolated process list (sorted by uid):");
9167 for (int i=0; i<mIsolatedProcesses.size(); i++) {
9168 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9169 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9170 continue;
9171 }
9172 pw.println(String.format("%sIsolated #%2d: %s",
9173 " ", i, r.toString()));
9174 }
9175 }
9176
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009177 if (mLruProcesses.size() > 0) {
9178 if (needSep) pw.println(" ");
9179 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07009180 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009181 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009182 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009183 needSep = true;
9184 }
9185
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009186 if (dumpAll) {
9187 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009188 boolean printed = false;
9189 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9190 ProcessRecord r = mPidsSelfLocked.valueAt(i);
9191 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9192 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009193 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009194 if (!printed) {
9195 if (needSep) pw.println(" ");
9196 needSep = true;
9197 pw.println(" PID mappings:");
9198 printed = true;
9199 }
9200 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9201 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202 }
9203 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009204 }
9205
9206 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009207 synchronized (mPidsSelfLocked) {
9208 boolean printed = false;
9209 for (int i=0; i<mForegroundProcesses.size(); i++) {
9210 ProcessRecord r = mPidsSelfLocked.get(
9211 mForegroundProcesses.valueAt(i).pid);
9212 if (dumpPackage != null && (r == null
9213 || !dumpPackage.equals(r.info.packageName))) {
9214 continue;
9215 }
9216 if (!printed) {
9217 if (needSep) pw.println(" ");
9218 needSep = true;
9219 pw.println(" Foreground Processes:");
9220 printed = true;
9221 }
9222 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9223 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009225 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009226 }
9227
9228 if (mPersistentStartingProcesses.size() > 0) {
9229 if (needSep) pw.println(" ");
9230 needSep = true;
9231 pw.println(" Persisent processes that are starting:");
9232 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009233 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009235
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009236 if (mRemovedProcesses.size() > 0) {
9237 if (needSep) pw.println(" ");
9238 needSep = true;
9239 pw.println(" Processes that are being removed:");
9240 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009241 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009242 }
9243
9244 if (mProcessesOnHold.size() > 0) {
9245 if (needSep) pw.println(" ");
9246 needSep = true;
9247 pw.println(" Processes that are on old until the system is ready:");
9248 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009249 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009252 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009253
9254 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009255 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009256 long now = SystemClock.uptimeMillis();
9257 for (Map.Entry<String, SparseArray<Long>> procs
9258 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009259 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009260 SparseArray<Long> uids = procs.getValue();
9261 final int N = uids.size();
9262 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009263 int puid = uids.keyAt(i);
9264 ProcessRecord r = mProcessNames.get(pname, puid);
9265 if (dumpPackage != null && (r == null
9266 || !dumpPackage.equals(r.info.packageName))) {
9267 continue;
9268 }
9269 if (!printed) {
9270 if (needSep) pw.println(" ");
9271 needSep = true;
9272 pw.println(" Time since processes crashed:");
9273 printed = true;
9274 }
9275 pw.print(" Process "); pw.print(pname);
9276 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009277 pw.print(": last crashed ");
9278 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009279 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009280 }
9281 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009284 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009285 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009286 for (Map.Entry<String, SparseArray<Long>> procs
9287 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009288 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009289 SparseArray<Long> uids = procs.getValue();
9290 final int N = uids.size();
9291 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009292 int puid = uids.keyAt(i);
9293 ProcessRecord r = mProcessNames.get(pname, puid);
9294 if (dumpPackage != null && (r == null
9295 || !dumpPackage.equals(r.info.packageName))) {
9296 continue;
9297 }
9298 if (!printed) {
9299 if (needSep) pw.println(" ");
9300 needSep = true;
9301 pw.println(" Bad processes:");
9302 }
9303 pw.print(" Bad process "); pw.print(pname);
9304 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009305 pw.print(": crashed at time ");
9306 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 }
9308 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009310
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009311 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009312 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009313 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009314 if (dumpAll) {
9315 StringBuilder sb = new StringBuilder(128);
9316 sb.append(" mPreviousProcessVisibleTime: ");
9317 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9318 pw.println(sb);
9319 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009320 if (mHeavyWeightProcess != null) {
9321 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9322 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009323 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009324 if (dumpAll) {
9325 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009326 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009327 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009328 for (Map.Entry<String, Integer> entry
9329 : mCompatModePackages.getPackages().entrySet()) {
9330 String pkg = entry.getKey();
9331 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009332 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9333 continue;
9334 }
9335 if (!printed) {
9336 pw.println(" mScreenCompatPackages:");
9337 printed = true;
9338 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009339 pw.print(" "); pw.print(pkg); pw.print(": ");
9340 pw.print(mode); pw.println();
9341 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009342 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009343 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009344 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9345 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9346 || mOrigWaitForDebugger) {
9347 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9348 + " mDebugTransient=" + mDebugTransient
9349 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9350 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009351 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9352 || mProfileFd != null) {
9353 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9354 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9355 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9356 + mAutoStopProfiler);
9357 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009358 if (mAlwaysFinishActivities || mController != null) {
9359 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9360 + " mController=" + mController);
9361 }
9362 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009364 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009365 + " mProcessesReady=" + mProcessesReady
9366 + " mSystemReady=" + mSystemReady);
9367 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009368 + " mBooted=" + mBooted
9369 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009370 pw.print(" mLastPowerCheckRealtime=");
9371 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9372 pw.println("");
9373 pw.print(" mLastPowerCheckUptime=");
9374 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9375 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009376 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9377 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009378 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009379 pw.println(" mNumServiceProcs=" + mNumServiceProcs
9380 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009382
9383 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009384 }
9385
Dianne Hackborn287952c2010-09-22 22:34:31 -07009386 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009387 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009388 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009389 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009390 long now = SystemClock.uptimeMillis();
9391 for (int i=0; i<mProcessesToGc.size(); i++) {
9392 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009393 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9394 continue;
9395 }
9396 if (!printed) {
9397 if (needSep) pw.println(" ");
9398 needSep = true;
9399 pw.println(" Processes that are waiting to GC:");
9400 printed = true;
9401 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009402 pw.print(" Process "); pw.println(proc);
9403 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9404 pw.print(", last gced=");
9405 pw.print(now-proc.lastRequestedGc);
9406 pw.print(" ms ago, last lowMem=");
9407 pw.print(now-proc.lastLowMemory);
9408 pw.println(" ms ago");
9409
9410 }
9411 }
9412 return needSep;
9413 }
9414
9415 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9416 int opti, boolean dumpAll) {
9417 boolean needSep = false;
9418
9419 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009420 if (needSep) pw.println(" ");
9421 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009422 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009423 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009424 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009425 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9426 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9427 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9428 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9429 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009430 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009431 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009432 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009433 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009434 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009435 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009436
9437 if (needSep) pw.println(" ");
9438 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009439 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009440 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009441 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009442 needSep = true;
9443 }
9444
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009445 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009446
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009447 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009448 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009449 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009450 if (mHeavyWeightProcess != null) {
9451 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9452 }
9453
9454 return true;
9455 }
9456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009457 /**
9458 * There are three ways to call this:
9459 * - no service specified: dump all the services
9460 * - a flattened component name that matched an existing service was specified as the
9461 * first arg: dump that one service
9462 * - the first arg isn't the flattened component name of an existing service:
9463 * dump all services whose component contains the first arg as a substring
9464 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009465 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9466 int opti, boolean dumpAll) {
9467 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009468
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009469 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009470 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009471 try {
9472 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9473 for (UserInfo user : users) {
9474 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9475 services.add(r1);
9476 }
9477 }
9478 } catch (RemoteException re) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009479 }
9480 }
9481 } else {
9482 ComponentName componentName = name != null
9483 ? ComponentName.unflattenFromString(name) : null;
9484 int objectId = 0;
9485 if (componentName == null) {
9486 // Not a '/' separated full component name; maybe an object ID?
9487 try {
9488 objectId = Integer.parseInt(name, 16);
9489 name = null;
9490 componentName = null;
9491 } catch (RuntimeException e) {
9492 }
9493 }
9494
9495 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009496 try {
9497 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9498 for (UserInfo user : users) {
9499 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9500 if (componentName != null) {
9501 if (r1.name.equals(componentName)) {
9502 services.add(r1);
9503 }
9504 } else if (name != null) {
9505 if (r1.name.flattenToString().contains(name)) {
9506 services.add(r1);
9507 }
9508 } else if (System.identityHashCode(r1) == objectId) {
9509 services.add(r1);
9510 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009511 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009512 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009513 } catch (RemoteException re) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009514 }
9515 }
9516 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009517
9518 if (services.size() <= 0) {
9519 return false;
9520 }
9521
9522 boolean needSep = false;
9523 for (int i=0; i<services.size(); i++) {
9524 if (needSep) {
9525 pw.println();
9526 }
9527 needSep = true;
9528 dumpService("", fd, pw, services.get(i), args, dumpAll);
9529 }
9530 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 }
9532
9533 /**
9534 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9535 * there is a thread associated with the service.
9536 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009537 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9538 final ServiceRecord r, String[] args, boolean dumpAll) {
9539 String innerPrefix = prefix + " ";
9540 synchronized (this) {
9541 pw.print(prefix); pw.print("SERVICE ");
9542 pw.print(r.shortName); pw.print(" ");
9543 pw.print(Integer.toHexString(System.identityHashCode(r)));
9544 pw.print(" pid=");
9545 if (r.app != null) pw.println(r.app.pid);
9546 else pw.println("(not running)");
9547 if (dumpAll) {
9548 r.dump(pw, innerPrefix);
9549 }
9550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009551 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009552 pw.print(prefix); pw.println(" Client:");
9553 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009554 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009555 TransferPipe tp = new TransferPipe();
9556 try {
9557 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9558 tp.setBufferPrefix(prefix + " ");
9559 tp.go(fd);
9560 } finally {
9561 tp.kill();
9562 }
9563 } catch (IOException e) {
9564 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009566 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 }
9568 }
9569 }
9570
Marco Nelissen18cb2872011-11-15 11:19:53 -08009571 /**
9572 * There are three ways to call this:
9573 * - no provider specified: dump all the providers
9574 * - a flattened component name that matched an existing provider was specified as the
9575 * first arg: dump that one provider
9576 * - the first arg isn't the flattened component name of an existing provider:
9577 * dump all providers whose component contains the first arg as a substring
9578 */
9579 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9580 int opti, boolean dumpAll) {
Marco Nelissende7408c2012-02-08 14:57:38 -08009581 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
Marco Nelissen18cb2872011-11-15 11:19:53 -08009582 }
9583
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009584 static class ItemMatcher {
9585 ArrayList<ComponentName> components;
9586 ArrayList<String> strings;
9587 ArrayList<Integer> objects;
9588 boolean all;
9589
9590 ItemMatcher() {
9591 all = true;
9592 }
9593
9594 void build(String name) {
9595 ComponentName componentName = ComponentName.unflattenFromString(name);
9596 if (componentName != null) {
9597 if (components == null) {
9598 components = new ArrayList<ComponentName>();
9599 }
9600 components.add(componentName);
9601 all = false;
9602 } else {
9603 int objectId = 0;
9604 // Not a '/' separated full component name; maybe an object ID?
9605 try {
9606 objectId = Integer.parseInt(name, 16);
9607 if (objects == null) {
9608 objects = new ArrayList<Integer>();
9609 }
9610 objects.add(objectId);
9611 all = false;
9612 } catch (RuntimeException e) {
9613 // Not an integer; just do string match.
9614 if (strings == null) {
9615 strings = new ArrayList<String>();
9616 }
9617 strings.add(name);
9618 all = false;
9619 }
9620 }
9621 }
9622
9623 int build(String[] args, int opti) {
9624 for (; opti<args.length; opti++) {
9625 String name = args[opti];
9626 if ("--".equals(name)) {
9627 return opti+1;
9628 }
9629 build(name);
9630 }
9631 return opti;
9632 }
9633
9634 boolean match(Object object, ComponentName comp) {
9635 if (all) {
9636 return true;
9637 }
9638 if (components != null) {
9639 for (int i=0; i<components.size(); i++) {
9640 if (components.get(i).equals(comp)) {
9641 return true;
9642 }
9643 }
9644 }
9645 if (objects != null) {
9646 for (int i=0; i<objects.size(); i++) {
9647 if (System.identityHashCode(object) == objects.get(i)) {
9648 return true;
9649 }
9650 }
9651 }
9652 if (strings != null) {
9653 String flat = comp.flattenToString();
9654 for (int i=0; i<strings.size(); i++) {
9655 if (flat.contains(strings.get(i))) {
9656 return true;
9657 }
9658 }
9659 }
9660 return false;
9661 }
9662 }
9663
Dianne Hackborn625ac272010-09-17 18:29:22 -07009664 /**
9665 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009666 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009667 * - the cmd arg isn't the flattened component name of an existing activity:
9668 * dump all activity whose component contains the cmd as a substring
9669 * - A hex number of the ActivityRecord object instance.
9670 */
9671 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9672 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009673 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009674
9675 if ("all".equals(name)) {
9676 synchronized (this) {
9677 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009678 activities.add(r1);
9679 }
9680 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009681 } else if ("top".equals(name)) {
9682 synchronized (this) {
9683 final int N = mMainStack.mHistory.size();
9684 if (N > 0) {
9685 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9686 }
9687 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009688 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009689 ItemMatcher matcher = new ItemMatcher();
9690 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009691
9692 synchronized (this) {
9693 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009694 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009695 activities.add(r1);
9696 }
9697 }
9698 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009699 }
9700
9701 if (activities.size() <= 0) {
9702 return false;
9703 }
9704
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009705 String[] newArgs = new String[args.length - opti];
9706 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9707
Dianne Hackborn30d71892010-12-11 10:37:55 -08009708 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009709 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009710 for (int i=activities.size()-1; i>=0; i--) {
9711 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009712 if (needSep) {
9713 pw.println();
9714 }
9715 needSep = true;
9716 synchronized (this) {
9717 if (lastTask != r.task) {
9718 lastTask = r.task;
9719 pw.print("TASK "); pw.print(lastTask.affinity);
9720 pw.print(" id="); pw.println(lastTask.taskId);
9721 if (dumpAll) {
9722 lastTask.dump(pw, " ");
9723 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009724 }
9725 }
9726 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009727 }
9728 return true;
9729 }
9730
9731 /**
9732 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9733 * there is a thread associated with the activity.
9734 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009735 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009736 final ActivityRecord r, String[] args, boolean dumpAll) {
9737 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009738 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009739 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9740 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9741 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009742 if (r.app != null) pw.println(r.app.pid);
9743 else pw.println("(not running)");
9744 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009745 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009746 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009747 }
9748 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009749 // flush anything that is already in the PrintWriter since the thread is going
9750 // to write to the file descriptor directly
9751 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009752 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009753 TransferPipe tp = new TransferPipe();
9754 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009755 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9756 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009757 tp.go(fd);
9758 } finally {
9759 tp.kill();
9760 }
9761 } catch (IOException e) {
9762 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009763 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009764 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009765 }
9766 }
9767 }
9768
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009769 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009770 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009771 boolean needSep = false;
9772
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009773 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009774 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009775 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009776 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009777 Iterator it = mRegisteredReceivers.values().iterator();
9778 while (it.hasNext()) {
9779 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009780 if (dumpPackage != null && (r.app == null ||
9781 !dumpPackage.equals(r.app.info.packageName))) {
9782 continue;
9783 }
9784 if (!printed) {
9785 pw.println(" Registered Receivers:");
9786 needSep = true;
9787 printed = true;
9788 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009789 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009790 r.dump(pw, " ");
9791 }
9792 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009793
9794 if (mReceiverResolver.dump(pw, needSep ?
9795 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9796 " ", dumpPackage, false)) {
9797 needSep = true;
9798 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009799 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009800
9801 for (BroadcastQueue q : mBroadcastQueues) {
9802 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009803 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009804
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009805 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009806
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009807 if (mStickyBroadcasts != null && dumpPackage == null) {
9808 if (needSep) {
9809 pw.println();
9810 }
9811 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009812 pw.println(" Sticky broadcasts:");
9813 StringBuilder sb = new StringBuilder(128);
9814 for (Map.Entry<String, ArrayList<Intent>> ent
9815 : mStickyBroadcasts.entrySet()) {
9816 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009817 if (dumpAll) {
9818 pw.println(":");
9819 ArrayList<Intent> intents = ent.getValue();
9820 final int N = intents.size();
9821 for (int i=0; i<N; i++) {
9822 sb.setLength(0);
9823 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009824 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009825 pw.println(sb.toString());
9826 Bundle bundle = intents.get(i).getExtras();
9827 if (bundle != null) {
9828 pw.print(" ");
9829 pw.println(bundle.toString());
9830 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009832 } else {
9833 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009834 }
9835 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009836 needSep = true;
9837 }
9838
9839 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009840 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009841 for (BroadcastQueue queue : mBroadcastQueues) {
9842 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9843 + queue.mBroadcastsScheduled);
9844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009845 pw.println(" mHandler:");
9846 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009847 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009848 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009849
9850 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851 }
9852
Marco Nelissen18cb2872011-11-15 11:19:53 -08009853 /**
9854 * Prints a list of ServiceRecords (dumpsys activity services)
9855 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009856 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009857 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009858 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009860 ItemMatcher matcher = new ItemMatcher();
9861 matcher.build(args, opti);
9862
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009863 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009864 try {
9865 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9866 for (UserInfo user : users) {
9867 if (mServiceMap.getAllServices(user.id).size() > 0) {
9868 boolean printed = false;
9869 long nowReal = SystemClock.elapsedRealtime();
9870 Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9871 user.id).iterator();
9872 needSep = false;
9873 while (it.hasNext()) {
9874 ServiceRecord r = it.next();
9875 if (!matcher.match(r, r.name)) {
9876 continue;
9877 }
9878 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9879 continue;
9880 }
9881 if (!printed) {
9882 pw.println(" Active services:");
9883 printed = true;
9884 }
9885 if (needSep) {
9886 pw.println();
9887 }
9888 pw.print(" * ");
9889 pw.println(r);
9890 if (dumpAll) {
9891 r.dump(pw, " ");
9892 needSep = true;
9893 } else {
9894 pw.print(" app=");
9895 pw.println(r.app);
9896 pw.print(" created=");
9897 TimeUtils.formatDuration(r.createTime, nowReal, pw);
9898 pw.print(" started=");
9899 pw.print(r.startRequested);
9900 pw.print(" connections=");
9901 pw.println(r.connections.size());
9902 if (r.connections.size() > 0) {
9903 pw.println(" Connections:");
9904 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9905 for (int i = 0; i < clist.size(); i++) {
9906 ConnectionRecord conn = clist.get(i);
9907 pw.print(" ");
9908 pw.print(conn.binding.intent.intent.getIntent()
9909 .toShortString(false, false, false));
9910 pw.print(" -> ");
9911 ProcessRecord proc = conn.binding.client;
9912 pw.println(proc != null ? proc.toShortString() : "null");
9913 }
9914 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009915 }
9916 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009917 if (dumpClient && r.app != null && r.app.thread != null) {
9918 pw.println(" Client:");
9919 pw.flush();
9920 try {
9921 TransferPipe tp = new TransferPipe();
9922 try {
9923 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9924 r, args);
9925 tp.setBufferPrefix(" ");
9926 // Short timeout, since blocking here can
9927 // deadlock with the application.
9928 tp.go(fd, 2000);
9929 } finally {
9930 tp.kill();
9931 }
9932 } catch (IOException e) {
9933 pw.println(" Failure while dumping the service: " + e);
9934 } catch (RemoteException e) {
9935 pw.println(" Got a RemoteException while dumping the service");
9936 }
9937 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009938 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009939 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009940 needSep = printed;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009941 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009942 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009943 } catch (RemoteException re) {
9944
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009945 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009946
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009947 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009948 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009949 for (int i=0; i<mPendingServices.size(); i++) {
9950 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009951 if (!matcher.match(r, r.name)) {
9952 continue;
9953 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009954 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9955 continue;
9956 }
9957 if (!printed) {
9958 if (needSep) pw.println(" ");
9959 needSep = true;
9960 pw.println(" Pending services:");
9961 printed = true;
9962 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009963 pw.print(" * Pending "); pw.println(r);
9964 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009966 needSep = true;
9967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009969 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009970 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009971 for (int i=0; i<mRestartingServices.size(); i++) {
9972 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009973 if (!matcher.match(r, r.name)) {
9974 continue;
9975 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009976 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9977 continue;
9978 }
9979 if (!printed) {
9980 if (needSep) pw.println(" ");
9981 needSep = true;
9982 pw.println(" Restarting services:");
9983 printed = true;
9984 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009985 pw.print(" * Restarting "); pw.println(r);
9986 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009987 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009988 needSep = true;
9989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009991 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009992 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009993 for (int i=0; i<mStoppingServices.size(); i++) {
9994 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009995 if (!matcher.match(r, r.name)) {
9996 continue;
9997 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009998 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9999 continue;
10000 }
10001 if (!printed) {
10002 if (needSep) pw.println(" ");
10003 needSep = true;
10004 pw.println(" Stopping services:");
10005 printed = true;
10006 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010007 pw.print(" * Stopping "); pw.println(r);
10008 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010010 needSep = true;
10011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010013 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010015 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010016 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010017 = mServiceConnections.values().iterator();
10018 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010019 ArrayList<ConnectionRecord> r = it.next();
10020 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010021 ConnectionRecord cr = r.get(i);
10022 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
10023 continue;
10024 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010025 if (dumpPackage != null && (cr.binding.client == null
10026 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
10027 continue;
10028 }
10029 if (!printed) {
10030 if (needSep) pw.println(" ");
10031 needSep = true;
10032 pw.println(" Connection bindings to services:");
10033 printed = true;
10034 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010035 pw.print(" * "); pw.println(cr);
10036 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010038 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010039 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010040 }
10041 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010042
10043 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010044 }
10045
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010046 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010047 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010048 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010050 ItemMatcher matcher = new ItemMatcher();
10051 matcher.build(args, opti);
10052
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010053 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -070010054
10055 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010056
10057 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010058 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010059 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010060 ContentProviderRecord r = mLaunchingProviders.get(i);
10061 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
10062 continue;
10063 }
10064 if (!printed) {
10065 if (needSep) pw.println(" ");
10066 needSep = true;
10067 pw.println(" Launching content providers:");
10068 printed = true;
10069 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010070 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010071 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010072 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010073 }
10074
10075 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010076 if (needSep) pw.println();
10077 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010078 pw.println("Granted Uri Permissions:");
10079 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
10080 int uid = mGrantedUriPermissions.keyAt(i);
10081 HashMap<Uri, UriPermission> perms
10082 = mGrantedUriPermissions.valueAt(i);
10083 pw.print(" * UID "); pw.print(uid);
10084 pw.println(" holds:");
10085 for (UriPermission perm : perms.values()) {
10086 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010087 if (dumpAll) {
10088 perm.dump(pw, " ");
10089 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010090 }
10091 }
10092 needSep = true;
10093 }
10094
10095 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010096 }
10097
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010098 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010099 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010100 boolean needSep = false;
10101
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010102 if (mIntentSenderRecords.size() > 0) {
10103 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010104 Iterator<WeakReference<PendingIntentRecord>> it
10105 = mIntentSenderRecords.values().iterator();
10106 while (it.hasNext()) {
10107 WeakReference<PendingIntentRecord> ref = it.next();
10108 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010109 if (dumpPackage != null && (rec == null
10110 || !dumpPackage.equals(rec.key.packageName))) {
10111 continue;
10112 }
10113 if (!printed) {
10114 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
10115 printed = true;
10116 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010117 needSep = true;
10118 if (rec != null) {
10119 pw.print(" * "); pw.println(rec);
10120 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010122 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010123 } else {
10124 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 }
10126 }
10127 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010128
10129 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010130 }
10131
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010132 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010133 String prefix, String label, boolean complete, boolean brief, boolean client,
10134 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010136 boolean needNL = false;
10137 final String innerPrefix = prefix + " ";
10138 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010139 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010140 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010141 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
10142 continue;
10143 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -070010144 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010145 if (needNL) {
10146 pw.println(" ");
10147 needNL = false;
10148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010149 if (lastTask != r.task) {
10150 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010151 pw.print(prefix);
10152 pw.print(full ? "* " : " ");
10153 pw.println(lastTask);
10154 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010155 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010156 } else if (complete) {
10157 // Complete + brief == give a summary. Isn't that obvious?!?
10158 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010159 pw.print(prefix); pw.print(" ");
10160 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010161 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010163 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010164 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
10165 pw.print(" #"); pw.print(i); pw.print(": ");
10166 pw.println(r);
10167 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010168 r.dump(pw, innerPrefix);
10169 } else if (complete) {
10170 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010171 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010172 if (r.app != null) {
10173 pw.print(innerPrefix); pw.println(r.app);
10174 }
10175 }
10176 if (client && r.app != null && r.app.thread != null) {
10177 // flush anything that is already in the PrintWriter since the thread is going
10178 // to write to the file descriptor directly
10179 pw.flush();
10180 try {
10181 TransferPipe tp = new TransferPipe();
10182 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -080010183 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10184 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010185 // Short timeout, since blocking here can
10186 // deadlock with the application.
10187 tp.go(fd, 2000);
10188 } finally {
10189 tp.kill();
10190 }
10191 } catch (IOException e) {
10192 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10193 } catch (RemoteException e) {
10194 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10195 }
10196 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010197 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010198 }
10199 }
10200
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010201 private static String buildOomTag(String prefix, String space, int val, int base) {
10202 if (val == base) {
10203 if (space == null) return prefix;
10204 return prefix + " ";
10205 }
10206 return prefix + "+" + Integer.toString(val-base);
10207 }
10208
10209 private static final int dumpProcessList(PrintWriter pw,
10210 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010211 String prefix, String normalLabel, String persistentLabel,
10212 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010214 final int N = list.size()-1;
10215 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010216 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010217 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10218 continue;
10219 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010220 pw.println(String.format("%s%s #%2d: %s",
10221 prefix, (r.persistent ? persistentLabel : normalLabel),
10222 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 if (r.persistent) {
10224 numPers++;
10225 }
10226 }
10227 return numPers;
10228 }
10229
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010230 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -070010231 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -070010232 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010233 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010234
Dianne Hackborn905577f2011-09-07 18:31:28 -070010235 ArrayList<Pair<ProcessRecord, Integer>> list
10236 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10237 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010238 ProcessRecord r = origList.get(i);
10239 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10240 continue;
10241 }
Dianne Hackborn905577f2011-09-07 18:31:28 -070010242 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10243 }
10244
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010245 if (list.size() <= 0) {
10246 return false;
10247 }
10248
Dianne Hackborn905577f2011-09-07 18:31:28 -070010249 Comparator<Pair<ProcessRecord, Integer>> comparator
10250 = new Comparator<Pair<ProcessRecord, Integer>>() {
10251 @Override
10252 public int compare(Pair<ProcessRecord, Integer> object1,
10253 Pair<ProcessRecord, Integer> object2) {
10254 if (object1.first.setAdj != object2.first.setAdj) {
10255 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10256 }
10257 if (object1.second.intValue() != object2.second.intValue()) {
10258 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10259 }
10260 return 0;
10261 }
10262 };
10263
10264 Collections.sort(list, comparator);
10265
Dianne Hackborn287952c2010-09-22 22:34:31 -070010266 final long curRealtime = SystemClock.elapsedRealtime();
10267 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10268 final long curUptime = SystemClock.uptimeMillis();
10269 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10270
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010271 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070010272 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010273 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010274 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070010275 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010276 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10277 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010278 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10279 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010280 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10281 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010282 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10283 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010284 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010285 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010286 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10287 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10288 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10289 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10290 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10291 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10292 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10293 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010294 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10295 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010296 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10297 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010298 } else {
10299 oomAdj = Integer.toString(r.setAdj);
10300 }
10301 String schedGroup;
10302 switch (r.setSchedGroup) {
10303 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10304 schedGroup = "B";
10305 break;
10306 case Process.THREAD_GROUP_DEFAULT:
10307 schedGroup = "F";
10308 break;
10309 default:
10310 schedGroup = Integer.toString(r.setSchedGroup);
10311 break;
10312 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010313 String foreground;
10314 if (r.foregroundActivities) {
10315 foreground = "A";
10316 } else if (r.foregroundServices) {
10317 foreground = "S";
10318 } else {
10319 foreground = " ";
10320 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010321 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -070010322 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010323 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10324 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -070010325 if (r.adjSource != null || r.adjTarget != null) {
10326 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010327 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070010328 if (r.adjTarget instanceof ComponentName) {
10329 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10330 } else if (r.adjTarget != null) {
10331 pw.print(r.adjTarget.toString());
10332 } else {
10333 pw.print("{null}");
10334 }
10335 pw.print("<=");
10336 if (r.adjSource instanceof ProcessRecord) {
10337 pw.print("Proc{");
10338 pw.print(((ProcessRecord)r.adjSource).toShortString());
10339 pw.println("}");
10340 } else if (r.adjSource != null) {
10341 pw.println(r.adjSource.toString());
10342 } else {
10343 pw.println("{null}");
10344 }
10345 }
10346 if (inclDetails) {
10347 pw.print(prefix);
10348 pw.print(" ");
10349 pw.print("oom: max="); pw.print(r.maxAdj);
10350 pw.print(" hidden="); pw.print(r.hiddenAdj);
10351 pw.print(" curRaw="); pw.print(r.curRawAdj);
10352 pw.print(" setRaw="); pw.print(r.setRawAdj);
10353 pw.print(" cur="); pw.print(r.curAdj);
10354 pw.print(" set="); pw.println(r.setAdj);
10355 pw.print(prefix);
10356 pw.print(" ");
10357 pw.print("keeping="); pw.print(r.keeping);
10358 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010359 pw.print(" empty="); pw.print(r.empty);
10360 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010361
10362 if (!r.keeping) {
10363 if (r.lastWakeTime != 0) {
10364 long wtime;
10365 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10366 synchronized (stats) {
10367 wtime = stats.getProcessWakeTime(r.info.uid,
10368 r.pid, curRealtime);
10369 }
10370 long timeUsed = wtime - r.lastWakeTime;
10371 pw.print(prefix);
10372 pw.print(" ");
10373 pw.print("keep awake over ");
10374 TimeUtils.formatDuration(realtimeSince, pw);
10375 pw.print(" used ");
10376 TimeUtils.formatDuration(timeUsed, pw);
10377 pw.print(" (");
10378 pw.print((timeUsed*100)/realtimeSince);
10379 pw.println("%)");
10380 }
10381 if (r.lastCpuTime != 0) {
10382 long timeUsed = r.curCpuTime - r.lastCpuTime;
10383 pw.print(prefix);
10384 pw.print(" ");
10385 pw.print("run cpu over ");
10386 TimeUtils.formatDuration(uptimeSince, pw);
10387 pw.print(" used ");
10388 TimeUtils.formatDuration(timeUsed, pw);
10389 pw.print(" (");
10390 pw.print((timeUsed*100)/uptimeSince);
10391 pw.println("%)");
10392 }
10393 }
10394 }
10395 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010396 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010397 }
10398
Dianne Hackbornb437e092011-08-05 17:50:29 -070010399 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010400 ArrayList<ProcessRecord> procs;
10401 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010402 if (args != null && args.length > start
10403 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010404 procs = new ArrayList<ProcessRecord>();
10405 int pid = -1;
10406 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010407 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010408 } catch (NumberFormatException e) {
10409
10410 }
10411 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10412 ProcessRecord proc = mLruProcesses.get(i);
10413 if (proc.pid == pid) {
10414 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010415 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010416 procs.add(proc);
10417 }
10418 }
10419 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010420 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010421 return null;
10422 }
10423 } else {
10424 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10425 }
10426 }
10427 return procs;
10428 }
10429
10430 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10431 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010432 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010433 if (procs == null) {
10434 return;
10435 }
10436
10437 long uptime = SystemClock.uptimeMillis();
10438 long realtime = SystemClock.elapsedRealtime();
10439 pw.println("Applications Graphics Acceleration Info:");
10440 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10441
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010442 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10443 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010444 if (r.thread != null) {
10445 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10446 pw.flush();
10447 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010448 TransferPipe tp = new TransferPipe();
10449 try {
10450 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10451 tp.go(fd);
10452 } finally {
10453 tp.kill();
10454 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010455 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010456 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010457 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -070010458 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010459 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010460 pw.flush();
10461 }
10462 }
10463 }
Chet Haase9c1e23b2011-03-24 10:51:31 -070010464 }
10465
Jeff Brown6754ba22011-12-14 20:20:01 -080010466 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10467 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10468 if (procs == null) {
10469 return;
10470 }
10471
10472 pw.println("Applications Database Info:");
10473
10474 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10475 ProcessRecord r = procs.get(i);
10476 if (r.thread != null) {
10477 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10478 pw.flush();
10479 try {
10480 TransferPipe tp = new TransferPipe();
10481 try {
10482 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10483 tp.go(fd);
10484 } finally {
10485 tp.kill();
10486 }
10487 } catch (IOException e) {
10488 pw.println("Failure while dumping the app: " + r);
10489 pw.flush();
10490 } catch (RemoteException e) {
10491 pw.println("Got a RemoteException while dumping the app " + r);
10492 pw.flush();
10493 }
10494 }
10495 }
10496 }
10497
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010498 final static class MemItem {
10499 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010500 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010501 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010502 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010503 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010504
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010505 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010506 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010507 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010508 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010509 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010510 }
10511 }
10512
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010513 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010514 boolean sort) {
10515 if (sort) {
10516 Collections.sort(items, new Comparator<MemItem>() {
10517 @Override
10518 public int compare(MemItem lhs, MemItem rhs) {
10519 if (lhs.pss < rhs.pss) {
10520 return 1;
10521 } else if (lhs.pss > rhs.pss) {
10522 return -1;
10523 }
10524 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010525 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010526 });
10527 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010528
10529 for (int i=0; i<items.size(); i++) {
10530 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010531 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010532 if (mi.subitems != null) {
10533 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10534 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010535 }
10536 }
10537
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010538 // These are in KB.
10539 static final long[] DUMP_MEM_BUCKETS = new long[] {
10540 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10541 120*1024, 160*1024, 200*1024,
10542 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10543 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10544 };
10545
Dianne Hackborn672342c2011-11-29 11:29:02 -080010546 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10547 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010548 int start = label.lastIndexOf('.');
10549 if (start >= 0) start++;
10550 else start = 0;
10551 int end = label.length();
10552 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10553 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10554 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10555 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010556 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010557 out.append(label, start, end);
10558 return;
10559 }
10560 }
10561 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010562 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010563 out.append(label, start, end);
10564 }
10565
10566 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10567 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10568 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10569 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10570 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10571 };
10572 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10573 "System", "Persistent", "Foreground",
10574 "Visible", "Perceptible", "Heavy Weight",
10575 "Backup", "A Services", "Home", "Previous",
10576 "B Services", "Background"
10577 };
10578
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010579 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010580 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010581 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010582 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010583 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010584
10585 int opti = 0;
10586 while (opti < args.length) {
10587 String opt = args[opti];
10588 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10589 break;
10590 }
10591 opti++;
10592 if ("-a".equals(opt)) {
10593 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010594 } else if ("--oom".equals(opt)) {
10595 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010596 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010597 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010598 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010599 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010600 pw.println("If [process] is specified it can be the name or ");
10601 pw.println("pid of a specific process to dump.");
10602 return;
10603 } else {
10604 pw.println("Unknown argument: " + opt + "; use -h for help");
10605 }
10606 }
10607
10608 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010609 if (procs == null) {
10610 return;
10611 }
10612
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010613 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010614 long uptime = SystemClock.uptimeMillis();
10615 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010616
10617 if (procs.size() == 1 || isCheckinRequest) {
10618 dumpAll = true;
10619 }
10620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010621 if (isCheckinRequest) {
10622 // short checkin version
10623 pw.println(uptime + "," + realtime);
10624 pw.flush();
10625 } else {
10626 pw.println("Applications Memory Usage (kB):");
10627 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10628 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010629
Dianne Hackbornb437e092011-08-05 17:50:29 -070010630 String[] innerArgs = new String[args.length-opti];
10631 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10632
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010633 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10634 long nativePss=0, dalvikPss=0, otherPss=0;
10635 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10636
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010637 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10638 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10639 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010640
10641 long totalPss = 0;
10642
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010643 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10644 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010645 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010646 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010647 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10648 pw.flush();
10649 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010650 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010651 if (dumpAll) {
10652 try {
10653 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10654 } catch (RemoteException e) {
10655 if (!isCheckinRequest) {
10656 pw.println("Got RemoteException!");
10657 pw.flush();
10658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010660 } else {
10661 mi = new Debug.MemoryInfo();
10662 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010663 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010664
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010665 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010666 long myTotalPss = mi.getTotalPss();
10667 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010668 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010669 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010670 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010671
10672 nativePss += mi.nativePss;
10673 dalvikPss += mi.dalvikPss;
10674 otherPss += mi.otherPss;
10675 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10676 long mem = mi.getOtherPss(j);
10677 miscPss[j] += mem;
10678 otherPss -= mem;
10679 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010680
10681 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010682 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10683 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010684 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010685 if (oomProcs[oomIndex] == null) {
10686 oomProcs[oomIndex] = new ArrayList<MemItem>();
10687 }
10688 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010689 break;
10690 }
10691 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010693 }
10694 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010695
10696 if (!isCheckinRequest && procs.size() > 1) {
10697 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10698
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010699 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10700 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10701 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010702 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010703 String label = Debug.MemoryInfo.getOtherLabel(j);
10704 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010705 }
10706
Dianne Hackbornb437e092011-08-05 17:50:29 -070010707 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10708 for (int j=0; j<oomPss.length; j++) {
10709 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010710 String label = DUMP_MEM_OOM_LABEL[j];
10711 MemItem item = new MemItem(label, label, oomPss[j],
10712 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010713 item.subitems = oomProcs[j];
10714 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010715 }
10716 }
10717
Dianne Hackborn672342c2011-11-29 11:29:02 -080010718 if (outTag != null || outStack != null) {
10719 if (outTag != null) {
10720 appendMemBucket(outTag, totalPss, "total", false);
10721 }
10722 if (outStack != null) {
10723 appendMemBucket(outStack, totalPss, "total", true);
10724 }
10725 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010726 for (int i=0; i<oomMems.size(); i++) {
10727 MemItem miCat = oomMems.get(i);
10728 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10729 continue;
10730 }
10731 if (miCat.id < ProcessList.SERVICE_ADJ
10732 || miCat.id == ProcessList.HOME_APP_ADJ
10733 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010734 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10735 outTag.append(" / ");
10736 }
10737 if (outStack != null) {
10738 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10739 if (firstLine) {
10740 outStack.append(":");
10741 firstLine = false;
10742 }
10743 outStack.append("\n\t at ");
10744 } else {
10745 outStack.append("$");
10746 }
10747 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010748 for (int j=0; j<miCat.subitems.size(); j++) {
10749 MemItem mi = miCat.subitems.get(j);
10750 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010751 if (outTag != null) {
10752 outTag.append(" ");
10753 }
10754 if (outStack != null) {
10755 outStack.append("$");
10756 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010757 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010758 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10759 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10760 }
10761 if (outStack != null) {
10762 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10763 }
10764 }
10765 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10766 outStack.append("(");
10767 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10768 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10769 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10770 outStack.append(":");
10771 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10772 }
10773 }
10774 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010775 }
10776 }
10777 }
10778 }
10779
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010780 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010781 pw.println();
10782 pw.println("Total PSS by process:");
10783 dumpMemItems(pw, " ", procMems, true);
10784 pw.println();
10785 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010786 pw.println("Total PSS by OOM adjustment:");
10787 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010788 if (!oomOnly) {
10789 PrintWriter out = categoryPw != null ? categoryPw : pw;
10790 out.println();
10791 out.println("Total PSS by category:");
10792 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010793 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010794 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010795 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010797 }
10798
10799 /**
10800 * Searches array of arguments for the specified string
10801 * @param args array of argument strings
10802 * @param value value to search for
10803 * @return true if the value is contained in the array
10804 */
10805 private static boolean scanArgs(String[] args, String value) {
10806 if (args != null) {
10807 for (String arg : args) {
10808 if (value.equals(arg)) {
10809 return true;
10810 }
10811 }
10812 }
10813 return false;
10814 }
10815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010816 private final void killServicesLocked(ProcessRecord app,
10817 boolean allowRestart) {
10818 // Report disconnected services.
10819 if (false) {
10820 // XXX we are letting the client link to the service for
10821 // death notifications.
10822 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010823 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010825 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010826 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010827 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010828 = r.connections.values().iterator();
10829 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010830 ArrayList<ConnectionRecord> cl = jt.next();
10831 for (int i=0; i<cl.size(); i++) {
10832 ConnectionRecord c = cl.get(i);
10833 if (c.binding.client != app) {
10834 try {
10835 //c.conn.connected(r.className, null);
10836 } catch (Exception e) {
10837 // todo: this should be asynchronous!
10838 Slog.w(TAG, "Exception thrown disconnected servce "
10839 + r.shortName
10840 + " from app " + app.processName, e);
10841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 }
10843 }
10844 }
10845 }
10846 }
10847 }
10848 }
10849
10850 // Clean up any connections this application has to other services.
10851 if (app.connections.size() > 0) {
10852 Iterator<ConnectionRecord> it = app.connections.iterator();
10853 while (it.hasNext()) {
10854 ConnectionRecord r = it.next();
10855 removeConnectionLocked(r, app, null);
10856 }
10857 }
10858 app.connections.clear();
10859
10860 if (app.services.size() != 0) {
10861 // Any services running in the application need to be placed
10862 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010863 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010864 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010865 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010866 synchronized (sr.stats.getBatteryStats()) {
10867 sr.stats.stopLaunchedLocked();
10868 }
10869 sr.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010870 sr.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010872 if (mStoppingServices.remove(sr)) {
10873 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10874 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010875
10876 boolean hasClients = sr.bindings.size() > 0;
10877 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010878 Iterator<IntentBindRecord> bindings
10879 = sr.bindings.values().iterator();
10880 while (bindings.hasNext()) {
10881 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010882 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010883 + ": shouldUnbind=" + b.hasBound);
10884 b.binder = null;
10885 b.requested = b.received = b.hasBound = false;
10886 }
10887 }
10888
Dianne Hackborn070783f2010-12-29 16:46:28 -080010889 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10890 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010891 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010892 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010893 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010894 sr.crashCount, sr.shortName, app.pid);
10895 bringDownServiceLocked(sr, true);
10896 } else if (!allowRestart) {
10897 bringDownServiceLocked(sr, true);
10898 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010899 boolean canceled = scheduleServiceRestartLocked(sr, true);
10900
10901 // Should the service remain running? Note that in the
10902 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010903 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010904 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10905 if (sr.pendingStarts.size() == 0) {
10906 sr.startRequested = false;
10907 if (!hasClients) {
10908 // Whoops, no reason to restart!
10909 bringDownServiceLocked(sr, true);
10910 }
10911 }
10912 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010913 }
10914 }
10915
10916 if (!allowRestart) {
10917 app.services.clear();
10918 }
10919 }
10920
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010921 // Make sure we have no more records on the stopping list.
10922 int i = mStoppingServices.size();
10923 while (i > 0) {
10924 i--;
10925 ServiceRecord sr = mStoppingServices.get(i);
10926 if (sr.app == app) {
10927 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010928 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010929 }
10930 }
10931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010932 app.executingServices.clear();
10933 }
10934
10935 private final void removeDyingProviderLocked(ProcessRecord proc,
10936 ContentProviderRecord cpr) {
10937 synchronized (cpr) {
10938 cpr.launchingApp = null;
10939 cpr.notifyAll();
10940 }
10941
Amith Yamasani742a6712011-05-04 14:49:28 -070010942 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010943 String names[] = cpr.info.authority.split(";");
10944 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -070010945 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010946 }
10947
10948 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10949 while (cit.hasNext()) {
10950 ProcessRecord capp = cit.next();
10951 if (!capp.persistent && capp.thread != null
10952 && capp.pid != 0
10953 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010954 Slog.i(TAG, "Kill " + capp.processName
10955 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010956 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010957 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010958 capp.processName, capp.setAdj, "dying provider "
10959 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010960 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010961 }
10962 }
10963
10964 mLaunchingProviders.remove(cpr);
10965 }
10966
10967 /**
10968 * Main code for cleaning up a process when it has gone away. This is
10969 * called both as a result of the process dying, or directly when stopping
10970 * a process when running in single process mode.
10971 */
10972 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010973 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010975 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 }
10977
Dianne Hackborn36124872009-10-08 16:22:03 -070010978 mProcessesToGc.remove(app);
10979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010980 // Dismiss any open dialogs.
10981 if (app.crashDialog != null) {
10982 app.crashDialog.dismiss();
10983 app.crashDialog = null;
10984 }
10985 if (app.anrDialog != null) {
10986 app.anrDialog.dismiss();
10987 app.anrDialog = null;
10988 }
10989 if (app.waitDialog != null) {
10990 app.waitDialog.dismiss();
10991 app.waitDialog = null;
10992 }
10993
10994 app.crashing = false;
10995 app.notResponding = false;
10996
10997 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010998 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010999 app.thread = null;
11000 app.forcingToForeground = null;
11001 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011002 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070011003 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011004 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011005
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011006 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011007
11008 boolean restart = false;
11009
11010 int NL = mLaunchingProviders.size();
11011
11012 // Remove published content providers.
11013 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011014 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011015 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011016 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011018 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011019
11020 // See if someone is waiting for this provider... in which
11021 // case we don't remove it, but just let it restart.
11022 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011023 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 for (; i<NL; i++) {
11025 if (mLaunchingProviders.get(i) == cpr) {
11026 restart = true;
11027 break;
11028 }
11029 }
11030 } else {
11031 i = NL;
11032 }
11033
11034 if (i >= NL) {
11035 removeDyingProviderLocked(app, cpr);
11036 NL = mLaunchingProviders.size();
11037 }
11038 }
11039 app.pubProviders.clear();
11040 }
11041
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011042 // Take care of any launching providers waiting for this process.
11043 if (checkAppInLaunchingProvidersLocked(app, false)) {
11044 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011045 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011047 // Unregister from connected content providers.
11048 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070011049 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 while (it.hasNext()) {
11051 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
11052 cpr.clients.remove(app);
11053 }
11054 app.conProviders.clear();
11055 }
11056
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011057 // At this point there may be remaining entries in mLaunchingProviders
11058 // where we were the only one waiting, so they are no longer of use.
11059 // Look for these and clean up if found.
11060 // XXX Commented out for now. Trying to figure out a way to reproduce
11061 // the actual situation to identify what is actually going on.
11062 if (false) {
11063 for (int i=0; i<NL; i++) {
11064 ContentProviderRecord cpr = (ContentProviderRecord)
11065 mLaunchingProviders.get(i);
11066 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
11067 synchronized (cpr) {
11068 cpr.launchingApp = null;
11069 cpr.notifyAll();
11070 }
11071 }
11072 }
11073 }
11074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011075 skipCurrentReceiverLocked(app);
11076
11077 // Unregister any receivers.
11078 if (app.receivers.size() > 0) {
11079 Iterator<ReceiverList> it = app.receivers.iterator();
11080 while (it.hasNext()) {
11081 removeReceiverLocked(it.next());
11082 }
11083 app.receivers.clear();
11084 }
11085
Christopher Tate181fafa2009-05-14 11:12:14 -070011086 // If the app is undergoing backup, tell the backup manager about it
11087 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011088 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070011089 try {
11090 IBackupManager bm = IBackupManager.Stub.asInterface(
11091 ServiceManager.getService(Context.BACKUP_SERVICE));
11092 bm.agentDisconnected(app.info.packageName);
11093 } catch (RemoteException e) {
11094 // can't happen; backup manager is local
11095 }
11096 }
11097
Jeff Sharkey287bd832011-05-28 19:36:26 -070011098 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011100 // If the caller is restarting this app, then leave it in its
11101 // current lists and let the caller take care of it.
11102 if (restarting) {
11103 return;
11104 }
11105
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011106 if (!app.persistent || app.isolated) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011107 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011109 mProcessNames.remove(app.processName, app.uid);
11110 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070011111 if (mHeavyWeightProcess == app) {
11112 mHeavyWeightProcess = null;
11113 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
11114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 } else if (!app.removed) {
11116 // This app is persistent, so we need to keep its record around.
11117 // If it is not already on the pending app list, add it there
11118 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 if (mPersistentStartingProcesses.indexOf(app) < 0) {
11120 mPersistentStartingProcesses.add(app);
11121 restart = true;
11122 }
11123 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011124 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
11125 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011126 mProcessesOnHold.remove(app);
11127
The Android Open Source Project4df24232009-03-05 14:34:35 -080011128 if (app == mHomeProcess) {
11129 mHomeProcess = null;
11130 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070011131 if (app == mPreviousProcess) {
11132 mPreviousProcess = null;
11133 }
11134
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011135 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 // We have components that still need to be running in the
11137 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011138 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011139 startProcessLocked(app, "restart", app.processName);
11140 } else if (app.pid > 0 && app.pid != MY_PID) {
11141 // Goodbye!
11142 synchronized (mPidsSelfLocked) {
11143 mPidsSelfLocked.remove(app.pid);
11144 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
11145 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070011146 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011147 }
11148 }
11149
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011150 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
11151 // Look through the content providers we are waiting to have launched,
11152 // and if any run in this process then either schedule a restart of
11153 // the process or kill the client waiting for it if this process has
11154 // gone bad.
11155 int NL = mLaunchingProviders.size();
11156 boolean restart = false;
11157 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011158 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011159 if (cpr.launchingApp == app) {
11160 if (!alwaysBad && !app.bad) {
11161 restart = true;
11162 } else {
11163 removeDyingProviderLocked(app, cpr);
11164 NL = mLaunchingProviders.size();
11165 }
11166 }
11167 }
11168 return restart;
11169 }
11170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011171 // =========================================================
11172 // SERVICES
11173 // =========================================================
11174
11175 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
11176 ActivityManager.RunningServiceInfo info =
11177 new ActivityManager.RunningServiceInfo();
11178 info.service = r.name;
11179 if (r.app != null) {
11180 info.pid = r.app.pid;
11181 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011182 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011183 info.process = r.processName;
11184 info.foreground = r.isForeground;
11185 info.activeSince = r.createTime;
11186 info.started = r.startRequested;
11187 info.clientCount = r.connections.size();
11188 info.crashCount = r.crashCount;
11189 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011190 if (r.isForeground) {
11191 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
11192 }
11193 if (r.startRequested) {
11194 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
11195 }
Dan Egnor42471dd2010-01-07 17:25:22 -080011196 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011197 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
11198 }
11199 if (r.app != null && r.app.persistent) {
11200 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
11201 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011202
11203 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
11204 for (int i=0; i<connl.size(); i++) {
11205 ConnectionRecord conn = connl.get(i);
11206 if (conn.clientLabel != 0) {
11207 info.clientPackage = conn.binding.client.info.packageName;
11208 info.clientLabel = conn.clientLabel;
11209 return info;
11210 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011211 }
11212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011213 return info;
11214 }
11215
11216 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11217 int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011218 enforceNotIsolatedCaller("getServices");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011219 synchronized (this) {
11220 ArrayList<ActivityManager.RunningServiceInfo> res
11221 = new ArrayList<ActivityManager.RunningServiceInfo>();
11222
Amith Yamasani742a6712011-05-04 14:49:28 -070011223 int userId = UserId.getUserId(Binder.getCallingUid());
11224 if (mServiceMap.getAllServices(userId).size() > 0) {
11225 Iterator<ServiceRecord> it
11226 = mServiceMap.getAllServices(userId).iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011227 while (it.hasNext() && res.size() < maxNum) {
11228 res.add(makeRunningServiceInfoLocked(it.next()));
11229 }
11230 }
11231
11232 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11233 ServiceRecord r = mRestartingServices.get(i);
11234 ActivityManager.RunningServiceInfo info =
11235 makeRunningServiceInfoLocked(r);
11236 info.restarting = r.nextRestartTime;
11237 res.add(info);
11238 }
11239
11240 return res;
11241 }
11242 }
11243
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011244 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011245 enforceNotIsolatedCaller("getRunningServiceControlPanel");
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011246 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011247 int userId = UserId.getUserId(Binder.getCallingUid());
11248 ServiceRecord r = mServiceMap.getServiceByName(name, userId);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011249 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011250 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11251 for (int i=0; i<conn.size(); i++) {
11252 if (conn.get(i).clientIntent != null) {
11253 return conn.get(i).clientIntent;
11254 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011255 }
11256 }
11257 }
11258 }
11259 return null;
11260 }
11261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011262 private final ServiceRecord findServiceLocked(ComponentName name,
11263 IBinder token) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011264 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011265 return r == token ? r : null;
11266 }
11267
11268 private final class ServiceLookupResult {
11269 final ServiceRecord record;
11270 final String permission;
11271
11272 ServiceLookupResult(ServiceRecord _record, String _permission) {
11273 record = _record;
11274 permission = _permission;
11275 }
11276 };
11277
11278 private ServiceLookupResult findServiceLocked(Intent service,
11279 String resolvedType) {
11280 ServiceRecord r = null;
11281 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011282 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011283 }
11284 if (r == null) {
11285 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani742a6712011-05-04 14:49:28 -070011286 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011287 }
11288
11289 if (r == null) {
11290 try {
11291 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011292 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011293 service, resolvedType, 0);
11294 ServiceInfo sInfo =
11295 rInfo != null ? rInfo.serviceInfo : null;
11296 if (sInfo == null) {
11297 return null;
11298 }
11299
11300 ComponentName name = new ComponentName(
11301 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011302 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011303 } catch (RemoteException ex) {
11304 // pm is in same process, this will never happen.
11305 }
11306 }
11307 if (r != null) {
11308 int callingPid = Binder.getCallingPid();
11309 int callingUid = Binder.getCallingUid();
11310 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011311 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011312 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011313 if (!r.exported) {
11314 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11315 + " from pid=" + callingPid
11316 + ", uid=" + callingUid
11317 + " that is not exported from uid " + r.appInfo.uid);
11318 return new ServiceLookupResult(null, "not exported from uid "
11319 + r.appInfo.uid);
11320 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011321 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011322 + " from pid=" + callingPid
11323 + ", uid=" + callingUid
11324 + " requires " + r.permission);
11325 return new ServiceLookupResult(null, r.permission);
11326 }
11327 return new ServiceLookupResult(r, null);
11328 }
11329 return null;
11330 }
11331
11332 private class ServiceRestarter implements Runnable {
11333 private ServiceRecord mService;
11334
11335 void setService(ServiceRecord service) {
11336 mService = service;
11337 }
11338
11339 public void run() {
11340 synchronized(ActivityManagerService.this) {
11341 performServiceRestartLocked(mService);
11342 }
11343 }
11344 }
11345
11346 private ServiceLookupResult retrieveServiceLocked(Intent service,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011347 String resolvedType, int callingPid, int callingUid, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011348 ServiceRecord r = null;
Amith Yamasani742a6712011-05-04 14:49:28 -070011349 if (DEBUG_SERVICE)
11350 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011351 + " callingUid=" + callingUid);
Amith Yamasani742a6712011-05-04 14:49:28 -070011352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011353 if (service.getComponent() != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011354 r = mServiceMap.getServiceByName(service.getComponent(), userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011355 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011356 if (r == null) {
11357 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011358 r = mServiceMap.getServiceByIntent(filter, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -070011359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 if (r == null) {
11361 try {
11362 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011363 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011364 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011365 ServiceInfo sInfo =
11366 rInfo != null ? rInfo.serviceInfo : null;
11367 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011368 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011369 ": not found");
11370 return null;
11371 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011372 if (userId > 0) {
11373 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -070011374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011375 ComponentName name = new ComponentName(
11376 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011377 r = mServiceMap.getServiceByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 if (r == null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011379 Intent.FilterComparison filter = new Intent.FilterComparison(
11380 service.cloneFilter());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011381 ServiceRestarter res = new ServiceRestarter();
11382 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11383 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11384 synchronized (stats) {
11385 ss = stats.getServiceStatsLocked(
11386 sInfo.applicationInfo.uid, sInfo.packageName,
11387 sInfo.name);
11388 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080011389 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011390 res.setService(r);
Amith Yamasani742a6712011-05-04 14:49:28 -070011391 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11392 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011393
11394 // Make sure this component isn't in the pending list.
11395 int N = mPendingServices.size();
11396 for (int i=0; i<N; i++) {
11397 ServiceRecord pr = mPendingServices.get(i);
11398 if (pr.name.equals(name)) {
11399 mPendingServices.remove(i);
11400 i--;
11401 N--;
11402 }
11403 }
11404 }
11405 } catch (RemoteException ex) {
11406 // pm is in same process, this will never happen.
11407 }
11408 }
11409 if (r != null) {
11410 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011411 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011413 if (!r.exported) {
11414 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11415 + " from pid=" + callingPid
11416 + ", uid=" + callingUid
11417 + " that is not exported from uid " + r.appInfo.uid);
11418 return new ServiceLookupResult(null, "not exported from uid "
11419 + r.appInfo.uid);
11420 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011421 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011422 + " from pid=" + callingPid
11423 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011424 + " requires " + r.permission);
11425 return new ServiceLookupResult(null, r.permission);
11426 }
11427 return new ServiceLookupResult(r, null);
11428 }
11429 return null;
11430 }
11431
Dianne Hackborn287952c2010-09-22 22:34:31 -070011432 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11433 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11434 + why + " of " + r + " in app " + r.app);
11435 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11436 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011437 long now = SystemClock.uptimeMillis();
11438 if (r.executeNesting == 0 && r.app != null) {
11439 if (r.app.executingServices.size() == 0) {
11440 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11441 msg.obj = r.app;
11442 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11443 }
11444 r.app.executingServices.add(r);
11445 }
11446 r.executeNesting++;
11447 r.executingStart = now;
11448 }
11449
11450 private final void sendServiceArgsLocked(ServiceRecord r,
11451 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011452 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 if (N == 0) {
11454 return;
11455 }
11456
Dianne Hackborn39792d22010-08-19 18:01:52 -070011457 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011458 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011459 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011460 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11461 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011462 if (si.intent == null && N > 1) {
11463 // If somehow we got a dummy null intent in the middle,
11464 // then skip it. DO NOT skip a null intent when it is
11465 // the only one in the list -- this is to support the
11466 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011467 continue;
11468 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070011469 si.deliveredTime = SystemClock.uptimeMillis();
11470 r.deliveredStarts.add(si);
11471 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011472 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011473 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070011474 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070011475 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070011476 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011477 if (!oomAdjusted) {
11478 oomAdjusted = true;
11479 updateOomAdjLocked(r.app);
11480 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011481 int flags = 0;
11482 if (si.deliveryCount > 0) {
11483 flags |= Service.START_FLAG_RETRY;
11484 }
11485 if (si.doneExecutingCount > 0) {
11486 flags |= Service.START_FLAG_REDELIVERY;
11487 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011488 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011489 } catch (RemoteException e) {
11490 // Remote process gone... we'll let the normal cleanup take
11491 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011492 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011493 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011494 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011495 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011496 break;
11497 }
11498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011499 }
11500
11501 private final boolean requestServiceBindingLocked(ServiceRecord r,
11502 IntentBindRecord i, boolean rebind) {
11503 if (r.app == null || r.app.thread == null) {
11504 // If service is not currently running, can't yet bind.
11505 return false;
11506 }
11507 if ((!i.requested || rebind) && i.apps.size() > 0) {
11508 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011509 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011510 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11511 if (!rebind) {
11512 i.requested = true;
11513 }
11514 i.hasBound = true;
11515 i.doRebind = false;
11516 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011517 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011518 return false;
11519 }
11520 }
11521 return true;
11522 }
11523
11524 private final void requestServiceBindingsLocked(ServiceRecord r) {
11525 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11526 while (bindings.hasNext()) {
11527 IntentBindRecord i = bindings.next();
11528 if (!requestServiceBindingLocked(r, i, false)) {
11529 break;
11530 }
11531 }
11532 }
11533
11534 private final void realStartServiceLocked(ServiceRecord r,
11535 ProcessRecord app) throws RemoteException {
11536 if (app.thread == null) {
11537 throw new RemoteException();
11538 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011539 if (DEBUG_MU)
11540 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011541 + ", ProcessRecord.uid = " + app.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070011543 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011544
11545 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011546 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011547 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011548
11549 boolean created = false;
11550 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011551 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070011552 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011553 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011554 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011555 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011556 synchronized (r.stats.getBatteryStats()) {
11557 r.stats.startLaunchedLocked();
11558 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011559 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011560 app.thread.scheduleCreateService(r, r.serviceInfo,
11561 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011562 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011563 created = true;
11564 } finally {
11565 if (!created) {
11566 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011567 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011568 }
11569 }
11570
11571 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011572
11573 // If the service is in the started state, and there are no
11574 // pending arguments, then fake up one so its onStartCommand() will
11575 // be called.
11576 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011577 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11578 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011579 }
11580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011581 sendServiceArgsLocked(r, true);
11582 }
11583
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011584 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11585 boolean allowCancel) {
11586 boolean canceled = false;
11587
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011588 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011589 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070011590 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011591
Dianne Hackborn070783f2010-12-29 16:46:28 -080011592 if ((r.serviceInfo.applicationInfo.flags
11593 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11594 minDuration /= 4;
11595 }
11596
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011597 // Any delivered but not yet finished starts should be put back
11598 // on the pending list.
11599 final int N = r.deliveredStarts.size();
11600 if (N > 0) {
11601 for (int i=N-1; i>=0; i--) {
11602 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070011603 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011604 if (si.intent == null) {
11605 // We'll generate this again if needed.
11606 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11607 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11608 r.pendingStarts.add(0, si);
11609 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11610 dur *= 2;
11611 if (minDuration < dur) minDuration = dur;
11612 if (resetTime < dur) resetTime = dur;
11613 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011614 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011615 + r.name);
11616 canceled = true;
11617 }
11618 }
11619 r.deliveredStarts.clear();
11620 }
11621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011622 r.totalRestartCount++;
11623 if (r.restartDelay == 0) {
11624 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011625 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011626 } else {
11627 // If it has been a "reasonably long time" since the service
11628 // was started, then reset our restart duration back to
11629 // the beginning, so we don't infinitely increase the duration
11630 // on a service that just occasionally gets killed (which is
11631 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011632 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011633 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011634 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080011636 if ((r.serviceInfo.applicationInfo.flags
11637 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11638 // Services in peristent processes will restart much more
11639 // quickly, since they are pretty important. (Think SystemUI).
11640 r.restartDelay += minDuration/2;
11641 } else {
11642 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11643 if (r.restartDelay < minDuration) {
11644 r.restartDelay = minDuration;
11645 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011647 }
11648 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011649
11650 r.nextRestartTime = now + r.restartDelay;
11651
11652 // Make sure that we don't end up restarting a bunch of services
11653 // all at the same time.
11654 boolean repeat;
11655 do {
11656 repeat = false;
11657 for (int i=mRestartingServices.size()-1; i>=0; i--) {
11658 ServiceRecord r2 = mRestartingServices.get(i);
11659 if (r2 != r && r.nextRestartTime
11660 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11661 && r.nextRestartTime
11662 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11663 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11664 r.restartDelay = r.nextRestartTime - now;
11665 repeat = true;
11666 break;
11667 }
11668 }
11669 } while (repeat);
11670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011671 if (!mRestartingServices.contains(r)) {
11672 mRestartingServices.add(r);
11673 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011674
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011675 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011678 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011680 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011681 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080011682 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011683 r.shortName, r.restartDelay);
11684
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011685 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011686 }
11687
11688 final void performServiceRestartLocked(ServiceRecord r) {
11689 if (!mRestartingServices.contains(r)) {
11690 return;
11691 }
11692 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11693 }
11694
11695 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11696 if (r.restartDelay == 0) {
11697 return false;
11698 }
11699 r.resetRestartCounter();
11700 mRestartingServices.remove(r);
11701 mHandler.removeCallbacks(r.restarter);
11702 return true;
11703 }
11704
11705 private final boolean bringUpServiceLocked(ServiceRecord r,
11706 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011707 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011708 //r.dump(" ");
11709
Dianne Hackborn36124872009-10-08 16:22:03 -070011710 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011711 sendServiceArgsLocked(r, false);
11712 return true;
11713 }
11714
11715 if (!whileRestarting && r.restartDelay > 0) {
11716 // If waiting for a restart, then do nothing.
11717 return true;
11718 }
11719
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011720 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011722 // We are now bringing the service up, so no longer in the
11723 // restarting state.
11724 mRestartingServices.remove(r);
11725
Dianne Hackborne7f97212011-02-24 14:40:20 -080011726 // Service is now being launched, its package can't be stopped.
11727 try {
11728 AppGlobals.getPackageManager().setPackageStoppedState(
11729 r.packageName, false);
11730 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011731 } catch (IllegalArgumentException e) {
11732 Slog.w(TAG, "Failed trying to unstop package "
11733 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011734 }
11735
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011736 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011737 final String appName = r.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011738 ProcessRecord app;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011739
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011740 if (!isolated) {
11741 app = getProcessRecordLocked(appName, r.appInfo.uid);
11742 if (DEBUG_MU)
11743 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11744 if (app != null && app.thread != null) {
11745 try {
11746 app.addPackage(r.appInfo.packageName);
11747 realStartServiceLocked(r, app);
11748 return true;
11749 } catch (RemoteException e) {
11750 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11751 }
11752
11753 // If a dead object exception was thrown -- fall through to
11754 // restart the application.
11755 }
11756 } else {
11757 // If this service runs in an isolated process, then each time
11758 // we call startProcessLocked() we will get a new isolated
11759 // process, starting another process if we are currently waiting
11760 // for a previous process to come up. To deal with this, we store
11761 // in the service any current isolated process it is running in or
11762 // waiting to have come up.
11763 app = r.isolatedProc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011764 }
11765
Dianne Hackborn36124872009-10-08 16:22:03 -070011766 // Not running -- get it started, and enqueue this service record
11767 // to be executed when the app comes up.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011768 if (app == null) {
11769 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11770 "service", r.name, false, isolated)) == null) {
11771 Slog.w(TAG, "Unable to launch app "
11772 + r.appInfo.packageName + "/"
11773 + r.appInfo.uid + " for service "
11774 + r.intent.getIntent() + ": process is bad");
11775 bringDownServiceLocked(r, true);
11776 return false;
11777 }
11778 if (isolated) {
11779 r.isolatedProc = app;
11780 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011781 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011784 mPendingServices.add(r);
11785 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011787 return true;
11788 }
11789
11790 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011791 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011792 //r.dump(" ");
11793
11794 // Does it still need to run?
11795 if (!force && r.startRequested) {
11796 return;
11797 }
11798 if (r.connections.size() > 0) {
11799 if (!force) {
11800 // XXX should probably keep a count of the number of auto-create
11801 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011802 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011803 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011804 ArrayList<ConnectionRecord> cr = it.next();
11805 for (int i=0; i<cr.size(); i++) {
11806 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11807 return;
11808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011809 }
11810 }
11811 }
11812
11813 // Report to all of the connections that the service is no longer
11814 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011815 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011816 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011817 ArrayList<ConnectionRecord> c = it.next();
11818 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011819 ConnectionRecord cr = c.get(i);
11820 // There is still a connection to the service that is
11821 // being brought down. Mark it as dead.
11822 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011823 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011824 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011825 } catch (Exception e) {
11826 Slog.w(TAG, "Failure disconnecting service " + r.name +
11827 " to connection " + c.get(i).conn.asBinder() +
11828 " (in " + c.get(i).binding.client.processName + ")", e);
11829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011830 }
11831 }
11832 }
11833
11834 // Tell the service that it has been unbound.
11835 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11836 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11837 while (it.hasNext()) {
11838 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011839 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011840 + ": hasBound=" + ibr.hasBound);
11841 if (r.app != null && r.app.thread != null && ibr.hasBound) {
11842 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011843 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011844 updateOomAdjLocked(r.app);
11845 ibr.hasBound = false;
11846 r.app.thread.scheduleUnbindService(r,
11847 ibr.intent.getIntent());
11848 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011849 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 + r.shortName, e);
11851 serviceDoneExecutingLocked(r, true);
11852 }
11853 }
11854 }
11855 }
11856
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011857 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011858 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011859 System.identityHashCode(r), r.shortName,
11860 (r.app != null) ? r.app.pid : -1);
11861
Amith Yamasani742a6712011-05-04 14:49:28 -070011862 mServiceMap.removeServiceByName(r.name, r.userId);
11863 mServiceMap.removeServiceByIntent(r.intent, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 r.totalRestartCount = 0;
11865 unscheduleServiceRestartLocked(r);
11866
11867 // Also make sure it is not on the pending list.
11868 int N = mPendingServices.size();
11869 for (int i=0; i<N; i++) {
11870 if (mPendingServices.get(i) == r) {
11871 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011872 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011873 i--;
11874 N--;
11875 }
11876 }
11877
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011878 r.cancelNotification();
11879 r.isForeground = false;
11880 r.foregroundId = 0;
11881 r.foregroundNoti = null;
11882
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011883 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011884 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011885 r.pendingStarts.clear();
11886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011887 if (r.app != null) {
11888 synchronized (r.stats.getBatteryStats()) {
11889 r.stats.stopLaunchedLocked();
11890 }
11891 r.app.services.remove(r);
11892 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011893 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011894 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011895 mStoppingServices.add(r);
11896 updateOomAdjLocked(r.app);
11897 r.app.thread.scheduleStopService(r);
11898 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011899 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011900 + r.shortName, e);
11901 serviceDoneExecutingLocked(r, true);
11902 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011903 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011905 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011906 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011907 }
11908 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011909 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011910 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080011912
11913 if (r.bindings.size() > 0) {
11914 r.bindings.clear();
11915 }
11916
11917 if (r.restarter instanceof ServiceRestarter) {
11918 ((ServiceRestarter)r.restarter).setService(null);
11919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011920 }
11921
11922 ComponentName startServiceLocked(IApplicationThread caller,
11923 Intent service, String resolvedType,
11924 int callingPid, int callingUid) {
11925 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011926 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011927 + " type=" + resolvedType + " args=" + service.getExtras());
11928
11929 if (caller != null) {
11930 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11931 if (callerApp == null) {
11932 throw new SecurityException(
11933 "Unable to find app for caller " + caller
11934 + " (pid=" + Binder.getCallingPid()
11935 + ") when starting service " + service);
11936 }
11937 }
11938
11939 ServiceLookupResult res =
11940 retrieveServiceLocked(service, resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011941 callingPid, callingUid, UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 if (res == null) {
11943 return null;
11944 }
11945 if (res.record == null) {
11946 return new ComponentName("!", res.permission != null
11947 ? res.permission : "private to package");
11948 }
11949 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070011950 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11951 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011952 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011953 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954 }
11955 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011956 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011957 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070011958 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011959 r.lastActivity = SystemClock.uptimeMillis();
11960 synchronized (r.stats.getBatteryStats()) {
11961 r.stats.startRunningLocked();
11962 }
11963 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11964 return new ComponentName("!", "Service process is bad");
11965 }
11966 return r.name;
11967 }
11968 }
11969
11970 public ComponentName startService(IApplicationThread caller, Intent service,
11971 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011972 enforceNotIsolatedCaller("startService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011973 // Refuse possible leaked file descriptors
11974 if (service != null && service.hasFileDescriptors() == true) {
11975 throw new IllegalArgumentException("File descriptors passed in Intent");
11976 }
11977
Amith Yamasani742a6712011-05-04 14:49:28 -070011978 if (DEBUG_SERVICE)
11979 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011980 synchronized(this) {
11981 final int callingPid = Binder.getCallingPid();
11982 final int callingUid = Binder.getCallingUid();
11983 final long origId = Binder.clearCallingIdentity();
11984 ComponentName res = startServiceLocked(caller, service,
11985 resolvedType, callingPid, callingUid);
11986 Binder.restoreCallingIdentity(origId);
11987 return res;
11988 }
11989 }
11990
11991 ComponentName startServiceInPackage(int uid,
11992 Intent service, String resolvedType) {
11993 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011994 if (DEBUG_SERVICE)
11995 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011996 final long origId = Binder.clearCallingIdentity();
11997 ComponentName res = startServiceLocked(null, service,
11998 resolvedType, -1, uid);
11999 Binder.restoreCallingIdentity(origId);
12000 return res;
12001 }
12002 }
12003
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012004 private void stopServiceLocked(ServiceRecord service) {
12005 synchronized (service.stats.getBatteryStats()) {
12006 service.stats.stopRunningLocked();
12007 }
12008 service.startRequested = false;
12009 service.callStart = false;
12010 bringDownServiceLocked(service, false);
12011 }
12012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 public int stopService(IApplicationThread caller, Intent service,
12014 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012015 enforceNotIsolatedCaller("stopService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012016 // Refuse possible leaked file descriptors
12017 if (service != null && service.hasFileDescriptors() == true) {
12018 throw new IllegalArgumentException("File descriptors passed in Intent");
12019 }
12020
12021 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012022 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 + " type=" + resolvedType);
12024
12025 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12026 if (caller != null && callerApp == null) {
12027 throw new SecurityException(
12028 "Unable to find app for caller " + caller
12029 + " (pid=" + Binder.getCallingPid()
12030 + ") when stopping service " + service);
12031 }
12032
12033 // If this service is active, make sure it is stopped.
12034 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12035 if (r != null) {
12036 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012037 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012038 try {
12039 stopServiceLocked(r.record);
12040 } finally {
12041 Binder.restoreCallingIdentity(origId);
12042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012043 return 1;
12044 }
12045 return -1;
12046 }
12047 }
12048
12049 return 0;
12050 }
12051
12052 public IBinder peekService(Intent service, String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012053 enforceNotIsolatedCaller("peekService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012054 // Refuse possible leaked file descriptors
12055 if (service != null && service.hasFileDescriptors() == true) {
12056 throw new IllegalArgumentException("File descriptors passed in Intent");
12057 }
12058
12059 IBinder ret = null;
12060
12061 synchronized(this) {
12062 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12063
12064 if (r != null) {
12065 // r.record is null if findServiceLocked() failed the caller permission check
12066 if (r.record == null) {
12067 throw new SecurityException(
12068 "Permission Denial: Accessing service " + r.record.name
12069 + " from pid=" + Binder.getCallingPid()
12070 + ", uid=" + Binder.getCallingUid()
12071 + " requires " + r.permission);
12072 }
12073 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
12074 if (ib != null) {
12075 ret = ib.binder;
12076 }
12077 }
12078 }
12079
12080 return ret;
12081 }
12082
12083 public boolean stopServiceToken(ComponentName className, IBinder token,
12084 int startId) {
12085 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012086 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087 + " " + token + " startId=" + startId);
12088 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012089 if (r != null) {
12090 if (startId >= 0) {
12091 // Asked to only stop if done with all work. Note that
12092 // to avoid leaks, we will take this as dropping all
12093 // start items up to and including this one.
12094 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12095 if (si != null) {
12096 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070012097 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
12098 cur.removeUriPermissionsLocked();
12099 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012100 break;
12101 }
12102 }
12103 }
12104
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012105 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012106 return false;
12107 }
12108
12109 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012110 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012111 + " is last, but have " + r.deliveredStarts.size()
12112 + " remaining args");
12113 }
12114 }
12115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 synchronized (r.stats.getBatteryStats()) {
12117 r.stats.stopRunningLocked();
12118 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012119 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012120 }
12121 final long origId = Binder.clearCallingIdentity();
12122 bringDownServiceLocked(r, false);
12123 Binder.restoreCallingIdentity(origId);
12124 return true;
12125 }
12126 }
12127 return false;
12128 }
12129
12130 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012131 int id, Notification notification, boolean removeNotification) {
12132 final long origId = Binder.clearCallingIdentity();
12133 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012134 synchronized(this) {
12135 ServiceRecord r = findServiceLocked(className, token);
12136 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012137 if (id != 0) {
12138 if (notification == null) {
12139 throw new IllegalArgumentException("null notification");
12140 }
12141 if (r.foregroundId != id) {
12142 r.cancelNotification();
12143 r.foregroundId = id;
12144 }
12145 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
12146 r.foregroundNoti = notification;
12147 r.isForeground = true;
12148 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 if (r.app != null) {
12150 updateServiceForegroundLocked(r.app, true);
12151 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012152 } else {
12153 if (r.isForeground) {
12154 r.isForeground = false;
12155 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070012156 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012157 updateServiceForegroundLocked(r.app, true);
12158 }
12159 }
12160 if (removeNotification) {
12161 r.cancelNotification();
12162 r.foregroundId = 0;
12163 r.foregroundNoti = null;
12164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165 }
12166 }
12167 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012168 } finally {
12169 Binder.restoreCallingIdentity(origId);
12170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012171 }
12172
12173 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
12174 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070012175 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012176 if (sr.isForeground) {
12177 anyForeground = true;
12178 break;
12179 }
12180 }
12181 if (anyForeground != proc.foregroundServices) {
12182 proc.foregroundServices = anyForeground;
12183 if (oomAdj) {
12184 updateOomAdjLocked();
12185 }
12186 }
12187 }
12188
12189 public int bindService(IApplicationThread caller, IBinder token,
12190 Intent service, String resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080012191 IServiceConnection connection, int flags, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012192 enforceNotIsolatedCaller("bindService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012193 // Refuse possible leaked file descriptors
12194 if (service != null && service.hasFileDescriptors() == true) {
12195 throw new IllegalArgumentException("File descriptors passed in Intent");
12196 }
12197
Amith Yamasani37ce3a82012-02-06 12:04:42 -080012198 checkValidCaller(Binder.getCallingUid(), userId);
12199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012200 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012201 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 + " type=" + resolvedType + " conn=" + connection.asBinder()
12203 + " flags=0x" + Integer.toHexString(flags));
Amith Yamasani742a6712011-05-04 14:49:28 -070012204 if (DEBUG_MU)
12205 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12206 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012207 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12208 if (callerApp == null) {
12209 throw new SecurityException(
12210 "Unable to find app for caller " + caller
12211 + " (pid=" + Binder.getCallingPid()
12212 + ") when binding service " + service);
12213 }
12214
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012215 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012216 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012217 activity = mMainStack.isInStackLocked(token);
12218 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012219 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 return 0;
12221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012222 }
12223
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012224 int clientLabel = 0;
12225 PendingIntent clientIntent = null;
12226
12227 if (callerApp.info.uid == Process.SYSTEM_UID) {
12228 // Hacky kind of thing -- allow system stuff to tell us
12229 // what they are, so we can report this elsewhere for
12230 // others to know why certain services are running.
12231 try {
12232 clientIntent = (PendingIntent)service.getParcelableExtra(
12233 Intent.EXTRA_CLIENT_INTENT);
12234 } catch (RuntimeException e) {
12235 }
12236 if (clientIntent != null) {
12237 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12238 if (clientLabel != 0) {
12239 // There are no useful extras in the intent, trash them.
12240 // System code calling with this stuff just needs to know
12241 // this will happen.
12242 service = service.cloneFilter();
12243 }
12244 }
12245 }
12246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012247 ServiceLookupResult res =
12248 retrieveServiceLocked(service, resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080012249 Binder.getCallingPid(), Binder.getCallingUid(), userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012250 if (res == null) {
12251 return 0;
12252 }
12253 if (res.record == null) {
12254 return -1;
12255 }
12256 ServiceRecord s = res.record;
12257
12258 final long origId = Binder.clearCallingIdentity();
12259
12260 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012261 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012262 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012263 }
12264
12265 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12266 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012267 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268
12269 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012270 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12271 if (clist == null) {
12272 clist = new ArrayList<ConnectionRecord>();
12273 s.connections.put(binder, clist);
12274 }
12275 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012276 b.connections.add(c);
12277 if (activity != null) {
12278 if (activity.connections == null) {
12279 activity.connections = new HashSet<ConnectionRecord>();
12280 }
12281 activity.connections.add(c);
12282 }
12283 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012284 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12285 b.client.hasAboveClient = true;
12286 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012287 clist = mServiceConnections.get(binder);
12288 if (clist == null) {
12289 clist = new ArrayList<ConnectionRecord>();
12290 mServiceConnections.put(binder, clist);
12291 }
12292 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012293
12294 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12295 s.lastActivity = SystemClock.uptimeMillis();
12296 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12297 return 0;
12298 }
12299 }
12300
12301 if (s.app != null) {
12302 // This could have made the service more important.
12303 updateOomAdjLocked(s.app);
12304 }
12305
Joe Onorato8a9b2202010-02-26 18:56:32 -080012306 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012307 + ": received=" + b.intent.received
12308 + " apps=" + b.intent.apps.size()
12309 + " doRebind=" + b.intent.doRebind);
12310
12311 if (s.app != null && b.intent.received) {
12312 // Service is already running, so we can immediately
12313 // publish the connection.
12314 try {
12315 c.conn.connected(s.name, b.intent.binder);
12316 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012317 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012318 + " to connection " + c.conn.asBinder()
12319 + " (in " + c.binding.client.processName + ")", e);
12320 }
12321
12322 // If this is the first app connected back to this binding,
12323 // and the service had previously asked to be told when
12324 // rebound, then do so.
12325 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12326 requestServiceBindingLocked(s, b.intent, true);
12327 }
12328 } else if (!b.intent.requested) {
12329 requestServiceBindingLocked(s, b.intent, false);
12330 }
12331
12332 Binder.restoreCallingIdentity(origId);
12333 }
12334
12335 return 1;
12336 }
12337
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012338 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012339 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012340 IBinder binder = c.conn.asBinder();
12341 AppBindRecord b = c.binding;
12342 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012343 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12344 if (clist != null) {
12345 clist.remove(c);
12346 if (clist.size() == 0) {
12347 s.connections.remove(binder);
12348 }
12349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012350 b.connections.remove(c);
12351 if (c.activity != null && c.activity != skipAct) {
12352 if (c.activity.connections != null) {
12353 c.activity.connections.remove(c);
12354 }
12355 }
12356 if (b.client != skipApp) {
12357 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012358 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12359 b.client.updateHasAboveClientLocked();
12360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012361 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012362 clist = mServiceConnections.get(binder);
12363 if (clist != null) {
12364 clist.remove(c);
12365 if (clist.size() == 0) {
12366 mServiceConnections.remove(binder);
12367 }
12368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012369
12370 if (b.connections.size() == 0) {
12371 b.intent.apps.remove(b.client);
12372 }
12373
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012374 if (!c.serviceDead) {
12375 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12376 + ": shouldUnbind=" + b.intent.hasBound);
12377 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12378 && b.intent.hasBound) {
12379 try {
12380 bumpServiceExecutingLocked(s, "unbind");
12381 updateOomAdjLocked(s.app);
12382 b.intent.hasBound = false;
12383 // Assume the client doesn't want to know about a rebind;
12384 // we will deal with that later if it asks for one.
12385 b.intent.doRebind = false;
12386 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12387 } catch (Exception e) {
12388 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12389 serviceDoneExecutingLocked(s, true);
12390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012391 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012392
12393 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12394 bringDownServiceLocked(s, false);
12395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012396 }
12397 }
12398
12399 public boolean unbindService(IServiceConnection connection) {
12400 synchronized (this) {
12401 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012402 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012403 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12404 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012405 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012406 + connection.asBinder());
12407 return false;
12408 }
12409
12410 final long origId = Binder.clearCallingIdentity();
12411
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012412 while (clist.size() > 0) {
12413 ConnectionRecord r = clist.get(0);
12414 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012415
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012416 if (r.binding.service.app != null) {
12417 // This could have made the service less important.
12418 updateOomAdjLocked(r.binding.service.app);
12419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012420 }
12421
12422 Binder.restoreCallingIdentity(origId);
12423 }
12424
12425 return true;
12426 }
12427
12428 public void publishService(IBinder token, Intent intent, IBinder service) {
12429 // Refuse possible leaked file descriptors
12430 if (intent != null && intent.hasFileDescriptors() == true) {
12431 throw new IllegalArgumentException("File descriptors passed in Intent");
12432 }
12433
12434 synchronized(this) {
12435 if (!(token instanceof ServiceRecord)) {
12436 throw new IllegalArgumentException("Invalid service token");
12437 }
12438 ServiceRecord r = (ServiceRecord)token;
12439
12440 final long origId = Binder.clearCallingIdentity();
12441
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012442 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 + " " + intent + ": " + service);
12444 if (r != null) {
12445 Intent.FilterComparison filter
12446 = new Intent.FilterComparison(intent);
12447 IntentBindRecord b = r.bindings.get(filter);
12448 if (b != null && !b.received) {
12449 b.binder = service;
12450 b.requested = true;
12451 b.received = true;
12452 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012453 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 = r.connections.values().iterator();
12455 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012456 ArrayList<ConnectionRecord> clist = it.next();
12457 for (int i=0; i<clist.size(); i++) {
12458 ConnectionRecord c = clist.get(i);
12459 if (!filter.equals(c.binding.intent.intent)) {
12460 if (DEBUG_SERVICE) Slog.v(
12461 TAG, "Not publishing to: " + c);
12462 if (DEBUG_SERVICE) Slog.v(
12463 TAG, "Bound intent: " + c.binding.intent.intent);
12464 if (DEBUG_SERVICE) Slog.v(
12465 TAG, "Published intent: " + intent);
12466 continue;
12467 }
12468 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12469 try {
12470 c.conn.connected(r.name, service);
12471 } catch (Exception e) {
12472 Slog.w(TAG, "Failure sending service " + r.name +
12473 " to connection " + c.conn.asBinder() +
12474 " (in " + c.binding.client.processName + ")", e);
12475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012476 }
12477 }
12478 }
12479 }
12480
12481 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12482
12483 Binder.restoreCallingIdentity(origId);
12484 }
12485 }
12486 }
12487
12488 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12489 // Refuse possible leaked file descriptors
12490 if (intent != null && intent.hasFileDescriptors() == true) {
12491 throw new IllegalArgumentException("File descriptors passed in Intent");
12492 }
12493
12494 synchronized(this) {
12495 if (!(token instanceof ServiceRecord)) {
12496 throw new IllegalArgumentException("Invalid service token");
12497 }
12498 ServiceRecord r = (ServiceRecord)token;
12499
12500 final long origId = Binder.clearCallingIdentity();
12501
12502 if (r != null) {
12503 Intent.FilterComparison filter
12504 = new Intent.FilterComparison(intent);
12505 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012506 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 + " at " + b + ": apps="
12508 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020012509
12510 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012511 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020012512 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012513 // Applications have already bound since the last
12514 // unbind, so just rebind right here.
12515 requestServiceBindingLocked(r, b, true);
12516 } else {
12517 // Note to tell the service the next time there is
12518 // a new client.
12519 b.doRebind = true;
12520 }
12521 }
12522
Per Edelberg78f9fff2010-08-30 20:01:35 +020012523 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012524
12525 Binder.restoreCallingIdentity(origId);
12526 }
12527 }
12528 }
12529
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012530 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012531 synchronized(this) {
12532 if (!(token instanceof ServiceRecord)) {
12533 throw new IllegalArgumentException("Invalid service token");
12534 }
12535 ServiceRecord r = (ServiceRecord)token;
12536 boolean inStopping = mStoppingServices.contains(token);
12537 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012538 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012539 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012540 + " with incorrect token: given " + token
12541 + ", expected " + r);
12542 return;
12543 }
12544
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012545 if (type == 1) {
12546 // This is a call from a service start... take care of
12547 // book-keeping.
12548 r.callStart = true;
12549 switch (res) {
12550 case Service.START_STICKY_COMPATIBILITY:
12551 case Service.START_STICKY: {
12552 // We are done with the associated start arguments.
12553 r.findDeliveredStart(startId, true);
12554 // Don't stop if killed.
12555 r.stopIfKilled = false;
12556 break;
12557 }
12558 case Service.START_NOT_STICKY: {
12559 // We are done with the associated start arguments.
12560 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012561 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012562 // There is no more work, and this service
12563 // doesn't want to hang around if killed.
12564 r.stopIfKilled = true;
12565 }
12566 break;
12567 }
12568 case Service.START_REDELIVER_INTENT: {
12569 // We'll keep this item until they explicitly
12570 // call stop for it, but keep track of the fact
12571 // that it was delivered.
12572 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12573 if (si != null) {
12574 si.deliveryCount = 0;
12575 si.doneExecutingCount++;
12576 // Don't stop if killed.
12577 r.stopIfKilled = true;
12578 }
12579 break;
12580 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012581 case Service.START_TASK_REMOVED_COMPLETE: {
12582 // Special processing for onTaskRemoved(). Don't
12583 // impact normal onStartCommand() processing.
12584 r.findDeliveredStart(startId, true);
12585 break;
12586 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012587 default:
12588 throw new IllegalArgumentException(
12589 "Unknown service start result: " + res);
12590 }
12591 if (res == Service.START_STICKY_COMPATIBILITY) {
12592 r.callStart = false;
12593 }
12594 }
Amith Yamasani742a6712011-05-04 14:49:28 -070012595 if (DEBUG_MU)
12596 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12597 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012598 final long origId = Binder.clearCallingIdentity();
12599 serviceDoneExecutingLocked(r, inStopping);
12600 Binder.restoreCallingIdentity(origId);
12601 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012602 Slog.w(TAG, "Done executing unknown service from pid "
12603 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012604 }
12605 }
12606 }
12607
12608 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012609 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12610 + ": nesting=" + r.executeNesting
12611 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012612 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012613 r.executeNesting--;
12614 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012615 if (DEBUG_SERVICE) Slog.v(TAG,
12616 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012617 r.app.executingServices.remove(r);
12618 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012619 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12620 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012621 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12622 }
12623 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012624 if (DEBUG_SERVICE) Slog.v(TAG,
12625 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012626 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020012627 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012628 }
12629 updateOomAdjLocked(r.app);
12630 }
12631 }
12632
12633 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012634 String anrMessage = null;
12635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012636 synchronized(this) {
12637 if (proc.executingServices.size() == 0 || proc.thread == null) {
12638 return;
12639 }
12640 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12641 Iterator<ServiceRecord> it = proc.executingServices.iterator();
12642 ServiceRecord timeout = null;
12643 long nextTime = 0;
12644 while (it.hasNext()) {
12645 ServiceRecord sr = it.next();
12646 if (sr.executingStart < maxTime) {
12647 timeout = sr;
12648 break;
12649 }
12650 if (sr.executingStart > nextTime) {
12651 nextTime = sr.executingStart;
12652 }
12653 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012654 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012655 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012656 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012657 } else {
12658 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12659 msg.obj = proc;
12660 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12661 }
12662 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012663
12664 if (anrMessage != null) {
12665 appNotResponding(proc, null, null, anrMessage);
12666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012667 }
12668
12669 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070012670 // BACKUP AND RESTORE
12671 // =========================================================
12672
12673 // Cause the target app to be launched if necessary and its backup agent
12674 // instantiated. The backup agent will invoke backupAgentCreated() on the
12675 // activity manager to announce its creation.
12676 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012677 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012678 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12679
12680 synchronized(this) {
12681 // !!! TODO: currently no check here that we're already bound
12682 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12683 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12684 synchronized (stats) {
12685 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12686 }
12687
Dianne Hackborne7f97212011-02-24 14:40:20 -080012688 // Backup agent is now in use, its package can't be stopped.
12689 try {
12690 AppGlobals.getPackageManager().setPackageStoppedState(
12691 app.packageName, false);
12692 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012693 } catch (IllegalArgumentException e) {
12694 Slog.w(TAG, "Failed trying to unstop package "
12695 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012696 }
12697
Christopher Tate181fafa2009-05-14 11:12:14 -070012698 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070012699 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12700 ? new ComponentName(app.packageName, app.backupAgentName)
12701 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070012702 // startProcessLocked() returns existing proc's record if it's already running
12703 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080012704 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070012705 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012706 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070012707 return false;
12708 }
12709
12710 r.app = proc;
12711 mBackupTarget = r;
12712 mBackupAppName = app.packageName;
12713
Christopher Tate6fa95972009-06-05 18:43:55 -070012714 // Try not to kill the process during backup
12715 updateOomAdjLocked(proc);
12716
Christopher Tate181fafa2009-05-14 11:12:14 -070012717 // If the process is already attached, schedule the creation of the backup agent now.
12718 // If it is not yet live, this will be done when it attaches to the framework.
12719 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012720 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070012721 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012722 proc.thread.scheduleCreateBackupAgent(app,
12723 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012724 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070012725 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070012726 }
12727 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012728 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070012729 }
12730 // Invariants: at this point, the target app process exists and the application
12731 // is either already running or in the process of coming up. mBackupTarget and
12732 // mBackupAppName describe the app, so that when it binds back to the AM we
12733 // know that it's scheduled for a backup-agent operation.
12734 }
12735
12736 return true;
12737 }
12738
12739 // A backup agent has just come up
12740 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012741 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070012742 + " = " + agent);
12743
12744 synchronized(this) {
12745 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012746 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070012747 return;
12748 }
Dianne Hackborn06740692010-09-22 22:46:21 -070012749 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012750
Dianne Hackborn06740692010-09-22 22:46:21 -070012751 long oldIdent = Binder.clearCallingIdentity();
12752 try {
12753 IBackupManager bm = IBackupManager.Stub.asInterface(
12754 ServiceManager.getService(Context.BACKUP_SERVICE));
12755 bm.agentConnected(agentPackageName, agent);
12756 } catch (RemoteException e) {
12757 // can't happen; the backup manager service is local
12758 } catch (Exception e) {
12759 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12760 e.printStackTrace();
12761 } finally {
12762 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070012763 }
12764 }
12765
12766 // done with this agent
12767 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012768 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070012769 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012770 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070012771 return;
12772 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012773
12774 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070012775 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012776 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070012777 return;
12778 }
12779
Christopher Tate181fafa2009-05-14 11:12:14 -070012780 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012781 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070012782 return;
12783 }
12784
Christopher Tate6fa95972009-06-05 18:43:55 -070012785 ProcessRecord proc = mBackupTarget.app;
12786 mBackupTarget = null;
12787 mBackupAppName = null;
12788
12789 // Not backing this app up any more; reset its OOM adjustment
12790 updateOomAdjLocked(proc);
12791
Christopher Tatec7b31e32009-06-10 15:49:30 -070012792 // If the app crashed during backup, 'thread' will be null here
12793 if (proc.thread != null) {
12794 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012795 proc.thread.scheduleDestroyBackupAgent(appInfo,
12796 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070012797 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012798 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070012799 e.printStackTrace();
12800 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012801 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012802 }
12803 }
12804 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012805 // BROADCASTS
12806 // =========================================================
12807
Josh Bartel7f208742010-02-25 11:01:44 -060012808 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 List cur) {
12810 final ContentResolver resolver = mContext.getContentResolver();
12811 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12812 if (list == null) {
12813 return cur;
12814 }
12815 int N = list.size();
12816 for (int i=0; i<N; i++) {
12817 Intent intent = list.get(i);
12818 if (filter.match(resolver, intent, true, TAG) >= 0) {
12819 if (cur == null) {
12820 cur = new ArrayList<Intent>();
12821 }
12822 cur.add(intent);
12823 }
12824 }
12825 return cur;
12826 }
12827
Christopher Tatef46723b2012-01-26 14:19:24 -080012828 boolean isPendingBroadcastProcessLocked(int pid) {
12829 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12830 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832
Christopher Tatef46723b2012-01-26 14:19:24 -080012833 void skipPendingBroadcastLocked(int pid) {
12834 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12835 for (BroadcastQueue queue : mBroadcastQueues) {
12836 queue.skipPendingBroadcastLocked(pid);
12837 }
12838 }
12839
12840 // The app just attached; send any pending broadcasts that it should receive
12841 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12842 boolean didSomething = false;
12843 for (BroadcastQueue queue : mBroadcastQueues) {
12844 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845 }
Christopher Tatef46723b2012-01-26 14:19:24 -080012846 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012847 }
12848
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012849 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012850 IIntentReceiver receiver, IntentFilter filter, String permission) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012851 enforceNotIsolatedCaller("registerReceiver");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012852 synchronized(this) {
12853 ProcessRecord callerApp = null;
12854 if (caller != null) {
12855 callerApp = getRecordForAppLocked(caller);
12856 if (callerApp == null) {
12857 throw new SecurityException(
12858 "Unable to find app for caller " + caller
12859 + " (pid=" + Binder.getCallingPid()
12860 + ") when registering receiver " + receiver);
12861 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012862 if (callerApp.info.uid != Process.SYSTEM_UID &&
12863 !callerApp.pkgList.contains(callerPackage)) {
12864 throw new SecurityException("Given caller package " + callerPackage
12865 + " is not running in process " + callerApp);
12866 }
12867 } else {
12868 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012869 }
12870
12871 List allSticky = null;
12872
12873 // Look for any matching sticky broadcasts...
12874 Iterator actions = filter.actionsIterator();
12875 if (actions != null) {
12876 while (actions.hasNext()) {
12877 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012878 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012879 }
12880 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012881 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012882 }
12883
12884 // The first sticky in the list is returned directly back to
12885 // the client.
12886 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12887
Joe Onorato8a9b2202010-02-26 18:56:32 -080012888 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012889 + ": " + sticky);
12890
12891 if (receiver == null) {
12892 return sticky;
12893 }
12894
12895 ReceiverList rl
12896 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12897 if (rl == null) {
12898 rl = new ReceiverList(this, callerApp,
12899 Binder.getCallingPid(),
12900 Binder.getCallingUid(), receiver);
12901 if (rl.app != null) {
12902 rl.app.receivers.add(rl);
12903 } else {
12904 try {
12905 receiver.asBinder().linkToDeath(rl, 0);
12906 } catch (RemoteException e) {
12907 return sticky;
12908 }
12909 rl.linkedToDeath = true;
12910 }
12911 mRegisteredReceivers.put(receiver.asBinder(), rl);
12912 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012913 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012914 rl.add(bf);
12915 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012916 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012917 }
12918 mReceiverResolver.addFilter(bf);
12919
12920 // Enqueue broadcasts for all existing stickies that match
12921 // this filter.
12922 if (allSticky != null) {
12923 ArrayList receivers = new ArrayList();
12924 receivers.add(bf);
12925
12926 int N = allSticky.size();
12927 for (int i=0; i<N; i++) {
12928 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080012929 BroadcastQueue queue = broadcastQueueForIntent(intent);
12930 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012931 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012932 false, true, true);
Christopher Tatef46723b2012-01-26 14:19:24 -080012933 queue.enqueueParallelBroadcastLocked(r);
12934 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012935 }
12936 }
12937
12938 return sticky;
12939 }
12940 }
12941
12942 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012943 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012944
Christopher Tatef46723b2012-01-26 14:19:24 -080012945 final long origId = Binder.clearCallingIdentity();
12946 try {
12947 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012948
Christopher Tatef46723b2012-01-26 14:19:24 -080012949 synchronized(this) {
12950 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012951 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080012952 if (rl != null) {
12953 if (rl.curBroadcast != null) {
12954 BroadcastRecord r = rl.curBroadcast;
12955 final boolean doNext = finishReceiverLocked(
12956 receiver.asBinder(), r.resultCode, r.resultData,
12957 r.resultExtras, r.resultAbort, true);
12958 if (doNext) {
12959 doTrim = true;
12960 r.queue.processNextBroadcast(false);
12961 }
12962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963
Christopher Tatef46723b2012-01-26 14:19:24 -080012964 if (rl.app != null) {
12965 rl.app.receivers.remove(rl);
12966 }
12967 removeReceiverLocked(rl);
12968 if (rl.linkedToDeath) {
12969 rl.linkedToDeath = false;
12970 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012972 }
12973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012974
Christopher Tatef46723b2012-01-26 14:19:24 -080012975 // If we actually concluded any broadcasts, we might now be able
12976 // to trim the recipients' apps from our working set
12977 if (doTrim) {
12978 trimApplications();
12979 return;
12980 }
12981
12982 } finally {
12983 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012985 }
12986
12987 void removeReceiverLocked(ReceiverList rl) {
12988 mRegisteredReceivers.remove(rl.receiver.asBinder());
12989 int N = rl.size();
12990 for (int i=0; i<N; i++) {
12991 mReceiverResolver.removeFilter(rl.get(i));
12992 }
12993 }
12994
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012995 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12996 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12997 ProcessRecord r = mLruProcesses.get(i);
12998 if (r.thread != null) {
12999 try {
13000 r.thread.dispatchPackageBroadcast(cmd, packages);
13001 } catch (RemoteException ex) {
13002 }
13003 }
13004 }
13005 }
13006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007 private final int broadcastIntentLocked(ProcessRecord callerApp,
13008 String callerPackage, Intent intent, String resolvedType,
13009 IIntentReceiver resultTo, int resultCode, String resultData,
13010 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013011 boolean ordered, boolean sticky, int callingPid, int callingUid,
13012 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013013 intent = new Intent(intent);
13014
Dianne Hackborne7f97212011-02-24 14:40:20 -080013015 // By default broadcasts do not go to stopped apps.
13016 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13017
Joe Onorato8a9b2202010-02-26 18:56:32 -080013018 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013019 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13020 + " ordered=" + ordered);
13021 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013022 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013023 }
13024
13025 // Handle special intents: if this broadcast is from the package
13026 // manager about a package being removed, we need to remove all of
13027 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013028 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013029 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013030 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13031 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013032 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013033 || uidRemoved) {
13034 if (checkComponentPermission(
13035 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013036 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013037 == PackageManager.PERMISSION_GRANTED) {
13038 if (uidRemoved) {
13039 final Bundle intentExtras = intent.getExtras();
13040 final int uid = intentExtras != null
13041 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13042 if (uid >= 0) {
13043 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13044 synchronized (bs) {
13045 bs.removeUidStatsLocked(uid);
13046 }
13047 }
13048 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013049 // If resources are unvailble just force stop all
13050 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013051 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013052 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13053 if (list != null && (list.length > 0)) {
13054 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070013055 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013056 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013057 sendPackageBroadcastLocked(
13058 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013059 }
13060 } else {
13061 Uri data = intent.getData();
13062 String ssp;
13063 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13064 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13065 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070013066 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070013067 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013068 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013069 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13070 new String[] {ssp});
13071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013072 }
13073 }
13074 }
13075 } else {
13076 String msg = "Permission Denial: " + intent.getAction()
13077 + " broadcast from " + callerPackage + " (pid=" + callingPid
13078 + ", uid=" + callingUid + ")"
13079 + " requires "
13080 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013081 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013082 throw new SecurityException(msg);
13083 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013084
13085 // Special case for adding a package: by default turn on compatibility
13086 // mode.
13087 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070013088 Uri data = intent.getData();
13089 String ssp;
13090 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13091 mCompatModePackages.handlePackageAddedLocked(ssp,
13092 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013094 }
13095
13096 /*
13097 * If this is the time zone changed action, queue up a message that will reset the timezone
13098 * of all currently running processes. This message will get queued up before the broadcast
13099 * happens.
13100 */
13101 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13102 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13103 }
13104
Robert Greenwalt03595d02010-11-02 14:08:23 -070013105 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13106 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
13107 }
13108
Robert Greenwalt434203a2010-10-11 16:00:27 -070013109 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13110 ProxyProperties proxy = intent.getParcelableExtra("proxy");
13111 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
13112 }
13113
Dianne Hackborn854060af2009-07-09 18:14:31 -070013114 /*
13115 * Prevent non-system code (defined here to be non-persistent
13116 * processes) from sending protected broadcasts.
13117 */
13118 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
13119 || callingUid == Process.SHELL_UID || callingUid == 0) {
13120 // Always okay.
13121 } else if (callerApp == null || !callerApp.persistent) {
13122 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013123 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070013124 intent.getAction())) {
13125 String msg = "Permission Denial: not allowed to send broadcast "
13126 + intent.getAction() + " from pid="
13127 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013128 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013129 throw new SecurityException(msg);
13130 }
13131 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013132 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013133 return BROADCAST_SUCCESS;
13134 }
13135 }
13136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013137 // Add to the sticky list if requested.
13138 if (sticky) {
13139 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13140 callingPid, callingUid)
13141 != PackageManager.PERMISSION_GRANTED) {
13142 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13143 + callingPid + ", uid=" + callingUid
13144 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013145 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013146 throw new SecurityException(msg);
13147 }
13148 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013149 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013150 + " and enforce permission " + requiredPermission);
13151 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13152 }
13153 if (intent.getComponent() != null) {
13154 throw new SecurityException(
13155 "Sticky broadcasts can't target a specific component");
13156 }
13157 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13158 if (list == null) {
13159 list = new ArrayList<Intent>();
13160 mStickyBroadcasts.put(intent.getAction(), list);
13161 }
13162 int N = list.size();
13163 int i;
13164 for (i=0; i<N; i++) {
13165 if (intent.filterEquals(list.get(i))) {
13166 // This sticky already exists, replace it.
13167 list.set(i, new Intent(intent));
13168 break;
13169 }
13170 }
13171 if (i >= N) {
13172 list.add(new Intent(intent));
13173 }
13174 }
13175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013176 // Figure out who all will receive this broadcast.
13177 List receivers = null;
13178 List<BroadcastFilter> registeredReceivers = null;
13179 try {
13180 if (intent.getComponent() != null) {
13181 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013182 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070013183 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013184 if (ai != null) {
13185 receivers = new ArrayList();
13186 ResolveInfo ri = new ResolveInfo();
Amith Yamasani742a6712011-05-04 14:49:28 -070013187 ri.activityInfo = getActivityInfoForUser(ai, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013188 receivers.add(ri);
13189 }
13190 } else {
Amith Yamasani742a6712011-05-04 14:49:28 -070013191 // TODO: Apply userId
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013192 // Need to resolve the intent to interested receivers...
13193 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13194 == 0) {
13195 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013196 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013197 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013198 }
Mihai Preda074edef2009-05-18 17:13:31 +020013199 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013200 }
13201 } catch (RemoteException ex) {
13202 // pm is in same process, this will never happen.
13203 }
13204
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013205 final boolean replacePending =
13206 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13207
Joe Onorato8a9b2202010-02-26 18:56:32 -080013208 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013209 + " replacePending=" + replacePending);
13210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013211 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13212 if (!ordered && NR > 0) {
13213 // If we are not serializing this broadcast, then send the
13214 // registered receivers separately so they don't wait for the
13215 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080013216 final BroadcastQueue queue = broadcastQueueForIntent(intent);
13217 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013218 callerPackage, callingPid, callingUid, requiredPermission,
13219 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013220 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013221 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080013222 TAG, "Enqueueing parallel broadcast " + r);
13223 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013224 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013225 queue.enqueueParallelBroadcastLocked(r);
13226 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013228 registeredReceivers = null;
13229 NR = 0;
13230 }
13231
13232 // Merge into one list.
13233 int ir = 0;
13234 if (receivers != null) {
13235 // A special case for PACKAGE_ADDED: do not allow the package
13236 // being added to see this broadcast. This prevents them from
13237 // using this as a back door to get run as soon as they are
13238 // installed. Maybe in the future we want to have a special install
13239 // broadcast or such for apps, but we'd like to deliberately make
13240 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013241 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013242 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13243 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13244 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013245 Uri data = intent.getData();
13246 if (data != null) {
13247 String pkgName = data.getSchemeSpecificPart();
13248 if (pkgName != null) {
13249 skipPackages = new String[] { pkgName };
13250 }
13251 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013252 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013253 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070013254 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013255 if (skipPackages != null && (skipPackages.length > 0)) {
13256 for (String skipPackage : skipPackages) {
13257 if (skipPackage != null) {
13258 int NT = receivers.size();
13259 for (int it=0; it<NT; it++) {
13260 ResolveInfo curt = (ResolveInfo)receivers.get(it);
13261 if (curt.activityInfo.packageName.equals(skipPackage)) {
13262 receivers.remove(it);
13263 it--;
13264 NT--;
13265 }
13266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013267 }
13268 }
13269 }
13270
13271 int NT = receivers != null ? receivers.size() : 0;
13272 int it = 0;
13273 ResolveInfo curt = null;
13274 BroadcastFilter curr = null;
13275 while (it < NT && ir < NR) {
13276 if (curt == null) {
13277 curt = (ResolveInfo)receivers.get(it);
13278 }
13279 if (curr == null) {
13280 curr = registeredReceivers.get(ir);
13281 }
13282 if (curr.getPriority() >= curt.priority) {
13283 // Insert this broadcast record into the final list.
13284 receivers.add(it, curr);
13285 ir++;
13286 curr = null;
13287 it++;
13288 NT++;
13289 } else {
13290 // Skip to the next ResolveInfo in the final list.
13291 it++;
13292 curt = null;
13293 }
13294 }
13295 }
13296 while (ir < NR) {
13297 if (receivers == null) {
13298 receivers = new ArrayList();
13299 }
13300 receivers.add(registeredReceivers.get(ir));
13301 ir++;
13302 }
13303
13304 if ((receivers != null && receivers.size() > 0)
13305 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013306 BroadcastQueue queue = broadcastQueueForIntent(intent);
13307 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013308 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013309 receivers, resultTo, resultCode, resultData, map, ordered,
13310 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013311 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013312 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080013313 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013314 if (DEBUG_BROADCAST) {
13315 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013316 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013317 }
Christopher Tatef46723b2012-01-26 14:19:24 -080013318 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013319 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013320 queue.enqueueOrderedBroadcastLocked(r);
13321 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 }
13324
13325 return BROADCAST_SUCCESS;
13326 }
13327
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013328 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013329 // Refuse possible leaked file descriptors
13330 if (intent != null && intent.hasFileDescriptors() == true) {
13331 throw new IllegalArgumentException("File descriptors passed in Intent");
13332 }
13333
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013334 int flags = intent.getFlags();
13335
13336 if (!mProcessesReady) {
13337 // if the caller really truly claims to know what they're doing, go
13338 // ahead and allow the broadcast without launching any receivers
13339 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13340 intent = new Intent(intent);
13341 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13342 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13343 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13344 + " before boot completion");
13345 throw new IllegalStateException("Cannot broadcast before boot completed");
13346 }
13347 }
13348
13349 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13350 throw new IllegalArgumentException(
13351 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13352 }
13353
13354 return intent;
13355 }
13356
13357 public final int broadcastIntent(IApplicationThread caller,
13358 Intent intent, String resolvedType, IIntentReceiver resultTo,
13359 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013360 String requiredPermission, boolean serialized, boolean sticky, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013361 enforceNotIsolatedCaller("broadcastIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013362 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013363 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013365 final ProcessRecord callerApp = getRecordForAppLocked(caller);
13366 final int callingPid = Binder.getCallingPid();
13367 final int callingUid = Binder.getCallingUid();
13368 final long origId = Binder.clearCallingIdentity();
13369 int res = broadcastIntentLocked(callerApp,
13370 callerApp != null ? callerApp.info.packageName : null,
13371 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070013372 resultCode, resultData, map, requiredPermission, serialized, sticky,
13373 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013374 Binder.restoreCallingIdentity(origId);
13375 return res;
13376 }
13377 }
13378
13379 int broadcastIntentInPackage(String packageName, int uid,
13380 Intent intent, String resolvedType, IIntentReceiver resultTo,
13381 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013382 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013383 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013384 intent = verifyBroadcastLocked(intent);
13385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013386 final long origId = Binder.clearCallingIdentity();
13387 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13388 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013389 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013390 Binder.restoreCallingIdentity(origId);
13391 return res;
13392 }
13393 }
13394
Amith Yamasani742a6712011-05-04 14:49:28 -070013395 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13396 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013397 // Refuse possible leaked file descriptors
13398 if (intent != null && intent.hasFileDescriptors() == true) {
13399 throw new IllegalArgumentException("File descriptors passed in Intent");
13400 }
13401
13402 synchronized(this) {
13403 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13404 != PackageManager.PERMISSION_GRANTED) {
13405 String msg = "Permission Denial: unbroadcastIntent() from pid="
13406 + Binder.getCallingPid()
13407 + ", uid=" + Binder.getCallingUid()
13408 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013409 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013410 throw new SecurityException(msg);
13411 }
13412 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13413 if (list != null) {
13414 int N = list.size();
13415 int i;
13416 for (i=0; i<N; i++) {
13417 if (intent.filterEquals(list.get(i))) {
13418 list.remove(i);
13419 break;
13420 }
13421 }
13422 }
13423 }
13424 }
13425
13426 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13427 String resultData, Bundle resultExtras, boolean resultAbort,
13428 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013429 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13430 if (r == null) {
13431 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013432 return false;
13433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013434
Christopher Tatef46723b2012-01-26 14:19:24 -080013435 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13436 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013437 }
13438
13439 public void finishReceiver(IBinder who, int resultCode, String resultData,
13440 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013441 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013442
13443 // Refuse possible leaked file descriptors
13444 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13445 throw new IllegalArgumentException("File descriptors passed in Bundle");
13446 }
13447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013448 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080013449 try {
13450 boolean doNext = false;
13451 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013452
Christopher Tatef46723b2012-01-26 14:19:24 -080013453 synchronized(this) {
13454 r = broadcastRecordForReceiverLocked(who);
13455 if (r != null) {
13456 doNext = r.queue.finishReceiverLocked(r, resultCode,
13457 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013459 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013460
Christopher Tatef46723b2012-01-26 14:19:24 -080013461 if (doNext) {
13462 r.queue.processNextBroadcast(false);
13463 }
13464 trimApplications();
13465 } finally {
13466 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070013467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013468 }
13469
13470 private final void processCurBroadcastLocked(BroadcastRecord r,
13471 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013472 if (DEBUG_BROADCAST) Slog.v(TAG,
13473 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013474 if (app.thread == null) {
13475 throw new RemoteException();
13476 }
13477 r.receiver = app.thread.asBinder();
13478 r.curApp = app;
13479 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013480 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013481
13482 // Tell the application to launch this receiver.
13483 r.intent.setComponent(r.curComponent);
13484
13485 boolean started = false;
13486 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013487 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013488 "Delivering to component " + r.curComponent
13489 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070013490 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013491 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040013492 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013493 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013494 if (DEBUG_BROADCAST) Slog.v(TAG,
13495 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013496 started = true;
13497 } finally {
13498 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013499 if (DEBUG_BROADCAST) Slog.v(TAG,
13500 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013501 r.receiver = null;
13502 r.curApp = null;
13503 app.curReceiver = null;
13504 }
13505 }
13506
13507 }
13508
Jeff Brown4d94a762010-09-23 11:33:28 -070013509 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013510 Intent intent, int resultCode, String data, Bundle extras,
13511 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070013512 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013513 if (app != null && app.thread != null) {
13514 // If we have an app thread, do the call through that so it is
13515 // correctly ordered with other one-way calls.
13516 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013517 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013518 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013519 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013520 }
13521 }
13522
Jeff Brown4d94a762010-09-23 11:33:28 -070013523 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013524 BroadcastFilter filter, boolean ordered) {
13525 boolean skip = false;
13526 if (filter.requiredPermission != null) {
13527 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013528 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013529 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013530 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 + r.intent.toString()
13532 + " from " + r.callerPackage + " (pid="
13533 + r.callingPid + ", uid=" + r.callingUid + ")"
13534 + " requires " + filter.requiredPermission
13535 + " due to registered receiver " + filter);
13536 skip = true;
13537 }
13538 }
13539 if (r.requiredPermission != null) {
13540 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013541 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013542 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013543 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013544 + r.intent.toString()
13545 + " to " + filter.receiverList.app
13546 + " (pid=" + filter.receiverList.pid
13547 + ", uid=" + filter.receiverList.uid + ")"
13548 + " requires " + r.requiredPermission
13549 + " due to sender " + r.callerPackage
13550 + " (uid " + r.callingUid + ")");
13551 skip = true;
13552 }
13553 }
13554
13555 if (!skip) {
13556 // If this is not being sent as an ordered broadcast, then we
13557 // don't want to touch the fields that keep track of the current
13558 // state of ordered broadcasts.
13559 if (ordered) {
13560 r.receiver = filter.receiverList.receiver.asBinder();
13561 r.curFilter = filter;
13562 filter.receiverList.curBroadcast = r;
13563 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013564 if (filter.receiverList.app != null) {
13565 // Bump hosting application to no longer be in background
13566 // scheduling class. Note that we can't do that if there
13567 // isn't an app... but we can only be in that case for
13568 // things that directly call the IActivityManager API, which
13569 // are already core system stuff so don't matter for this.
13570 r.curApp = filter.receiverList.app;
13571 filter.receiverList.app.curReceiver = r;
13572 updateOomAdjLocked();
13573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013574 }
13575 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013576 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013577 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013578 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013579 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013580 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013581 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013582 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013583 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013584 if (ordered) {
13585 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
13586 }
13587 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013588 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013589 if (ordered) {
13590 r.receiver = null;
13591 r.curFilter = null;
13592 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013593 if (filter.receiverList.app != null) {
13594 filter.receiverList.app.curReceiver = null;
13595 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013596 }
13597 }
13598 }
13599 }
13600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013601 // =========================================================
13602 // INSTRUMENTATION
13603 // =========================================================
13604
13605 public boolean startInstrumentation(ComponentName className,
13606 String profileFile, int flags, Bundle arguments,
13607 IInstrumentationWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013608 enforceNotIsolatedCaller("startInstrumentation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013609 // Refuse possible leaked file descriptors
13610 if (arguments != null && arguments.hasFileDescriptors()) {
13611 throw new IllegalArgumentException("File descriptors passed in Bundle");
13612 }
13613
13614 synchronized(this) {
13615 InstrumentationInfo ii = null;
13616 ApplicationInfo ai = null;
13617 try {
13618 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013619 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013620 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013621 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013622 } catch (PackageManager.NameNotFoundException e) {
13623 }
13624 if (ii == null) {
13625 reportStartInstrumentationFailure(watcher, className,
13626 "Unable to find instrumentation info for: " + className);
13627 return false;
13628 }
13629 if (ai == null) {
13630 reportStartInstrumentationFailure(watcher, className,
13631 "Unable to find instrumentation target package: " + ii.targetPackage);
13632 return false;
13633 }
13634
13635 int match = mContext.getPackageManager().checkSignatures(
13636 ii.targetPackage, ii.packageName);
13637 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13638 String msg = "Permission Denial: starting instrumentation "
13639 + className + " from pid="
13640 + Binder.getCallingPid()
13641 + ", uid=" + Binder.getCallingPid()
13642 + " not allowed because package " + ii.packageName
13643 + " does not have a signature matching the target "
13644 + ii.targetPackage;
13645 reportStartInstrumentationFailure(watcher, className, msg);
13646 throw new SecurityException(msg);
13647 }
13648
13649 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013650 // Instrumentation can kill and relaunch even persistent processes
13651 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013652 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013653 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013654 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013655 app.instrumentationProfileFile = profileFile;
13656 app.instrumentationArguments = arguments;
13657 app.instrumentationWatcher = watcher;
13658 app.instrumentationResultClass = className;
13659 Binder.restoreCallingIdentity(origId);
13660 }
13661
13662 return true;
13663 }
13664
13665 /**
13666 * Report errors that occur while attempting to start Instrumentation. Always writes the
13667 * error to the logs, but if somebody is watching, send the report there too. This enables
13668 * the "am" command to report errors with more information.
13669 *
13670 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13671 * @param cn The component name of the instrumentation.
13672 * @param report The error report.
13673 */
13674 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13675 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013676 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013677 try {
13678 if (watcher != null) {
13679 Bundle results = new Bundle();
13680 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13681 results.putString("Error", report);
13682 watcher.instrumentationStatus(cn, -1, results);
13683 }
13684 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013685 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013686 }
13687 }
13688
13689 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13690 if (app.instrumentationWatcher != null) {
13691 try {
13692 // NOTE: IInstrumentationWatcher *must* be oneway here
13693 app.instrumentationWatcher.instrumentationFinished(
13694 app.instrumentationClass,
13695 resultCode,
13696 results);
13697 } catch (RemoteException e) {
13698 }
13699 }
13700 app.instrumentationWatcher = null;
13701 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013702 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013703 app.instrumentationProfileFile = null;
13704 app.instrumentationArguments = null;
13705
Christopher Tate3dacd842011-08-19 14:56:15 -070013706 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013707 }
13708
13709 public void finishInstrumentation(IApplicationThread target,
13710 int resultCode, Bundle results) {
13711 // Refuse possible leaked file descriptors
13712 if (results != null && results.hasFileDescriptors()) {
13713 throw new IllegalArgumentException("File descriptors passed in Intent");
13714 }
13715
13716 synchronized(this) {
13717 ProcessRecord app = getRecordForAppLocked(target);
13718 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013719 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013720 return;
13721 }
13722 final long origId = Binder.clearCallingIdentity();
13723 finishInstrumentationLocked(app, resultCode, results);
13724 Binder.restoreCallingIdentity(origId);
13725 }
13726 }
13727
13728 // =========================================================
13729 // CONFIGURATION
13730 // =========================================================
13731
13732 public ConfigurationInfo getDeviceConfigurationInfo() {
13733 ConfigurationInfo config = new ConfigurationInfo();
13734 synchronized (this) {
13735 config.reqTouchScreen = mConfiguration.touchscreen;
13736 config.reqKeyboardType = mConfiguration.keyboard;
13737 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013738 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13739 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013740 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13741 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013742 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13743 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013744 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13745 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013746 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013747 }
13748 return config;
13749 }
13750
13751 public Configuration getConfiguration() {
13752 Configuration ci;
13753 synchronized(this) {
13754 ci = new Configuration(mConfiguration);
13755 }
13756 return ci;
13757 }
13758
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013759 public void updatePersistentConfiguration(Configuration values) {
13760 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13761 "updateConfiguration()");
13762 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13763 "updateConfiguration()");
13764 if (values == null) {
13765 throw new NullPointerException("Configuration must not be null");
13766 }
13767
13768 synchronized(this) {
13769 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013770 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013771 Binder.restoreCallingIdentity(origId);
13772 }
13773 }
13774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013775 public void updateConfiguration(Configuration values) {
13776 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13777 "updateConfiguration()");
13778
13779 synchronized(this) {
13780 if (values == null && mWindowManager != null) {
13781 // sentinel: fetch the current configuration from the window manager
13782 values = mWindowManager.computeNewConfiguration();
13783 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013784
13785 if (mWindowManager != null) {
13786 mProcessList.applyDisplaySize(mWindowManager);
13787 }
13788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013789 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013790 if (values != null) {
13791 Settings.System.clearConfiguration(values);
13792 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013793 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013794 Binder.restoreCallingIdentity(origId);
13795 }
13796 }
13797
13798 /**
13799 * Do either or both things: (1) change the current configuration, and (2)
13800 * make sure the given activity is running with the (now) current
13801 * configuration. Returns true if the activity has been left running, or
13802 * false if <var>starting</var> is being destroyed to match the new
13803 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013804 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013805 */
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013806 boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013807 ActivityRecord starting, boolean persistent, boolean initLocale) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -070013808 // do nothing if we are headless
13809 if (mHeadless) return true;
13810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013811 int changes = 0;
13812
13813 boolean kept = true;
13814
13815 if (values != null) {
13816 Configuration newConfig = new Configuration(mConfiguration);
13817 changes = newConfig.updateFrom(values);
13818 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013819 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013820 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013821 }
13822
Doug Zongker2bec3d42009-12-04 12:52:44 -080013823 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013824
Dianne Hackborn813075a62011-11-14 17:45:19 -080013825 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013826 saveLocaleLocked(values.locale,
13827 !values.locale.equals(mConfiguration.locale),
13828 values.userSetLocale);
13829 }
13830
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013831 mConfigurationSeq++;
13832 if (mConfigurationSeq <= 0) {
13833 mConfigurationSeq = 1;
13834 }
13835 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013836 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013837 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013838
13839 final Configuration configCopy = new Configuration(mConfiguration);
13840
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013841 AttributeCache ac = AttributeCache.instance();
13842 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013843 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013845
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013846 // Make sure all resources in our process are updated
13847 // right now, so that anyone who is going to retrieve
13848 // resource values after we return will be sure to get
13849 // the new ones. This is especially important during
13850 // boot, where the first config change needs to guarantee
13851 // all resources have that config before following boot
13852 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013853 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013854
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013855 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013856 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013857 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013858 mHandler.sendMessage(msg);
13859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013860
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013861 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13862 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013863 try {
13864 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013865 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013866 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013867 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013868 }
13869 } catch (Exception e) {
13870 }
13871 }
13872 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013873 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13874 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013875 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013876 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013877 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13878 broadcastIntentLocked(null, null,
13879 new Intent(Intent.ACTION_LOCALE_CHANGED),
13880 null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013881 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013883 }
13884 }
13885
13886 if (changes != 0 && starting == null) {
13887 // If the configuration changed, and the caller is not already
13888 // in the process of starting an activity, then find the top
13889 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013890 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013891 }
13892
13893 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013894 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013895 // And we need to make sure at this point that all other activities
13896 // are made visible with the correct configuration.
13897 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013898 }
13899
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013900 if (values != null && mWindowManager != null) {
13901 mWindowManager.setNewConfiguration(mConfiguration);
13902 }
13903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013904 return kept;
13905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013906
13907 /**
13908 * Save the locale. You must be inside a synchronized (this) block.
13909 */
13910 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13911 if(isDiff) {
13912 SystemProperties.set("user.language", l.getLanguage());
13913 SystemProperties.set("user.region", l.getCountry());
13914 }
13915
13916 if(isPersist) {
13917 SystemProperties.set("persist.sys.language", l.getLanguage());
13918 SystemProperties.set("persist.sys.country", l.getCountry());
13919 SystemProperties.set("persist.sys.localevar", l.getVariant());
13920 }
13921 }
13922
13923 // =========================================================
13924 // LIFETIME MANAGEMENT
13925 // =========================================================
13926
Christopher Tatef46723b2012-01-26 14:19:24 -080013927 // Returns which broadcast queue the app is the current [or imminent] receiver
13928 // on, or 'null' if the app is not an active broadcast recipient.
13929 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
13930 BroadcastRecord r = app.curReceiver;
13931 if (r != null) {
13932 return r.queue;
13933 }
13934
13935 // It's not the current receiver, but it might be starting up to become one
13936 synchronized (this) {
13937 for (BroadcastQueue queue : mBroadcastQueues) {
13938 r = queue.mPendingBroadcast;
13939 if (r != null && r.curApp == app) {
13940 // found it; report which queue it's in
13941 return queue;
13942 }
13943 }
13944 }
13945
13946 return null;
13947 }
13948
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013949 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013950 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013951 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013952 // This adjustment has already been computed. If we are calling
13953 // from the top, we may have already computed our adjustment with
13954 // an earlier hidden adjustment that isn't really for us... if
13955 // so, use the new hidden adjustment.
13956 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013957 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013958 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013959 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013960 }
13961
13962 if (app.thread == null) {
13963 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013964 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013965 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013966 }
13967
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013968 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13969 app.adjSource = null;
13970 app.adjTarget = null;
13971 app.empty = false;
13972 app.hidden = false;
13973
13974 final int activitiesSize = app.activities.size();
13975
Dianne Hackborn7d608422011-08-07 16:24:18 -070013976 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013977 // The max adjustment doesn't allow this app to be anything
13978 // below foreground, so it is not worth doing work for it.
13979 app.adjType = "fixed";
13980 app.adjSeq = mAdjSeq;
13981 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013982 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013983 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013984 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013985 // System process can do UI, and when they do we want to have
13986 // them trim their memory after the user leaves the UI. To
13987 // facilitate this, here we need to determine whether or not it
13988 // is currently showing UI.
13989 app.systemNoUi = true;
13990 if (app == TOP_APP) {
13991 app.systemNoUi = false;
13992 } else if (activitiesSize > 0) {
13993 for (int j = 0; j < activitiesSize; j++) {
13994 final ActivityRecord r = app.activities.get(j);
13995 if (r.visible) {
13996 app.systemNoUi = false;
13997 break;
13998 }
13999 }
14000 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014001 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014002 }
14003
14004 final boolean hadForegroundActivities = app.foregroundActivities;
14005
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014006 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014007 app.keeping = false;
14008 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014009
The Android Open Source Project4df24232009-03-05 14:34:35 -080014010 // Determine the importance of the process, starting with most
14011 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014012 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014013 int schedGroup;
Christopher Tatef46723b2012-01-26 14:19:24 -080014014 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014015 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014016 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014017 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014018 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014019 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014020 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014021 } else if (app.instrumentationClass != null) {
14022 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014023 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014024 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014025 app.adjType = "instrumentation";
Christopher Tatef46723b2012-01-26 14:19:24 -080014026 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014027 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080014028 // counts as being in the foreground for OOM killer purposes.
14029 // It's placed in a sched group based on the nature of the
14030 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014031 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080014032 schedGroup = (queue == mFgBroadcastQueue)
14033 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014034 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014035 } else if (app.executingServices.size() > 0) {
14036 // An app that is currently executing a service callback also
14037 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014038 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014039 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014040 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014041 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014042 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014043 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014044 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014045 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014046 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014047 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014048 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014049 // A very not-needed process. If this is lower in the lru list,
14050 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014051 adj = hiddenAdj;
14052 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014053 app.hidden = true;
14054 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014055 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014056 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014057
14058 // Examine all activities if not already foreground.
14059 if (!app.foregroundActivities && activitiesSize > 0) {
14060 for (int j = 0; j < activitiesSize; j++) {
14061 final ActivityRecord r = app.activities.get(j);
14062 if (r.visible) {
14063 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014064 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14065 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014066 app.adjType = "visible";
14067 }
14068 schedGroup = Process.THREAD_GROUP_DEFAULT;
14069 app.hidden = false;
14070 app.foregroundActivities = true;
14071 break;
14072 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
14073 || r.state == ActivityState.STOPPING) {
14074 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014075 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14076 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014077 app.adjType = "stopping";
14078 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080014079 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014080 app.foregroundActivities = true;
14081 }
14082 }
14083 }
14084
Dianne Hackborn7d608422011-08-07 16:24:18 -070014085 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014086 if (app.foregroundServices) {
14087 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014088 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014089 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014090 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014091 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014092 } else if (app.forcingToForeground != null) {
14093 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014094 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014095 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014096 app.adjType = "force-foreground";
14097 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014098 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014099 }
14100 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014101
Dianne Hackborn7d608422011-08-07 16:24:18 -070014102 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014103 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014104 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014105 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014106 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014107 app.adjType = "heavy";
14108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014109
Dianne Hackborn7d608422011-08-07 16:24:18 -070014110 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014111 // This process is hosting what we currently consider to be the
14112 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014113 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014114 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014115 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014116 app.adjType = "home";
14117 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014118
Dianne Hackbornf35fe232011-11-01 19:25:20 -070014119 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
14120 && app.activities.size() > 0) {
14121 // This was the previous process that showed UI to the user.
14122 // We want to try to keep it around more aggressively, to give
14123 // a good experience around switching between two apps.
14124 adj = ProcessList.PREVIOUS_APP_ADJ;
14125 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14126 app.hidden = false;
14127 app.adjType = "previous";
14128 }
14129
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014130 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14131 + " reason=" + app.adjType);
14132
The Android Open Source Project4df24232009-03-05 14:34:35 -080014133 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014134 // there are applications dependent on our services or providers, but
14135 // this gives us a baseline and makes sure we don't get into an
14136 // infinite recursion.
14137 app.adjSeq = mAdjSeq;
14138 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014139
Christopher Tate6fa95972009-06-05 18:43:55 -070014140 if (mBackupTarget != null && app == mBackupTarget.app) {
14141 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070014142 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014143 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014144 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014145 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014146 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070014147 }
14148 }
14149
Dianne Hackborn7d608422011-08-07 16:24:18 -070014150 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014151 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014152 final long now = SystemClock.uptimeMillis();
14153 // This process is more important if the top activity is
14154 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070014155 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014156 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014157 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014158 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014159 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014160 // If this process has shown some UI, let it immediately
14161 // go to the LRU list because it may be pretty heavy with
14162 // UI stuff. We'll tag it with a label just to help
14163 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014164 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014165 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014166 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014167 } else {
14168 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14169 // This service has seen some activity within
14170 // recent memory, so we will keep its process ahead
14171 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014172 if (adj > ProcessList.SERVICE_ADJ) {
14173 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014174 app.adjType = "started-services";
14175 app.hidden = false;
14176 }
14177 }
14178 // If we have let the service slide into the background
14179 // state, still have some text describing what it is doing
14180 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014181 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014182 app.adjType = "started-bg-services";
14183 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014184 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014185 // Don't kill this process because it is doing work; it
14186 // has said it is doing work.
14187 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014188 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014189 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014190 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014191 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014192 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014193 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014194 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014195 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014196 // XXX should compute this based on the max of
14197 // all connected clients.
14198 ConnectionRecord cr = clist.get(i);
14199 if (cr.binding.client == app) {
14200 // Binding to ourself is not interesting.
14201 continue;
14202 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014203 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014204 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014205 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014206 int myHiddenAdj = hiddenAdj;
14207 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014208 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014209 myHiddenAdj = client.hiddenAdj;
14210 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014211 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014212 }
14213 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014214 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014215 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014216 String adjType = null;
14217 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14218 // Not doing bind OOM management, so treat
14219 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014220 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014221 // If this process has shown some UI, let it immediately
14222 // go to the LRU list because it may be pretty heavy with
14223 // UI stuff. We'll tag it with a label just to help
14224 // debug and understand what is going on.
14225 if (adj > clientAdj) {
14226 adjType = "bound-bg-ui-services";
14227 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014228 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014229 clientAdj = adj;
14230 } else {
14231 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14232 // This service has not seen activity within
14233 // recent memory, so allow it to drop to the
14234 // LRU list if there is no other reason to keep
14235 // it around. We'll also tag it with a label just
14236 // to help debug and undertand what is going on.
14237 if (adj > clientAdj) {
14238 adjType = "bound-bg-services";
14239 }
14240 clientAdj = adj;
14241 }
14242 }
14243 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014244 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014245 // If this process has recently shown UI, and
14246 // the process that is binding to it is less
14247 // important than being visible, then we don't
14248 // care about the binding as much as we care
14249 // about letting this process get into the LRU
14250 // list to be killed and restarted if needed for
14251 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014252 if (app.hasShownUi && app != mHomeProcess
14253 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014254 adjType = "bound-bg-ui-services";
14255 } else {
14256 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14257 |Context.BIND_IMPORTANT)) != 0) {
14258 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014259 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14260 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14261 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14262 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14263 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014264 adj = clientAdj;
14265 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014266 app.pendingUiClean = true;
14267 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14268 adj = ProcessList.VISIBLE_APP_ADJ;
14269 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014270 }
14271 if (!client.hidden) {
14272 app.hidden = false;
14273 }
14274 if (client.keeping) {
14275 app.keeping = true;
14276 }
14277 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014278 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014279 }
14280 if (adjType != null) {
14281 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014282 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14283 .REASON_SERVICE_IN_USE;
14284 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014285 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014286 app.adjTarget = s.name;
14287 }
14288 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14289 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14290 schedGroup = Process.THREAD_GROUP_DEFAULT;
14291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014292 }
14293 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014294 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14295 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014296 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014297 (a.visible || a.state == ActivityState.RESUMED
14298 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014299 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014300 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14301 schedGroup = Process.THREAD_GROUP_DEFAULT;
14302 }
14303 app.hidden = false;
14304 app.adjType = "service";
14305 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14306 .REASON_SERVICE_IN_USE;
14307 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014308 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014309 app.adjTarget = s.name;
14310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014312 }
14313 }
14314 }
14315 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014316
Dianne Hackborn287952c2010-09-22 22:34:31 -070014317 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014318 // would like to avoid killing it unless it would prevent the current
14319 // application from running. By default we put the process in
14320 // with the rest of the background processes; as we scan through
14321 // its services we may bump it up from there.
14322 if (adj > hiddenAdj) {
14323 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014324 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014325 app.adjType = "bg-services";
14326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014327 }
14328
Dianne Hackborn7d608422011-08-07 16:24:18 -070014329 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014330 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014331 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014332 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014333 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014334 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014335 if (cpr.clients.size() != 0) {
14336 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014337 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014338 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070014339 if (client == app) {
14340 // Being our own client is not interesting.
14341 continue;
14342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014343 int myHiddenAdj = hiddenAdj;
14344 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014345 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014346 myHiddenAdj = client.hiddenAdj;
14347 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014348 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014349 }
14350 }
14351 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014352 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014353 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014354 if (app.hasShownUi && app != mHomeProcess
14355 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014356 app.adjType = "bg-ui-provider";
14357 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014358 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14359 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014360 app.adjType = "provider";
14361 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014362 if (!client.hidden) {
14363 app.hidden = false;
14364 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014365 if (client.keeping) {
14366 app.keeping = true;
14367 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070014368 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14369 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014370 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014371 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014372 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014373 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014374 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14375 schedGroup = Process.THREAD_GROUP_DEFAULT;
14376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014377 }
14378 }
14379 // If the provider has external (non-framework) process
14380 // dependencies, ensure that its adjustment is at least
14381 // FOREGROUND_APP_ADJ.
14382 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014383 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14384 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014385 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014386 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014387 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014388 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014389 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014390 }
14391 }
14392 }
14393 }
14394
14395 app.curRawAdj = adj;
14396
Joe Onorato8a9b2202010-02-26 18:56:32 -080014397 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014398 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14399 if (adj > app.maxAdj) {
14400 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014401 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014402 schedGroup = Process.THREAD_GROUP_DEFAULT;
14403 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014404 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014405 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014406 app.keeping = true;
14407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014408
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014409 if (app.hasAboveClient) {
14410 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14411 // then we need to drop its adjustment to be lower than the service's
14412 // in order to honor the request. We want to drop it by one adjustment
14413 // level... but there is special meaning applied to various levels so
14414 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014415 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014416 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014417 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14418 adj = ProcessList.VISIBLE_APP_ADJ;
14419 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14420 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14421 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14422 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014423 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014424 adj++;
14425 }
14426 }
14427
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014428 if (adj == ProcessList.SERVICE_ADJ) {
14429 if (doingAll) {
14430 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14431 mNewNumServiceProcs++;
14432 }
14433 if (app.serviceb) {
14434 adj = ProcessList.SERVICE_B_ADJ;
14435 }
14436 } else {
14437 app.serviceb = false;
14438 }
14439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014440 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014441 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014442
14443 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014444 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14445 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014446 }
14447
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014448 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014449 }
14450
14451 /**
14452 * Ask a given process to GC right now.
14453 */
14454 final void performAppGcLocked(ProcessRecord app) {
14455 try {
14456 app.lastRequestedGc = SystemClock.uptimeMillis();
14457 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014458 if (app.reportLowMemory) {
14459 app.reportLowMemory = false;
14460 app.thread.scheduleLowMemory();
14461 } else {
14462 app.thread.processInBackground();
14463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014464 }
14465 } catch (Exception e) {
14466 // whatever.
14467 }
14468 }
14469
14470 /**
14471 * Returns true if things are idle enough to perform GCs.
14472 */
Josh Bartel7f208742010-02-25 11:01:44 -060014473 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080014474 boolean processingBroadcasts = false;
14475 for (BroadcastQueue q : mBroadcastQueues) {
14476 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14477 processingBroadcasts = true;
14478 }
14479 }
14480 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014481 && (mSleeping || (mMainStack.mResumedActivity != null &&
14482 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014483 }
14484
14485 /**
14486 * Perform GCs on all processes that are waiting for it, but only
14487 * if things are idle.
14488 */
14489 final void performAppGcsLocked() {
14490 final int N = mProcessesToGc.size();
14491 if (N <= 0) {
14492 return;
14493 }
Josh Bartel7f208742010-02-25 11:01:44 -060014494 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014495 while (mProcessesToGc.size() > 0) {
14496 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014497 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014498 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14499 <= SystemClock.uptimeMillis()) {
14500 // To avoid spamming the system, we will GC processes one
14501 // at a time, waiting a few seconds between each.
14502 performAppGcLocked(proc);
14503 scheduleAppGcsLocked();
14504 return;
14505 } else {
14506 // It hasn't been long enough since we last GCed this
14507 // process... put it in the list to wait for its time.
14508 addProcessToGcListLocked(proc);
14509 break;
14510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014511 }
14512 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014513
14514 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014515 }
14516 }
14517
14518 /**
14519 * If all looks good, perform GCs on all processes waiting for them.
14520 */
14521 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014522 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014523 performAppGcsLocked();
14524 return;
14525 }
14526 // Still not idle, wait some more.
14527 scheduleAppGcsLocked();
14528 }
14529
14530 /**
14531 * Schedule the execution of all pending app GCs.
14532 */
14533 final void scheduleAppGcsLocked() {
14534 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014535
14536 if (mProcessesToGc.size() > 0) {
14537 // Schedule a GC for the time to the next process.
14538 ProcessRecord proc = mProcessesToGc.get(0);
14539 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14540
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014541 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014542 long now = SystemClock.uptimeMillis();
14543 if (when < (now+GC_TIMEOUT)) {
14544 when = now + GC_TIMEOUT;
14545 }
14546 mHandler.sendMessageAtTime(msg, when);
14547 }
14548 }
14549
14550 /**
14551 * Add a process to the array of processes waiting to be GCed. Keeps the
14552 * list in sorted order by the last GC time. The process can't already be
14553 * on the list.
14554 */
14555 final void addProcessToGcListLocked(ProcessRecord proc) {
14556 boolean added = false;
14557 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14558 if (mProcessesToGc.get(i).lastRequestedGc <
14559 proc.lastRequestedGc) {
14560 added = true;
14561 mProcessesToGc.add(i+1, proc);
14562 break;
14563 }
14564 }
14565 if (!added) {
14566 mProcessesToGc.add(0, proc);
14567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014568 }
14569
14570 /**
14571 * Set up to ask a process to GC itself. This will either do it
14572 * immediately, or put it on the list of processes to gc the next
14573 * time things are idle.
14574 */
14575 final void scheduleAppGcLocked(ProcessRecord app) {
14576 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014577 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014578 return;
14579 }
14580 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014581 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014582 scheduleAppGcsLocked();
14583 }
14584 }
14585
Dianne Hackborn287952c2010-09-22 22:34:31 -070014586 final void checkExcessivePowerUsageLocked(boolean doKills) {
14587 updateCpuStatsNow();
14588
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014589 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014590 boolean doWakeKills = doKills;
14591 boolean doCpuKills = doKills;
14592 if (mLastPowerCheckRealtime == 0) {
14593 doWakeKills = false;
14594 }
14595 if (mLastPowerCheckUptime == 0) {
14596 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014597 }
14598 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014599 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014600 }
14601 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014602 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14603 final long curUptime = SystemClock.uptimeMillis();
14604 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14605 mLastPowerCheckRealtime = curRealtime;
14606 mLastPowerCheckUptime = curUptime;
14607 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14608 doWakeKills = false;
14609 }
14610 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14611 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014612 }
14613 int i = mLruProcesses.size();
14614 while (i > 0) {
14615 i--;
14616 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014617 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014618 long wtime;
14619 synchronized (stats) {
14620 wtime = stats.getProcessWakeTime(app.info.uid,
14621 app.pid, curRealtime);
14622 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014623 long wtimeUsed = wtime - app.lastWakeTime;
14624 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14625 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014626 StringBuilder sb = new StringBuilder(128);
14627 sb.append("Wake for ");
14628 app.toShortString(sb);
14629 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014630 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014631 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014632 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014633 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014634 sb.append((wtimeUsed*100)/realtimeSince);
14635 sb.append("%)");
14636 Slog.i(TAG, sb.toString());
14637 sb.setLength(0);
14638 sb.append("CPU for ");
14639 app.toShortString(sb);
14640 sb.append(": over ");
14641 TimeUtils.formatDuration(uptimeSince, sb);
14642 sb.append(" used ");
14643 TimeUtils.formatDuration(cputimeUsed, sb);
14644 sb.append(" (");
14645 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014646 sb.append("%)");
14647 Slog.i(TAG, sb.toString());
14648 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014649 // If a process has held a wake lock for more
14650 // than 50% of the time during this period,
14651 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014652 if (doWakeKills && realtimeSince > 0
14653 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14654 synchronized (stats) {
14655 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14656 realtimeSince, wtimeUsed);
14657 }
14658 Slog.w(TAG, "Excessive wake lock in " + app.processName
14659 + " (pid " + app.pid + "): held " + wtimeUsed
14660 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014661 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14662 app.processName, app.setAdj, "excessive wake lock");
14663 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014664 } else if (doCpuKills && uptimeSince > 0
14665 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14666 synchronized (stats) {
14667 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14668 uptimeSince, cputimeUsed);
14669 }
14670 Slog.w(TAG, "Excessive CPU in " + app.processName
14671 + " (pid " + app.pid + "): used " + cputimeUsed
14672 + " during " + uptimeSince);
14673 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14674 app.processName, app.setAdj, "excessive cpu");
14675 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014676 } else {
14677 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014678 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014679 }
14680 }
14681 }
14682 }
14683
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014684 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014685 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014686 app.hiddenAdj = hiddenAdj;
14687
14688 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014689 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014690 }
14691
Dianne Hackborn287952c2010-09-22 22:34:31 -070014692 final boolean wasKeeping = app.keeping;
14693
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014694 boolean success = true;
14695
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014696 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014697
Jeff Brown10e89712011-07-08 18:52:57 -070014698 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014699 if (false) {
14700 // Removing for now. Forcing GCs is not so useful anymore
14701 // with Dalvik, and the new memory level hint facility is
14702 // better for what we need to do these days.
14703 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14704 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14705 // If this app is transitioning from foreground to
14706 // non-foreground, have it do a gc.
14707 scheduleAppGcLocked(app);
14708 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14709 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14710 // Likewise do a gc when an app is moving in to the
14711 // background (such as a service stopping).
14712 scheduleAppGcLocked(app);
14713 }
Jeff Brown10e89712011-07-08 18:52:57 -070014714 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014715
Jeff Brown10e89712011-07-08 18:52:57 -070014716 if (wasKeeping && !app.keeping) {
14717 // This app is no longer something we want to keep. Note
14718 // its current wake lock time to later know to kill it if
14719 // it is not behaving well.
14720 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14721 synchronized (stats) {
14722 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14723 app.pid, SystemClock.elapsedRealtime());
14724 }
14725 app.lastCpuTime = app.curCpuTime;
14726 }
14727
14728 app.setRawAdj = app.curRawAdj;
14729 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014730
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014731 if (app.curAdj != app.setAdj) {
14732 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014733 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014734 TAG, "Set " + app.pid + " " + app.processName +
14735 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014736 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014737 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014738 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014739 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014740 }
14741 }
14742 if (app.setSchedGroup != app.curSchedGroup) {
14743 app.setSchedGroup = app.curSchedGroup;
14744 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14745 "Setting process group of " + app.processName
14746 + " to " + app.curSchedGroup);
14747 if (app.waitingToKill != null &&
14748 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14749 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14750 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14751 app.processName, app.setAdj, app.waitingToKill);
14752 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014753 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014754 } else {
14755 if (true) {
14756 long oldId = Binder.clearCallingIdentity();
14757 try {
14758 Process.setProcessGroup(app.pid, app.curSchedGroup);
14759 } catch (Exception e) {
14760 Slog.w(TAG, "Failed setting process group of " + app.pid
14761 + " to " + app.curSchedGroup);
14762 e.printStackTrace();
14763 } finally {
14764 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014765 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014766 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014767 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014768 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014769 app.thread.setSchedulingGroup(app.curSchedGroup);
14770 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014771 }
14772 }
14773 }
14774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014775 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014776 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014777 }
14778
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014779 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014780 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014781 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborncbb722e2012-02-07 18:33:49 -080014782 for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) {
14783 ActivityRecord r = mMainStack.mPausingActivities.get(i);
14784 if (r.app != null) {
14785 resumedActivity = r;
14786 break;
14787 }
14788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014789 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014790 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014791 }
14792 }
14793 return resumedActivity;
14794 }
14795
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014796 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014797 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014798 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14799 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014800 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14801 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014802
14803 mAdjSeq++;
14804
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014805 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014806 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14807 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014808 if (nowHidden != wasHidden) {
14809 // Changed to/from hidden state, so apps after it in the LRU
14810 // list may also be changed.
14811 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014812 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014813 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014814 }
14815
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014816 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014817 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014818 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14819
14820 if (false) {
14821 RuntimeException e = new RuntimeException();
14822 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014823 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014824 }
14825
14826 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014827 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014828
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014829 // Let's determine how many processes we have running vs.
14830 // how many slots we have for background processes; we may want
14831 // to put multiple processes in a slot of there are enough of
14832 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014833 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014834 int factor = (mLruProcesses.size()-4)/numSlots;
14835 if (factor < 1) factor = 1;
14836 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014837 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014838
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014839 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014840 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014841 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014842 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014843 while (i > 0) {
14844 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014845 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014846 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014847 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14848 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014849 && app.curAdj == curHiddenAdj) {
14850 step++;
14851 if (step >= factor) {
14852 step = 0;
14853 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014854 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014855 }
14856 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014857 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014858 numHidden++;
14859 if (numHidden > mProcessLimit) {
14860 Slog.i(TAG, "No longer want " + app.processName
14861 + " (pid " + app.pid + "): hidden #" + numHidden);
14862 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14863 app.processName, app.setAdj, "too many background");
14864 app.killedBackground = true;
14865 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014866 }
14867 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080014868 if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14869 // If this is an isolated process, and there are no
14870 // services running in it, then the process is no longer
14871 // needed. We agressively kill these because we can by
14872 // definition not re-use the same process again, and it is
14873 // good to avoid having whatever code was running in them
14874 // left sitting around after no longer needed.
14875 Slog.i(TAG, "Isolated process " + app.processName
14876 + " (pid " + app.pid + ") no longer needed");
14877 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14878 app.processName, app.setAdj, "isolated not needed");
14879 app.killedBackground = true;
14880 Process.killProcessQuiet(app.pid);
14881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014882 }
14883 }
14884
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014885 mNumServiceProcs = mNewNumServiceProcs;
14886
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014887 // Now determine the memory trimming level of background processes.
14888 // Unfortunately we need to start at the back of the list to do this
14889 // properly. We only do this if the number of background apps we
14890 // are managing to keep around is less than half the maximum we desire;
14891 // if we are keeping a good number around, we'll let them use whatever
14892 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014893 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014894 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014895 factor = numHidden/3;
14896 int minFactor = 2;
14897 if (mHomeProcess != null) minFactor++;
14898 if (mPreviousProcess != null) minFactor++;
14899 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014900 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014901 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014902 for (i=0; i<N; i++) {
14903 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014904 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14905 && app.curAdj != ProcessList.SERVICE_B_ADJ
14906 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014907 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14908 try {
14909 app.thread.scheduleTrimMemory(curLevel);
14910 } catch (RemoteException e) {
14911 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014912 if (false) {
14913 // For now we won't do this; our memory trimming seems
14914 // to be good enough at this point that destroying
14915 // activities causes more harm than good.
14916 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14917 && app != mHomeProcess && app != mPreviousProcess) {
14918 // For these apps we will also finish their activities
14919 // to help them free memory.
14920 mMainStack.destroyActivitiesLocked(app, false, "trim");
14921 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014922 }
14923 }
14924 app.trimMemoryLevel = curLevel;
14925 step++;
14926 if (step >= factor) {
14927 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014928 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14929 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014930 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014931 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14932 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014933 break;
14934 }
14935 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014936 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014937 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014938 && app.thread != null) {
14939 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014940 app.thread.scheduleTrimMemory(
14941 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014942 } catch (RemoteException e) {
14943 }
14944 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014945 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014946 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014947 && app.pendingUiClean) {
14948 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14949 && app.thread != null) {
14950 try {
14951 app.thread.scheduleTrimMemory(
14952 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14953 } catch (RemoteException e) {
14954 }
14955 }
14956 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14957 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014958 } else {
14959 app.trimMemoryLevel = 0;
14960 }
14961 }
14962 } else {
14963 final int N = mLruProcesses.size();
14964 for (i=0; i<N; i++) {
14965 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014966 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014967 && app.pendingUiClean) {
14968 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14969 && app.thread != null) {
14970 try {
14971 app.thread.scheduleTrimMemory(
14972 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14973 } catch (RemoteException e) {
14974 }
14975 }
14976 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14977 app.pendingUiClean = false;
14978 } else {
14979 app.trimMemoryLevel = 0;
14980 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014981 }
14982 }
14983
14984 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014985 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014987 }
14988
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014989 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014990 synchronized (this) {
14991 int i;
14992
14993 // First remove any unused application processes whose package
14994 // has been removed.
14995 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14996 final ProcessRecord app = mRemovedProcesses.get(i);
14997 if (app.activities.size() == 0
14998 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014999 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015000 TAG, "Exiting empty application process "
15001 + app.processName + " ("
15002 + (app.thread != null ? app.thread.asBinder() : null)
15003 + ")\n");
15004 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070015005 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
15006 app.processName, app.setAdj, "empty");
15007 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015008 } else {
15009 try {
15010 app.thread.scheduleExit();
15011 } catch (Exception e) {
15012 // Ignore exceptions.
15013 }
15014 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070015015 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015016 mRemovedProcesses.remove(i);
15017
15018 if (app.persistent) {
15019 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080015020 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015021 }
15022 }
15023 }
15024 }
15025
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015026 // Now update the oom adj for all processes.
15027 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015028 }
15029 }
15030
15031 /** This method sends the specified signal to each of the persistent apps */
15032 public void signalPersistentProcesses(int sig) throws RemoteException {
15033 if (sig != Process.SIGNAL_USR1) {
15034 throw new SecurityException("Only SIGNAL_USR1 is allowed");
15035 }
15036
15037 synchronized (this) {
15038 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15039 != PackageManager.PERMISSION_GRANTED) {
15040 throw new SecurityException("Requires permission "
15041 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15042 }
15043
Dianne Hackborndd71fc82009-12-16 19:24:32 -080015044 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15045 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015046 if (r.thread != null && r.persistent) {
15047 Process.sendSignal(r.pid, sig);
15048 }
15049 }
15050 }
15051 }
15052
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015053 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15054 if (proc == null || proc == mProfileProc) {
15055 proc = mProfileProc;
15056 path = mProfileFile;
15057 profileType = mProfileType;
15058 clearProfilerLocked();
15059 }
15060 if (proc == null) {
15061 return;
15062 }
15063 try {
15064 proc.thread.profilerControl(false, path, null, profileType);
15065 } catch (RemoteException e) {
15066 throw new IllegalStateException("Process disappeared");
15067 }
15068 }
15069
15070 private void clearProfilerLocked() {
15071 if (mProfileFd != null) {
15072 try {
15073 mProfileFd.close();
15074 } catch (IOException e) {
15075 }
15076 }
15077 mProfileApp = null;
15078 mProfileProc = null;
15079 mProfileFile = null;
15080 mProfileType = 0;
15081 mAutoStopProfiler = false;
15082 }
15083
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015084 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070015085 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015086
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015087 try {
15088 synchronized (this) {
15089 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15090 // its own permission.
15091 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15092 != PackageManager.PERMISSION_GRANTED) {
15093 throw new SecurityException("Requires permission "
15094 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015095 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015096
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015097 if (start && fd == null) {
15098 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015099 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015100
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015101 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015102 if (process != null) {
15103 try {
15104 int pid = Integer.parseInt(process);
15105 synchronized (mPidsSelfLocked) {
15106 proc = mPidsSelfLocked.get(pid);
15107 }
15108 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015109 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015110
15111 if (proc == null) {
15112 HashMap<String, SparseArray<ProcessRecord>> all
15113 = mProcessNames.getMap();
15114 SparseArray<ProcessRecord> procs = all.get(process);
15115 if (procs != null && procs.size() > 0) {
15116 proc = procs.valueAt(0);
15117 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015118 }
15119 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015120
15121 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015122 throw new IllegalArgumentException("Unknown process: " + process);
15123 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015124
15125 if (start) {
15126 stopProfilerLocked(null, null, 0);
15127 setProfileApp(proc.info, proc.processName, path, fd, false);
15128 mProfileProc = proc;
15129 mProfileType = profileType;
15130 try {
15131 fd = fd.dup();
15132 } catch (IOException e) {
15133 fd = null;
15134 }
15135 proc.thread.profilerControl(start, path, fd, profileType);
15136 fd = null;
15137 mProfileFd = null;
15138 } else {
15139 stopProfilerLocked(proc, path, profileType);
15140 if (fd != null) {
15141 try {
15142 fd.close();
15143 } catch (IOException e) {
15144 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015145 }
15146 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015147
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015148 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015149 }
15150 } catch (RemoteException e) {
15151 throw new IllegalStateException("Process disappeared");
15152 } finally {
15153 if (fd != null) {
15154 try {
15155 fd.close();
15156 } catch (IOException e) {
15157 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015158 }
15159 }
15160 }
Andy McFadden824c5102010-07-09 16:26:57 -070015161
15162 public boolean dumpHeap(String process, boolean managed,
15163 String path, ParcelFileDescriptor fd) throws RemoteException {
15164
15165 try {
15166 synchronized (this) {
15167 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15168 // its own permission (same as profileControl).
15169 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15170 != PackageManager.PERMISSION_GRANTED) {
15171 throw new SecurityException("Requires permission "
15172 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15173 }
15174
15175 if (fd == null) {
15176 throw new IllegalArgumentException("null fd");
15177 }
15178
15179 ProcessRecord proc = null;
15180 try {
15181 int pid = Integer.parseInt(process);
15182 synchronized (mPidsSelfLocked) {
15183 proc = mPidsSelfLocked.get(pid);
15184 }
15185 } catch (NumberFormatException e) {
15186 }
15187
15188 if (proc == null) {
15189 HashMap<String, SparseArray<ProcessRecord>> all
15190 = mProcessNames.getMap();
15191 SparseArray<ProcessRecord> procs = all.get(process);
15192 if (procs != null && procs.size() > 0) {
15193 proc = procs.valueAt(0);
15194 }
15195 }
15196
15197 if (proc == null || proc.thread == null) {
15198 throw new IllegalArgumentException("Unknown process: " + process);
15199 }
15200
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080015201 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15202 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070015203 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15204 throw new SecurityException("Process not debuggable: " + proc);
15205 }
15206 }
15207
15208 proc.thread.dumpHeap(managed, path, fd);
15209 fd = null;
15210 return true;
15211 }
15212 } catch (RemoteException e) {
15213 throw new IllegalStateException("Process disappeared");
15214 } finally {
15215 if (fd != null) {
15216 try {
15217 fd.close();
15218 } catch (IOException e) {
15219 }
15220 }
15221 }
15222 }
15223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015224 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15225 public void monitor() {
15226 synchronized (this) { }
15227 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015228
Dianne Hackborna573f6a2012-02-09 16:12:18 -080015229 void onCoreSettingsChange(Bundle settings) {
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015230 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15231 ProcessRecord processRecord = mLruProcesses.get(i);
15232 try {
15233 if (processRecord.thread != null) {
15234 processRecord.thread.setCoreSettings(settings);
15235 }
15236 } catch (RemoteException re) {
15237 /* ignore */
15238 }
15239 }
15240 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015241
15242 // Multi-user methods
15243
Amith Yamasani742a6712011-05-04 14:49:28 -070015244 private int mCurrentUserId;
15245 private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015246 private ArrayList<UserListener> mUserListeners = new ArrayList<UserListener>(3);
15247
15248 public interface UserListener {
15249 public void onUserChanged(int userId);
15250
15251 public void onUserAdded(int userId);
15252
15253 public void onUserRemoved(int userId);
15254
15255 public void onUserLoggedOut(int userId);
15256 }
15257
15258 public void addUserListener(UserListener listener) {
15259 synchronized (this) {
15260 if (!mUserListeners.contains(listener)) {
15261 mUserListeners.add(listener);
15262 }
15263 }
15264 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015265
15266 public boolean switchUser(int userId) {
15267 final int callingUid = Binder.getCallingUid();
15268 if (callingUid != 0 && callingUid != Process.myUid()) {
15269 Slog.e(TAG, "Trying to switch user from unauthorized app");
15270 return false;
15271 }
15272 if (mCurrentUserId == userId)
15273 return true;
15274
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015275 ArrayList<UserListener> listeners;
15276
Amith Yamasani742a6712011-05-04 14:49:28 -070015277 synchronized (this) {
15278 // Check if user is already logged in, otherwise check if user exists first before
15279 // adding to the list of logged in users.
15280 if (mLoggedInUsers.indexOfKey(userId) < 0) {
15281 if (!userExists(userId)) {
15282 return false;
15283 }
15284 mLoggedInUsers.append(userId, userId);
15285 }
15286
15287 mCurrentUserId = userId;
15288 boolean haveActivities = mMainStack.switchUser(userId);
15289 if (!haveActivities) {
15290 startHomeActivityLocked(userId);
15291 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015292
15293 listeners = (ArrayList<UserListener>) mUserListeners.clone();
15294 }
15295 // Inform the listeners
15296 for (UserListener listener : listeners) {
15297 listener.onUserChanged(userId);
Amith Yamasani742a6712011-05-04 14:49:28 -070015298 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015299 return true;
15300 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015301
15302 private boolean userExists(int userId) {
15303 try {
15304 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
15305 for (UserInfo user : users) {
15306 if (user.id == userId) {
15307 return true;
15308 }
15309 }
15310 } catch (RemoteException re) {
15311 // Won't happen, in same process
15312 }
15313
15314 return false;
15315 }
15316
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015317 private void checkValidCaller(int uid, int userId) {
15318 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15319
15320 throw new SecurityException("Caller uid=" + uid
15321 + " is not privileged to communicate with user=" + userId);
15322 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015323
15324 private int applyUserId(int uid, int userId) {
15325 return UserId.getUid(userId, uid);
15326 }
15327
15328 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015329 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070015330 ApplicationInfo newInfo = new ApplicationInfo(info);
15331 newInfo.uid = applyUserId(info.uid, userId);
15332 if (newInfo.uid >= Process.FIRST_APPLICATION_UID) {
15333 newInfo.dataDir = USER_DATA_DIR + userId + "/"
15334 + info.packageName;
15335 }
15336 return newInfo;
15337 }
15338
15339 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015340 if (aInfo == null || aInfo.applicationInfo.uid < Process.FIRST_APPLICATION_UID
Amith Yamasani742a6712011-05-04 14:49:28 -070015341 || userId < 1) {
15342 return aInfo;
15343 }
15344
15345 ActivityInfo info = new ActivityInfo(aInfo);
15346 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15347 return info;
15348 }
15349
15350 static class ServiceMap {
15351
15352 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15353 = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15354 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15355 mServicesByIntentPerUser = new SparseArray<
15356 HashMap<Intent.FilterComparison, ServiceRecord>>();
15357
15358 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15359 // TODO: Deal with global services
15360 if (DEBUG_MU)
15361 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15362 return getServices(callingUser).get(name);
15363 }
15364
15365 ServiceRecord getServiceByName(ComponentName name) {
15366 return getServiceByName(name, -1);
15367 }
15368
15369 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15370 // TODO: Deal with global services
15371 if (DEBUG_MU)
15372 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15373 return getServicesByIntent(callingUser).get(filter);
15374 }
15375
15376 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15377 return getServiceByIntent(filter, -1);
15378 }
15379
15380 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15381 // TODO: Deal with global services
15382 getServices(callingUser).put(name, value);
15383 }
15384
15385 void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15386 ServiceRecord value) {
15387 // TODO: Deal with global services
15388 getServicesByIntent(callingUser).put(filter, value);
15389 }
15390
15391 void removeServiceByName(ComponentName name, int callingUser) {
15392 // TODO: Deal with global services
15393 ServiceRecord removed = getServices(callingUser).remove(name);
15394 if (DEBUG_MU)
15395 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15396 + " removed=" + removed);
15397 }
15398
15399 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15400 // TODO: Deal with global services
15401 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15402 if (DEBUG_MU)
15403 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15404 + " removed=" + removed);
15405 }
15406
15407 Collection<ServiceRecord> getAllServices(int callingUser) {
15408 // TODO: Deal with global services
15409 return getServices(callingUser).values();
15410 }
15411
15412 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15413 HashMap map = mServicesByNamePerUser.get(callingUser);
15414 if (map == null) {
15415 map = new HashMap<ComponentName, ServiceRecord>();
15416 mServicesByNamePerUser.put(callingUser, map);
15417 }
15418 return map;
15419 }
15420
15421 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15422 int callingUser) {
15423 HashMap map = mServicesByIntentPerUser.get(callingUser);
15424 if (map == null) {
15425 map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15426 mServicesByIntentPerUser.put(callingUser, map);
15427 }
15428 return map;
15429 }
15430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015431}