blob: a110dd69b5eefcf57455d89bf95c97d206cbc451 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
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;
272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700274 * Description of a request to start a new activity, which has been held
275 * due to app switches being disabled.
276 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700277 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700278 ActivityRecord r;
279 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700280 Uri[] grantedUriPermissions;
281 int grantedMode;
282 boolean onlyIfNeeded;
283 }
284
285 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
286 = new ArrayList<PendingActivityLaunch>();
287
288 /**
Christopher Tatef46723b2012-01-26 14:19:24 -0800289 * BROADCASTS
290 *
291 * We keep two broadcast queues and associated bookkeeping, one for those at
292 * foreground priority, and one for normal (background-priority) broadcasts.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 */
Christopher Tatef46723b2012-01-26 14:19:24 -0800294 public class BroadcastQueue {
295 static final String TAG = "BroadcastQueue";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296
Christopher Tatef46723b2012-01-26 14:19:24 -0800297 static final int MAX_BROADCAST_HISTORY = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298
Christopher Tatef46723b2012-01-26 14:19:24 -0800299 /**
300 * Recognizable moniker for this queue
301 */
302 String mQueueName;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800303
Christopher Tatef46723b2012-01-26 14:19:24 -0800304 /**
305 * Timeout period for this queue's broadcasts
306 */
307 long mTimeoutPeriod;
308
309 /**
310 * Lists of all active broadcasts that are to be executed immediately
311 * (without waiting for another broadcast to finish). Currently this only
312 * contains broadcasts to registered receivers, to avoid spinning up
313 * a bunch of processes to execute IntentReceiver components. Background-
314 * and foreground-priority broadcasts are queued separately.
315 */
316 final ArrayList<BroadcastRecord> mParallelBroadcasts
317 = new ArrayList<BroadcastRecord>();
318 /**
319 * List of all active broadcasts that are to be executed one at a time.
320 * The object at the top of the list is the currently activity broadcasts;
321 * those after it are waiting for the top to finish. As with parallel
322 * broadcasts, separate background- and foreground-priority queues are
323 * maintained.
324 */
325 final ArrayList<BroadcastRecord> mOrderedBroadcasts
326 = new ArrayList<BroadcastRecord>();
327
328 /**
329 * Historical data of past broadcasts, for debugging.
330 */
331 final BroadcastRecord[] mBroadcastHistory
332 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
333
334 /**
335 * Set when we current have a BROADCAST_INTENT_MSG in flight.
336 */
337 boolean mBroadcastsScheduled = false;
338
339 /**
340 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
341 */
342 boolean mPendingBroadcastTimeoutMessage;
343
344 /**
345 * Intent broadcasts that we have tried to start, but are
346 * waiting for the application's process to be created. We only
347 * need one per scheduling class (instead of a list) because we always
348 * process broadcasts one at a time, so no others can be started while
349 * waiting for this one.
350 */
351 BroadcastRecord mPendingBroadcast = null;
352
353 /**
354 * The receiver index that is pending, to restart the broadcast if needed.
355 */
356 int mPendingBroadcastRecvIndex;
357
358 BroadcastQueue(String name, long timeoutPeriod) {
359 mQueueName = name;
360 mTimeoutPeriod = timeoutPeriod;
361 }
362
363 public boolean isPendingBroadcastProcessLocked(int pid) {
364 return mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid;
365 }
366
367 public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
368 mParallelBroadcasts.add(r);
369 }
370
371 public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
372 mOrderedBroadcasts.add(r);
373 }
374
375 public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
376 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
377 if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
378 if (DEBUG_BROADCAST) Slog.v(TAG,
379 "***** DROPPING PARALLEL ["
380 + mQueueName + "]: " + r.intent);
381 mParallelBroadcasts.set(i, r);
382 return true;
383 }
384 }
385 return false;
386 }
387
388 public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
389 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
390 if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
391 if (DEBUG_BROADCAST) Slog.v(TAG,
392 "***** DROPPING ORDERED ["
393 + mQueueName + "]: " + r.intent);
394 mOrderedBroadcasts.set(i, r);
395 return true;
396 }
397 }
398 return false;
399 }
400
401 public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
402 boolean didSomething = false;
403 final BroadcastRecord br = mPendingBroadcast;
404 if (br != null && br.curApp.pid == app.pid) {
405 try {
406 mPendingBroadcast = null;
407 processCurBroadcastLocked(br, app);
408 didSomething = true;
409 } catch (Exception e) {
410 Slog.w(TAG, "Exception in new application when starting receiver "
411 + br.curComponent.flattenToShortString(), e);
412 logBroadcastReceiverDiscardLocked(br);
413 finishReceiverLocked(br, br.resultCode, br.resultData,
414 br.resultExtras, br.resultAbort, true);
415 scheduleBroadcastsLocked();
416 // We need to reset the state if we fails to start the receiver.
417 br.state = BroadcastRecord.IDLE;
418 throw new RuntimeException(e.getMessage());
419 }
420 }
421 return didSomething;
422 }
423
424 public void skipPendingBroadcastLocked(int pid) {
425 final BroadcastRecord br = mPendingBroadcast;
426 if (br != null && br.curApp.pid == pid) {
427 br.state = BroadcastRecord.IDLE;
428 br.nextReceiver = mPendingBroadcastRecvIndex;
429 mPendingBroadcast = null;
430 scheduleBroadcastsLocked();
431 }
432 }
433
434 public void skipCurrentReceiverLocked(ProcessRecord app) {
435 boolean reschedule = false;
436 BroadcastRecord r = app.curReceiver;
437 if (r != null) {
438 // The current broadcast is waiting for this app's receiver
439 // to be finished. Looks like that's not going to happen, so
440 // let the broadcast continue.
441 logBroadcastReceiverDiscardLocked(r);
442 finishReceiverLocked(r, r.resultCode, r.resultData,
443 r.resultExtras, r.resultAbort, true);
444 reschedule = true;
445 }
446
447 r = mPendingBroadcast;
448 if (r != null && r.curApp == app) {
449 if (DEBUG_BROADCAST) Slog.v(TAG,
450 "[" + mQueueName + "] skip & discard pending app " + r);
451 logBroadcastReceiverDiscardLocked(r);
452 finishReceiverLocked(r, r.resultCode, r.resultData,
453 r.resultExtras, r.resultAbort, true);
454 reschedule = true;
455 }
456 if (reschedule) {
457 scheduleBroadcastsLocked();
458 }
459 }
460
461 public void scheduleBroadcastsLocked() {
462 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
463 + mQueueName + "]: current="
464 + mBroadcastsScheduled);
465
466 if (mBroadcastsScheduled) {
467 return;
468 }
469 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
470 mBroadcastsScheduled = true;
471 }
472
473 public BroadcastRecord getMatchingOrderedReceiver(IBinder receiver) {
474 if (mOrderedBroadcasts.size() > 0) {
475 final BroadcastRecord r = mOrderedBroadcasts.get(0);
476 if (r != null && r.receiver == receiver) {
477 return r;
478 }
479 }
480 return null;
481 }
482
483 public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
484 String resultData, Bundle resultExtras, boolean resultAbort,
485 boolean explicit) {
486 int state = r.state;
487 r.state = BroadcastRecord.IDLE;
488 if (state == BroadcastRecord.IDLE) {
489 if (explicit) {
490 Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
491 }
492 }
493 r.receiver = null;
494 r.intent.setComponent(null);
495 if (r.curApp != null) {
496 r.curApp.curReceiver = null;
497 }
498 if (r.curFilter != null) {
499 r.curFilter.receiverList.curBroadcast = null;
500 }
501 r.curFilter = null;
502 r.curApp = null;
503 r.curComponent = null;
504 r.curReceiver = null;
505 mPendingBroadcast = null;
506
507 r.resultCode = resultCode;
508 r.resultData = resultData;
509 r.resultExtras = resultExtras;
510 r.resultAbort = resultAbort;
511
512 // We will process the next receiver right now if this is finishing
513 // an app receiver (which is always asynchronous) or after we have
514 // come back from calling a receiver.
515 return state == BroadcastRecord.APP_RECEIVE
516 || state == BroadcastRecord.CALL_DONE_RECEIVE;
517 }
518
519 private final void processNextBroadcast(boolean fromMsg) {
520 synchronized(ActivityManagerService.this) {
521 BroadcastRecord r;
522
523 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast ["
524 + mQueueName + "]: "
525 + mParallelBroadcasts.size() + " broadcasts, "
526 + mOrderedBroadcasts.size() + " ordered broadcasts");
527
528 updateCpuStats();
529
530 if (fromMsg) {
531 mBroadcastsScheduled = false;
532 }
533
534 // First, deliver any non-serialized broadcasts right away.
535 while (mParallelBroadcasts.size() > 0) {
536 r = mParallelBroadcasts.remove(0);
537 r.dispatchTime = SystemClock.uptimeMillis();
538 r.dispatchClockTime = System.currentTimeMillis();
539 final int N = r.receivers.size();
540 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast ["
541 + mQueueName + "] " + r);
542 for (int i=0; i<N; i++) {
543 Object target = r.receivers.get(i);
544 if (DEBUG_BROADCAST) Slog.v(TAG,
545 "Delivering non-ordered on [" + mQueueName + "] to registered "
546 + target + ": " + r);
547 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
548 }
549 addBroadcastToHistoryLocked(r);
550 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast ["
551 + mQueueName + "] " + r);
552 }
553
554 // Now take care of the next serialized one...
555
556 // If we are waiting for a process to come up to handle the next
557 // broadcast, then do nothing at this point. Just in case, we
558 // check that the process we're waiting for still exists.
559 if (mPendingBroadcast != null) {
560 if (DEBUG_BROADCAST_LIGHT) {
561 Slog.v(TAG, "processNextBroadcast ["
562 + mQueueName + "]: waiting for "
563 + mPendingBroadcast.curApp);
564 }
565
566 boolean isDead;
567 synchronized (mPidsSelfLocked) {
568 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
569 }
570 if (!isDead) {
571 // It's still alive, so keep waiting
572 return;
573 } else {
574 Slog.w(TAG, "pending app ["
575 + mQueueName + "]" + mPendingBroadcast.curApp
576 + " died before responding to broadcast");
577 mPendingBroadcast.state = BroadcastRecord.IDLE;
578 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
579 mPendingBroadcast = null;
580 }
581 }
582
583 boolean looped = false;
584
585 do {
586 if (mOrderedBroadcasts.size() == 0) {
587 // No more broadcasts pending, so all done!
588 scheduleAppGcsLocked();
589 if (looped) {
590 // If we had finished the last ordered broadcast, then
591 // make sure all processes have correct oom and sched
592 // adjustments.
593 updateOomAdjLocked();
594 }
595 return;
596 }
597 r = mOrderedBroadcasts.get(0);
598 boolean forceReceive = false;
599
600 // Ensure that even if something goes awry with the timeout
601 // detection, we catch "hung" broadcasts here, discard them,
602 // and continue to make progress.
603 //
604 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
605 // receivers don't get executed with timeouts. They're intended for
606 // one time heavy lifting after system upgrades and can take
607 // significant amounts of time.
608 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
609 if (mProcessesReady && r.dispatchTime > 0) {
610 long now = SystemClock.uptimeMillis();
611 if ((numReceivers > 0) &&
612 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
613 Slog.w(TAG, "Hung broadcast ["
614 + mQueueName + "] discarded after timeout failure:"
615 + " now=" + now
616 + " dispatchTime=" + r.dispatchTime
617 + " startTime=" + r.receiverTime
618 + " intent=" + r.intent
619 + " numReceivers=" + numReceivers
620 + " nextReceiver=" + r.nextReceiver
621 + " state=" + r.state);
622 broadcastTimeoutLocked(false); // forcibly finish this broadcast
623 forceReceive = true;
624 r.state = BroadcastRecord.IDLE;
625 }
626 }
627
628 if (r.state != BroadcastRecord.IDLE) {
629 if (DEBUG_BROADCAST) Slog.d(TAG,
630 "processNextBroadcast("
631 + mQueueName + ") called when not idle (state="
632 + r.state + ")");
633 return;
634 }
635
636 if (r.receivers == null || r.nextReceiver >= numReceivers
637 || r.resultAbort || forceReceive) {
638 // No more receivers for this broadcast! Send the final
639 // result if requested...
640 if (r.resultTo != null) {
641 try {
642 if (DEBUG_BROADCAST) {
643 int seq = r.intent.getIntExtra("seq", -1);
644 Slog.i(TAG, "Finishing broadcast ["
645 + mQueueName + "] " + r.intent.getAction()
646 + " seq=" + seq + " app=" + r.callerApp);
647 }
648 performReceiveLocked(r.callerApp, r.resultTo,
649 new Intent(r.intent), r.resultCode,
650 r.resultData, r.resultExtras, false, false);
651 // Set this to null so that the reference
652 // (local and remote) isnt kept in the mBroadcastHistory.
653 r.resultTo = null;
654 } catch (RemoteException e) {
655 Slog.w(TAG, "Failure ["
656 + mQueueName + "] sending broadcast result of "
657 + r.intent, e);
658 }
659 }
660
661 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
662 cancelBroadcastTimeoutLocked();
663
664 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
665 + r);
666
667 // ... and on to the next...
668 addBroadcastToHistoryLocked(r);
669 mOrderedBroadcasts.remove(0);
670 r = null;
671 looped = true;
672 continue;
673 }
674 } while (r == null);
675
676 // Get the next receiver...
677 int recIdx = r.nextReceiver++;
678
679 // Keep track of when this receiver started, and make sure there
680 // is a timeout message pending to kill it if need be.
681 r.receiverTime = SystemClock.uptimeMillis();
682 if (recIdx == 0) {
683 r.dispatchTime = r.receiverTime;
684 r.dispatchClockTime = System.currentTimeMillis();
685 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["
686 + mQueueName + "] " + r);
687 }
688 if (! mPendingBroadcastTimeoutMessage) {
689 long timeoutTime = r.receiverTime + mTimeoutPeriod;
690 if (DEBUG_BROADCAST) Slog.v(TAG,
691 "Submitting BROADCAST_TIMEOUT_MSG ["
692 + mQueueName + "] for " + r + " at " + timeoutTime);
693 setBroadcastTimeoutLocked(timeoutTime);
694 }
695
696 Object nextReceiver = r.receivers.get(recIdx);
697 if (nextReceiver instanceof BroadcastFilter) {
698 // Simple case: this is a registered receiver who gets
699 // a direct call.
700 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
701 if (DEBUG_BROADCAST) Slog.v(TAG,
702 "Delivering ordered ["
703 + mQueueName + "] to registered "
704 + filter + ": " + r);
705 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
706 if (r.receiver == null || !r.ordered) {
707 // The receiver has already finished, so schedule to
708 // process the next one.
709 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing ["
710 + mQueueName + "]: ordered="
711 + r.ordered + " receiver=" + r.receiver);
712 r.state = BroadcastRecord.IDLE;
713 scheduleBroadcastsLocked();
714 }
715 return;
716 }
717
718 // Hard case: need to instantiate the receiver, possibly
719 // starting its application process to host it.
720
721 ResolveInfo info =
722 (ResolveInfo)nextReceiver;
723
724 boolean skip = false;
725 int perm = checkComponentPermission(info.activityInfo.permission,
726 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
727 info.activityInfo.exported);
728 if (perm != PackageManager.PERMISSION_GRANTED) {
729 if (!info.activityInfo.exported) {
730 Slog.w(TAG, "Permission Denial: broadcasting "
731 + r.intent.toString()
732 + " from " + r.callerPackage + " (pid=" + r.callingPid
733 + ", uid=" + r.callingUid + ")"
734 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
735 + " due to receiver " + info.activityInfo.packageName
736 + "/" + info.activityInfo.name);
737 } else {
738 Slog.w(TAG, "Permission Denial: broadcasting "
739 + r.intent.toString()
740 + " from " + r.callerPackage + " (pid=" + r.callingPid
741 + ", uid=" + r.callingUid + ")"
742 + " requires " + info.activityInfo.permission
743 + " due to receiver " + info.activityInfo.packageName
744 + "/" + info.activityInfo.name);
745 }
746 skip = true;
747 }
748 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
749 r.requiredPermission != null) {
750 try {
751 perm = AppGlobals.getPackageManager().
752 checkPermission(r.requiredPermission,
753 info.activityInfo.applicationInfo.packageName);
754 } catch (RemoteException e) {
755 perm = PackageManager.PERMISSION_DENIED;
756 }
757 if (perm != PackageManager.PERMISSION_GRANTED) {
758 Slog.w(TAG, "Permission Denial: receiving "
759 + r.intent + " to "
760 + info.activityInfo.applicationInfo.packageName
761 + " requires " + r.requiredPermission
762 + " due to sender " + r.callerPackage
763 + " (uid " + r.callingUid + ")");
764 skip = true;
765 }
766 }
767 if (r.curApp != null && r.curApp.crashing) {
768 // If the target process is crashing, just skip it.
769 if (DEBUG_BROADCAST) Slog.v(TAG,
770 "Skipping deliver ordered ["
771 + mQueueName + "] " + r + " to " + r.curApp
772 + ": process crashing");
773 skip = true;
774 }
775
776 if (skip) {
777 if (DEBUG_BROADCAST) Slog.v(TAG,
778 "Skipping delivery of ordered ["
779 + mQueueName + "] " + r + " for whatever reason");
780 r.receiver = null;
781 r.curFilter = null;
782 r.state = BroadcastRecord.IDLE;
783 scheduleBroadcastsLocked();
784 return;
785 }
786
787 r.state = BroadcastRecord.APP_RECEIVE;
788 String targetProcess = info.activityInfo.processName;
789 r.curComponent = new ComponentName(
790 info.activityInfo.applicationInfo.packageName,
791 info.activityInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -0700792 if (r.callingUid != Process.SYSTEM_UID) {
793 info.activityInfo = getActivityInfoForUser(info.activityInfo, UserId
794 .getUserId(r.callingUid));
795 }
Christopher Tatef46723b2012-01-26 14:19:24 -0800796 r.curReceiver = info.activityInfo;
Amith Yamasani742a6712011-05-04 14:49:28 -0700797 if (DEBUG_MU && r.callingUid > UserId.PER_USER_RANGE) {
798 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
799 + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
800 + info.activityInfo.applicationInfo.uid);
801 }
Christopher Tatef46723b2012-01-26 14:19:24 -0800802
803 // Broadcast is being executed, its package can't be stopped.
804 try {
805 AppGlobals.getPackageManager().setPackageStoppedState(
806 r.curComponent.getPackageName(), false);
807 } catch (RemoteException e) {
808 } catch (IllegalArgumentException e) {
809 Slog.w(TAG, "Failed trying to unstop package "
810 + r.curComponent.getPackageName() + ": " + e);
811 }
812
813 // Is this receiver's application already running?
814 ProcessRecord app = getProcessRecordLocked(targetProcess,
815 info.activityInfo.applicationInfo.uid);
816 if (app != null && app.thread != null) {
817 try {
818 app.addPackage(info.activityInfo.packageName);
819 processCurBroadcastLocked(r, app);
820 return;
821 } catch (RemoteException e) {
822 Slog.w(TAG, "Exception when sending broadcast to "
823 + r.curComponent, e);
824 }
825
826 // If a dead object exception was thrown -- fall through to
827 // restart the application.
828 }
829
830 // Not running -- get it started, to be executed when the app comes up.
831 if (DEBUG_BROADCAST) Slog.v(TAG,
832 "Need to start app ["
833 + mQueueName + "] " + targetProcess + " for broadcast " + r);
834 if ((r.curApp=startProcessLocked(targetProcess,
835 info.activityInfo.applicationInfo, true,
836 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
837 "broadcast", r.curComponent,
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800838 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false))
Christopher Tatef46723b2012-01-26 14:19:24 -0800839 == null) {
840 // Ah, this recipient is unavailable. Finish it if necessary,
841 // and mark the broadcast record as ready for the next.
842 Slog.w(TAG, "Unable to launch app "
843 + info.activityInfo.applicationInfo.packageName + "/"
844 + info.activityInfo.applicationInfo.uid + " for broadcast "
845 + r.intent + ": process is bad");
846 logBroadcastReceiverDiscardLocked(r);
847 finishReceiverLocked(r, r.resultCode, r.resultData,
848 r.resultExtras, r.resultAbort, true);
849 scheduleBroadcastsLocked();
850 r.state = BroadcastRecord.IDLE;
851 return;
852 }
853
854 mPendingBroadcast = r;
855 mPendingBroadcastRecvIndex = recIdx;
856 }
857 }
858
859 final void setBroadcastTimeoutLocked(long timeoutTime) {
860 if (! mPendingBroadcastTimeoutMessage) {
861 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
862 mHandler.sendMessageAtTime(msg, timeoutTime);
863 mPendingBroadcastTimeoutMessage = true;
864 }
865 }
866
867 final void cancelBroadcastTimeoutLocked() {
868 if (mPendingBroadcastTimeoutMessage) {
869 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
870 mPendingBroadcastTimeoutMessage = false;
871 }
872 }
873
874 final void broadcastTimeoutLocked(boolean fromMsg) {
875 if (fromMsg) {
876 mPendingBroadcastTimeoutMessage = false;
877 }
878
879 if (mOrderedBroadcasts.size() == 0) {
880 return;
881 }
882
883 long now = SystemClock.uptimeMillis();
884 BroadcastRecord r = mOrderedBroadcasts.get(0);
885 if (fromMsg) {
886 if (mDidDexOpt) {
887 // Delay timeouts until dexopt finishes.
888 mDidDexOpt = false;
889 long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
890 setBroadcastTimeoutLocked(timeoutTime);
891 return;
892 }
893 if (! mProcessesReady) {
894 // Only process broadcast timeouts if the system is ready. That way
895 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
896 // to do heavy lifting for system up.
897 return;
898 }
899
900 long timeoutTime = r.receiverTime + mTimeoutPeriod;
901 if (timeoutTime > now) {
902 // We can observe premature timeouts because we do not cancel and reset the
903 // broadcast timeout message after each receiver finishes. Instead, we set up
904 // an initial timeout then kick it down the road a little further as needed
905 // when it expires.
906 if (DEBUG_BROADCAST) Slog.v(TAG,
907 "Premature timeout ["
908 + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
909 + timeoutTime);
910 setBroadcastTimeoutLocked(timeoutTime);
911 return;
912 }
913 }
914
915 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
916 + ", started " + (now - r.receiverTime) + "ms ago");
917 r.receiverTime = now;
918 r.anrCount++;
919
920 // Current receiver has passed its expiration date.
921 if (r.nextReceiver <= 0) {
922 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
923 return;
924 }
925
926 ProcessRecord app = null;
927 String anrMessage = null;
928
929 Object curReceiver = r.receivers.get(r.nextReceiver-1);
930 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
931 logBroadcastReceiverDiscardLocked(r);
932 if (curReceiver instanceof BroadcastFilter) {
933 BroadcastFilter bf = (BroadcastFilter)curReceiver;
934 if (bf.receiverList.pid != 0
935 && bf.receiverList.pid != MY_PID) {
936 synchronized (ActivityManagerService.this.mPidsSelfLocked) {
937 app = ActivityManagerService.this.mPidsSelfLocked.get(
938 bf.receiverList.pid);
939 }
940 }
941 } else {
942 app = r.curApp;
943 }
944
945 if (app != null) {
946 anrMessage = "Broadcast of " + r.intent.toString();
947 }
948
949 if (mPendingBroadcast == r) {
950 mPendingBroadcast = null;
951 }
952
953 // Move on to the next receiver.
954 finishReceiverLocked(r, r.resultCode, r.resultData,
955 r.resultExtras, r.resultAbort, true);
956 scheduleBroadcastsLocked();
957
958 if (anrMessage != null) {
959 // Post the ANR to the handler since we do not want to process ANRs while
960 // potentially holding our lock.
961 mHandler.post(new AppNotResponding(app, anrMessage));
962 }
963 }
964
965 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
966 if (r.callingUid < 0) {
967 // This was from a registerReceiver() call; ignore it.
968 return;
969 }
970 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
971 MAX_BROADCAST_HISTORY-1);
972 r.finishTime = SystemClock.uptimeMillis();
973 mBroadcastHistory[0] = r;
974 }
975
976 final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
977 if (r.nextReceiver > 0) {
978 Object curReceiver = r.receivers.get(r.nextReceiver-1);
979 if (curReceiver instanceof BroadcastFilter) {
980 BroadcastFilter bf = (BroadcastFilter) curReceiver;
981 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
982 System.identityHashCode(r),
983 r.intent.getAction(),
984 r.nextReceiver - 1,
985 System.identityHashCode(bf));
986 } else {
987 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
988 System.identityHashCode(r),
989 r.intent.getAction(),
990 r.nextReceiver - 1,
991 ((ResolveInfo)curReceiver).toString());
992 }
993 } else {
994 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
995 + r);
996 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
997 System.identityHashCode(r),
998 r.intent.getAction(),
999 r.nextReceiver,
1000 "NONE");
1001 }
1002 }
1003
1004 final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
1005 int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
1006 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
1007 || mPendingBroadcast != null) {
1008 boolean printed = false;
1009 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
1010 BroadcastRecord br = mParallelBroadcasts.get(i);
1011 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1012 continue;
1013 }
1014 if (!printed) {
1015 if (needSep) {
1016 pw.println();
1017 needSep = false;
1018 }
1019 printed = true;
1020 pw.println(" Active broadcasts [" + mQueueName + "]:");
1021 }
1022 pw.println(" Broadcast #" + i + ":");
1023 br.dump(pw, " ");
1024 }
1025 printed = false;
1026 needSep = true;
1027 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
1028 BroadcastRecord br = mOrderedBroadcasts.get(i);
1029 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1030 continue;
1031 }
1032 if (!printed) {
1033 if (needSep) {
1034 pw.println();
1035 }
1036 needSep = true;
1037 pw.println(" Active ordered broadcasts [" + mQueueName + "]:");
1038 }
1039 pw.println(" Ordered Broadcast #" + i + ":");
1040 mOrderedBroadcasts.get(i).dump(pw, " ");
1041 }
1042 if (dumpPackage == null || (mPendingBroadcast != null
1043 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
1044 if (needSep) {
1045 pw.println();
1046 }
1047 pw.println(" Pending broadcast [" + mQueueName + "]:");
1048 if (mPendingBroadcast != null) {
1049 mPendingBroadcast.dump(pw, " ");
1050 } else {
1051 pw.println(" (null)");
1052 }
1053 needSep = true;
1054 }
1055 }
1056
1057 boolean printed = false;
1058 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
1059 BroadcastRecord r = mBroadcastHistory[i];
1060 if (r == null) {
1061 break;
1062 }
1063 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
1064 continue;
1065 }
1066 if (!printed) {
1067 if (needSep) {
1068 pw.println();
1069 }
1070 needSep = true;
1071 pw.println(" Historical broadcasts [" + mQueueName + "]:");
1072 printed = true;
1073 }
1074 if (dumpAll) {
1075 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
1076 r.dump(pw, " ");
1077 } else {
1078 if (i >= 50) {
1079 pw.println(" ...");
1080 break;
1081 }
1082 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
1083 }
1084 }
1085
1086 return needSep;
1087 }
1088 }
1089
1090 final BroadcastQueue mFgBroadcastQueue = new BroadcastQueue("foreground", BROADCAST_FG_TIMEOUT);
1091 final BroadcastQueue mBgBroadcastQueue = new BroadcastQueue("background", BROADCAST_BG_TIMEOUT);
1092 // Convenient for easy iteration over the queues. Foreground is first
1093 // so that dispatch of foreground broadcasts gets precedence.
1094 final BroadcastQueue[] mBroadcastQueues = { mFgBroadcastQueue, mBgBroadcastQueue };
1095
1096 BroadcastQueue broadcastQueueForIntent(Intent intent) {
1097 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
1098 if (DEBUG_BACKGROUND_BROADCAST) {
1099 Slog.i(TAG, "Broadcast intent " + intent + " on "
1100 + (isFg ? "foreground" : "background")
1101 + " queue");
1102 }
1103 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
1104 }
1105
1106 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
1107 for (BroadcastQueue queue : mBroadcastQueues) {
1108 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
1109 if (r != null) {
1110 return r;
1111 }
1112 }
1113 return null;
1114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115
1116 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 * Activity we have told the window manager to have key focus.
1118 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001119 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001120 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 * List of intents that were used to start the most recent tasks.
1122 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07001123 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124
1125 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -07001126 * Process management.
1127 */
1128 final ProcessList mProcessList = new ProcessList();
1129
1130 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 * All of the applications we currently have running organized by name.
1132 * The keys are strings of the application package name (as
1133 * returned by the package manager), and the keys are ApplicationRecord
1134 * objects.
1135 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07001136 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137
1138 /**
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001139 * The currently running isolated processes.
1140 */
1141 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
1142
1143 /**
1144 * Counter for assigning isolated process uids, to avoid frequently reusing the
1145 * same ones.
1146 */
1147 int mNextIsolatedProcessUid = 0;
1148
1149 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -07001150 * The currently running heavy-weight process, if any.
1151 */
1152 ProcessRecord mHeavyWeightProcess = null;
1153
1154 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 * The last time that various processes have crashed.
1156 */
1157 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
1158
1159 /**
1160 * Set of applications that we consider to be bad, and will reject
1161 * incoming broadcasts from (which the user has no control over).
1162 * Processes are added to this set when they have crashed twice within
1163 * a minimum amount of time; they are removed from it when they are
1164 * later restarted (hopefully due to some user action). The value is the
1165 * time it was added to the list.
1166 */
1167 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
1168
1169 /**
1170 * All of the processes we currently have running organized by pid.
1171 * The keys are the pid running the application.
1172 *
1173 * <p>NOTE: This object is protected by its own lock, NOT the global
1174 * activity manager lock!
1175 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07001176 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177
1178 /**
1179 * All of the processes that have been forced to be foreground. The key
1180 * is the pid of the caller who requested it (we hold a death
1181 * link on it).
1182 */
1183 abstract class ForegroundToken implements IBinder.DeathRecipient {
1184 int pid;
1185 IBinder token;
1186 }
1187 final SparseArray<ForegroundToken> mForegroundProcesses
1188 = new SparseArray<ForegroundToken>();
1189
1190 /**
1191 * List of records for processes that someone had tried to start before the
1192 * system was ready. We don't start them at that point, but ensure they
1193 * are started by the time booting is complete.
1194 */
1195 final ArrayList<ProcessRecord> mProcessesOnHold
1196 = new ArrayList<ProcessRecord>();
1197
1198 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 * List of persistent applications that are in the process
1200 * of being started.
1201 */
1202 final ArrayList<ProcessRecord> mPersistentStartingProcesses
1203 = new ArrayList<ProcessRecord>();
1204
1205 /**
1206 * Processes that are being forcibly torn down.
1207 */
1208 final ArrayList<ProcessRecord> mRemovedProcesses
1209 = new ArrayList<ProcessRecord>();
1210
1211 /**
1212 * List of running applications, sorted by recent usage.
1213 * The first entry in the list is the least recently used.
1214 * It contains ApplicationRecord objects. This list does NOT include
1215 * any persistent application records (since we never want to exit them).
1216 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001217 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 = new ArrayList<ProcessRecord>();
1219
1220 /**
1221 * List of processes that should gc as soon as things are idle.
1222 */
1223 final ArrayList<ProcessRecord> mProcessesToGc
1224 = new ArrayList<ProcessRecord>();
1225
1226 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -08001227 * This is the process holding what we currently consider to be
1228 * the "home" activity.
1229 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001230 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -08001231
1232 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -07001233 * This is the process holding the activity the user last visited that
1234 * is in a different process from the one they are currently in.
1235 */
1236 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -08001237
1238 /**
1239 * The time at which the previous process was last visible.
1240 */
1241 long mPreviousProcessVisibleTime;
1242
Dianne Hackbornf35fe232011-11-01 19:25:20 -07001243 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001244 * Packages that the user has asked to have run in screen size
1245 * compatibility mode instead of filling the screen.
1246 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001247 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001248
1249 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 * Set of PendingResultRecord objects that are currently active.
1251 */
1252 final HashSet mPendingResultRecords = new HashSet();
1253
1254 /**
1255 * Set of IntentSenderRecord objects that are currently active.
1256 */
1257 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1258 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1259
1260 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08001261 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07001262 * already logged DropBox entries for. Guarded by itself. If
1263 * something (rogue user app) forces this over
1264 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1265 */
1266 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1267 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1268
1269 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07001270 * Strict Mode background batched logging state.
1271 *
1272 * The string buffer is guarded by itself, and its lock is also
1273 * used to determine if another batched write is already
1274 * in-flight.
1275 */
1276 private final StringBuilder mStrictModeBuffer = new StringBuilder();
1277
1278 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 * Keeps track of all IIntentReceivers that have been registered for
1280 * broadcasts. Hash keys are the receiver IBinder, hash value is
1281 * a ReceiverList.
1282 */
1283 final HashMap mRegisteredReceivers = new HashMap();
1284
1285 /**
1286 * Resolver for broadcast intents to registered receivers.
1287 * Holds BroadcastFilter (subclass of IntentFilter).
1288 */
1289 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1290 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1291 @Override
1292 protected boolean allowFilterResult(
1293 BroadcastFilter filter, List<BroadcastFilter> dest) {
1294 IBinder target = filter.receiverList.receiver.asBinder();
1295 for (int i=dest.size()-1; i>=0; i--) {
1296 if (dest.get(i).receiverList.receiver.asBinder() == target) {
1297 return false;
1298 }
1299 }
1300 return true;
1301 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001302
1303 @Override
1304 protected String packageForFilter(BroadcastFilter filter) {
1305 return filter.packageName;
1306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 };
1308
1309 /**
1310 * State of all active sticky broadcasts. Keys are the action of the
1311 * sticky Intent, values are an ArrayList of all broadcasted intents with
1312 * that action (which should usually be one).
1313 */
1314 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
1315 new HashMap<String, ArrayList<Intent>>();
1316
Amith Yamasani742a6712011-05-04 14:49:28 -07001317 final ServiceMap mServiceMap = new ServiceMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318
1319 /**
1320 * All currently bound service connections. Keys are the IBinder of
1321 * the client's IServiceConnection.
1322 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07001323 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
1324 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325
1326 /**
1327 * List of services that we have been asked to start,
1328 * but haven't yet been able to. It is used to hold start requests
1329 * while waiting for their corresponding application thread to get
1330 * going.
1331 */
1332 final ArrayList<ServiceRecord> mPendingServices
1333 = new ArrayList<ServiceRecord>();
1334
1335 /**
1336 * List of services that are scheduled to restart following a crash.
1337 */
1338 final ArrayList<ServiceRecord> mRestartingServices
1339 = new ArrayList<ServiceRecord>();
1340
1341 /**
1342 * List of services that are in the process of being stopped.
1343 */
1344 final ArrayList<ServiceRecord> mStoppingServices
1345 = new ArrayList<ServiceRecord>();
1346
1347 /**
Christopher Tate181fafa2009-05-14 11:12:14 -07001348 * Backup/restore process management
1349 */
1350 String mBackupAppName = null;
1351 BackupRecord mBackupTarget = null;
1352
1353 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 * List of PendingThumbnailsRecord objects of clients who are still
1355 * waiting to receive all of the thumbnails for a task.
1356 */
1357 final ArrayList mPendingThumbnails = new ArrayList();
1358
1359 /**
1360 * List of HistoryRecord objects that have been finished and must
1361 * still report back to a pending thumbnail receiver.
1362 */
1363 final ArrayList mCancelledThumbnails = new ArrayList();
1364
1365 /**
1366 * All of the currently running global content providers. Keys are a
1367 * string containing the provider name and values are a
1368 * ContentProviderRecord object containing the data about it. Note
1369 * that a single provider may be published under multiple names, so
1370 * there may be multiple entries here for a single one in mProvidersByClass.
1371 */
Dianne Hackborn860755f2010-06-03 18:47:52 -07001372 final HashMap<String, ContentProviderRecord> mProvidersByName
1373 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374
1375 /**
1376 * All of the currently running global content providers. Keys are a
1377 * string containing the provider's implementation class and values are a
1378 * ContentProviderRecord object containing the data about it.
1379 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07001380 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
1381 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382
Amith Yamasani742a6712011-05-04 14:49:28 -07001383 final ProviderMap mProviderMap = new ProviderMap();
1384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 /**
1386 * List of content providers who have clients waiting for them. The
1387 * application is currently being launched and the provider will be
1388 * removed from this list once it is published.
1389 */
Dianne Hackborn860755f2010-06-03 18:47:52 -07001390 final ArrayList<ContentProviderRecord> mLaunchingProviders
1391 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392
1393 /**
1394 * Global set of specific Uri permissions that have been granted.
1395 */
1396 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
1397 = new SparseArray<HashMap<Uri, UriPermission>>();
1398
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001399 CoreSettingsObserver mCoreSettingsObserver;
1400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401 /**
1402 * Thread-local storage used to carry caller permissions over through
1403 * indirect content-provider access.
1404 * @see #ActivityManagerService.openContentUri()
1405 */
1406 private class Identity {
1407 public int pid;
1408 public int uid;
1409
1410 Identity(int _pid, int _uid) {
1411 pid = _pid;
1412 uid = _uid;
1413 }
1414 }
Amith Yamasani742a6712011-05-04 14:49:28 -07001415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1417
1418 /**
1419 * All information we have collected about the runtime performance of
1420 * any user id that can impact battery performance.
1421 */
1422 final BatteryStatsService mBatteryStatsService;
1423
1424 /**
1425 * information about component usage
1426 */
1427 final UsageStatsService mUsageStatsService;
1428
1429 /**
1430 * Current configuration information. HistoryRecord objects are given
1431 * a reference to this object to indicate which configuration they are
1432 * currently running in, so this object must be kept immutable.
1433 */
1434 Configuration mConfiguration = new Configuration();
1435
1436 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001437 * Current sequencing integer of the configuration, for skipping old
1438 * configurations.
1439 */
1440 int mConfigurationSeq = 0;
1441
1442 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -07001443 * Hardware-reported OpenGLES version.
1444 */
1445 final int GL_ES_VERSION;
1446
1447 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 * List of initialization arguments to pass to all processes when binding applications to them.
1449 * For example, references to the commonly used services.
1450 */
1451 HashMap<String, IBinder> mAppBindArgs;
1452
1453 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001454 * Temporary to avoid allocations. Protected by main lock.
1455 */
1456 final StringBuilder mStringBuilder = new StringBuilder(256);
1457
1458 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 * Used to control how we initialize the service.
1460 */
1461 boolean mStartRunning = false;
1462 ComponentName mTopComponent;
1463 String mTopAction;
1464 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001465 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 boolean mSystemReady = false;
1467 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001468 boolean mWaitingUpdate = false;
1469 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001470 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -07001471 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472
1473 Context mContext;
1474
1475 int mFactoryTest;
1476
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001477 boolean mCheckedForSetup;
1478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001480 * The time at which we will allow normal application switches again,
1481 * after a call to {@link #stopAppSwitches()}.
1482 */
1483 long mAppSwitchesAllowedTime;
1484
1485 /**
1486 * This is set to true after the first switch after mAppSwitchesAllowedTime
1487 * is set; any switches after that will clear the time.
1488 */
1489 boolean mDidAppSwitch;
1490
1491 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -07001492 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001493 */
Dianne Hackborn287952c2010-09-22 22:34:31 -07001494 long mLastPowerCheckRealtime;
1495
1496 /**
1497 * Last time (in uptime) at which we checked for power usage.
1498 */
1499 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001500
1501 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 * Set while we are wanting to sleep, to prevent any
1503 * activities from being started/resumed.
1504 */
1505 boolean mSleeping = false;
1506
1507 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -07001508 * Set if we are shutting down the system, similar to sleeping.
1509 */
1510 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511
1512 /**
1513 * Task identifier that activities are currently being started
1514 * in. Incremented each time a new task is created.
1515 * todo: Replace this with a TokenSpace class that generates non-repeating
1516 * integers that won't wrap.
1517 */
1518 int mCurTask = 1;
1519
1520 /**
1521 * Current sequence id for oom_adj computation traversal.
1522 */
1523 int mAdjSeq = 0;
1524
1525 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -07001526 * Current sequence id for process LRU updating.
1527 */
1528 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529
1530 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -07001531 * Keep track of the number of service processes we last found, to
1532 * determine on the next iteration which should be B services.
1533 */
1534 int mNumServiceProcs = 0;
1535 int mNewNumServiceProcs = 0;
1536
1537 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 * System monitoring: number of processes that died since the last
1539 * N procs were started.
1540 */
1541 int[] mProcDeaths = new int[20];
1542
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001543 /**
1544 * This is set if we had to do a delayed dexopt of an app before launching
1545 * it, to increasing the ANR timeouts in that case.
1546 */
1547 boolean mDidDexOpt;
1548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 String mDebugApp = null;
1550 boolean mWaitForDebugger = false;
1551 boolean mDebugTransient = false;
1552 String mOrigDebugApp = null;
1553 boolean mOrigWaitForDebugger = false;
1554 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001555 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001556 String mProfileApp = null;
1557 ProcessRecord mProfileProc = null;
1558 String mProfileFile;
1559 ParcelFileDescriptor mProfileFd;
1560 int mProfileType = 0;
1561 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001563 final RemoteCallbackList<IActivityWatcher> mWatchers
1564 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -07001565
1566 final RemoteCallbackList<IProcessObserver> mProcessObservers
1567 = new RemoteCallbackList<IProcessObserver>();
1568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 /**
1570 * Callback of last caller to {@link #requestPss}.
1571 */
1572 Runnable mRequestPssCallback;
1573
1574 /**
1575 * Remaining processes for which we are waiting results from the last
1576 * call to {@link #requestPss}.
1577 */
1578 final ArrayList<ProcessRecord> mRequestPssList
1579 = new ArrayList<ProcessRecord>();
1580
1581 /**
1582 * Runtime statistics collection thread. This object's lock is used to
1583 * protect all related state.
1584 */
1585 final Thread mProcessStatsThread;
1586
1587 /**
1588 * Used to collect process stats when showing not responding dialog.
1589 * Protected by mProcessStatsThread.
1590 */
1591 final ProcessStats mProcessStats = new ProcessStats(
1592 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001593 final AtomicLong mLastCpuTime = new AtomicLong(0);
1594 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
1595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 long mLastWriteTime = 0;
1597
1598 /**
1599 * Set to true after the system has finished booting.
1600 */
1601 boolean mBooted = false;
1602
Dianne Hackborn7d608422011-08-07 16:24:18 -07001603 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001604 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605
1606 WindowManagerService mWindowManager;
1607
1608 static ActivityManagerService mSelf;
1609 static ActivityThread mSystemThread;
1610
1611 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1612 final ProcessRecord mApp;
1613 final int mPid;
1614 final IApplicationThread mAppThread;
1615
1616 AppDeathRecipient(ProcessRecord app, int pid,
1617 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001618 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001619 TAG, "New death recipient " + this
1620 + " for thread " + thread.asBinder());
1621 mApp = app;
1622 mPid = pid;
1623 mAppThread = thread;
1624 }
1625
1626 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001627 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 TAG, "Death received in " + this
1629 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 synchronized(ActivityManagerService.this) {
1631 appDiedLocked(mApp, mPid, mAppThread);
1632 }
1633 }
1634 }
1635
1636 static final int SHOW_ERROR_MSG = 1;
1637 static final int SHOW_NOT_RESPONDING_MSG = 2;
1638 static final int SHOW_FACTORY_ERROR_MSG = 3;
1639 static final int UPDATE_CONFIGURATION_MSG = 4;
1640 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1641 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1642 static final int BROADCAST_INTENT_MSG = 7;
1643 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001644 static final int SERVICE_TIMEOUT_MSG = 12;
1645 static final int UPDATE_TIME_ZONE = 13;
1646 static final int SHOW_UID_ERROR_MSG = 14;
1647 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001649 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001650 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001651 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001652 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1653 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001654 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001655 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001656 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001657 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001658 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001659 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
1660 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001661 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662
1663 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001664 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001665 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666
1667 final Handler mHandler = new Handler() {
1668 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001669 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001670 //}
1671
1672 public void handleMessage(Message msg) {
1673 switch (msg.what) {
1674 case SHOW_ERROR_MSG: {
1675 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 synchronized (ActivityManagerService.this) {
1677 ProcessRecord proc = (ProcessRecord)data.get("app");
1678 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001679 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 return;
1681 }
1682 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -07001683 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -08001684 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 d.show();
1686 proc.crashDialog = d;
1687 } else {
1688 // The device is asleep, so just pretend that the user
1689 // saw a crash dialog and hit "force quit".
1690 res.set(0);
1691 }
1692 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001693
1694 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 } break;
1696 case SHOW_NOT_RESPONDING_MSG: {
1697 synchronized (ActivityManagerService.this) {
1698 HashMap data = (HashMap) msg.obj;
1699 ProcessRecord proc = (ProcessRecord)data.get("app");
1700 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001701 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 return;
1703 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001704
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001705 Intent intent = new Intent("android.intent.action.ANR");
1706 if (!mProcessesReady) {
Christopher Tatef46723b2012-01-26 14:19:24 -08001707 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1708 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001709 }
1710 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001711 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001712 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
The Android Open Source Project4df24232009-03-05 14:34:35 -08001713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001715 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 d.show();
1717 proc.anrDialog = d;
1718 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001719
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001720 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001721 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001722 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1723 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1724 synchronized (ActivityManagerService.this) {
1725 ProcessRecord proc = (ProcessRecord) data.get("app");
1726 if (proc == null) {
1727 Slog.e(TAG, "App not found when showing strict mode dialog.");
1728 break;
1729 }
1730 if (proc.crashDialog != null) {
1731 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1732 return;
1733 }
1734 AppErrorResult res = (AppErrorResult) data.get("result");
1735 if (!mSleeping && !mShuttingDown) {
1736 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1737 d.show();
1738 proc.crashDialog = d;
1739 } else {
1740 // The device is asleep, so just pretend that the user
1741 // saw a crash dialog and hit "force quit".
1742 res.set(0);
1743 }
1744 }
1745 ensureBootCompleted();
1746 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 case SHOW_FACTORY_ERROR_MSG: {
1748 Dialog d = new FactoryErrorDialog(
1749 mContext, msg.getData().getCharSequence("msg"));
1750 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001751 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001752 } break;
1753 case UPDATE_CONFIGURATION_MSG: {
1754 final ContentResolver resolver = mContext.getContentResolver();
1755 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1756 } break;
1757 case GC_BACKGROUND_PROCESSES_MSG: {
1758 synchronized (ActivityManagerService.this) {
1759 performAppGcsIfAppropriateLocked();
1760 }
1761 } break;
1762 case WAIT_FOR_DEBUGGER_MSG: {
1763 synchronized (ActivityManagerService.this) {
1764 ProcessRecord app = (ProcessRecord)msg.obj;
1765 if (msg.arg1 != 0) {
1766 if (!app.waitedForDebugger) {
1767 Dialog d = new AppWaitingForDebuggerDialog(
1768 ActivityManagerService.this,
1769 mContext, app);
1770 app.waitDialog = d;
1771 app.waitedForDebugger = true;
1772 d.show();
1773 }
1774 } else {
1775 if (app.waitDialog != null) {
1776 app.waitDialog.dismiss();
1777 app.waitDialog = null;
1778 }
1779 }
1780 }
1781 } break;
1782 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 TAG, "Received BROADCAST_INTENT_MSG");
Christopher Tatef46723b2012-01-26 14:19:24 -08001785 BroadcastQueue queue = (BroadcastQueue) msg.obj;
1786 queue.processNextBroadcast(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 } break;
1788 case BROADCAST_TIMEOUT_MSG: {
Christopher Tatef46723b2012-01-26 14:19:24 -08001789 final BroadcastQueue queue = (BroadcastQueue) msg.obj;
Jeff Brown4d94a762010-09-23 11:33:28 -07001790 synchronized (ActivityManagerService.this) {
Christopher Tatef46723b2012-01-26 14:19:24 -08001791 queue.broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001795 if (mDidDexOpt) {
1796 mDidDexOpt = false;
1797 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1798 nmsg.obj = msg.obj;
1799 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1800 return;
1801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 serviceTimeout((ProcessRecord)msg.obj);
1803 } break;
1804 case UPDATE_TIME_ZONE: {
1805 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001806 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 if (r.thread != null) {
1809 try {
1810 r.thread.updateTimeZone();
1811 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001812 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001813 }
1814 }
1815 }
1816 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001817 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001818 case CLEAR_DNS_CACHE: {
1819 synchronized (ActivityManagerService.this) {
1820 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821 ProcessRecord r = mLruProcesses.get(i);
1822 if (r.thread != null) {
1823 try {
1824 r.thread.clearDnsCache();
1825 } catch (RemoteException ex) {
1826 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1827 }
1828 }
1829 }
1830 }
1831 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001832 case UPDATE_HTTP_PROXY: {
1833 ProxyProperties proxy = (ProxyProperties)msg.obj;
1834 String host = "";
1835 String port = "";
1836 String exclList = "";
1837 if (proxy != null) {
1838 host = proxy.getHost();
1839 port = Integer.toString(proxy.getPort());
1840 exclList = proxy.getExclusionList();
1841 }
1842 synchronized (ActivityManagerService.this) {
1843 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1844 ProcessRecord r = mLruProcesses.get(i);
1845 if (r.thread != null) {
1846 try {
1847 r.thread.setHttpProxy(host, port, exclList);
1848 } catch (RemoteException ex) {
1849 Slog.w(TAG, "Failed to update http proxy for: " +
1850 r.info.processName);
1851 }
1852 }
1853 }
1854 }
1855 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 case SHOW_UID_ERROR_MSG: {
1857 // XXX This is a temporary dialog, no need to localize.
1858 AlertDialog d = new BaseErrorDialog(mContext);
1859 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1860 d.setCancelable(false);
1861 d.setTitle("System UIDs Inconsistent");
1862 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 +02001863 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1865 mUidAlert = d;
1866 d.show();
1867 } break;
1868 case IM_FEELING_LUCKY_MSG: {
1869 if (mUidAlert != null) {
1870 mUidAlert.dismiss();
1871 mUidAlert = null;
1872 }
1873 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001875 if (mDidDexOpt) {
1876 mDidDexOpt = false;
1877 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1878 nmsg.obj = msg.obj;
1879 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1880 return;
1881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 ProcessRecord app = (ProcessRecord)msg.obj;
1883 synchronized (ActivityManagerService.this) {
1884 processStartTimedOutLocked(app);
1885 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001886 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001887 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1888 synchronized (ActivityManagerService.this) {
1889 doPendingActivityLaunchesLocked(true);
1890 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001891 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001892 case KILL_APPLICATION_MSG: {
1893 synchronized (ActivityManagerService.this) {
1894 int uid = msg.arg1;
1895 boolean restart = (msg.arg2 == 1);
1896 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001897 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001898 }
1899 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001900 case FINALIZE_PENDING_INTENT_MSG: {
1901 ((PendingIntentRecord)msg.obj).completeFinalize();
1902 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001903 case POST_HEAVY_NOTIFICATION_MSG: {
1904 INotificationManager inm = NotificationManager.getService();
1905 if (inm == null) {
1906 return;
1907 }
1908
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001909 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001910 ProcessRecord process = root.app;
1911 if (process == null) {
1912 return;
1913 }
1914
1915 try {
1916 Context context = mContext.createPackageContext(process.info.packageName, 0);
1917 String text = mContext.getString(R.string.heavy_weight_notification,
1918 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1919 Notification notification = new Notification();
1920 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1921 notification.when = 0;
1922 notification.flags = Notification.FLAG_ONGOING_EVENT;
1923 notification.tickerText = text;
1924 notification.defaults = 0; // please be quiet
1925 notification.sound = null;
1926 notification.vibrate = null;
1927 notification.setLatestEventInfo(context, text,
1928 mContext.getText(R.string.heavy_weight_notification_detail),
1929 PendingIntent.getActivity(mContext, 0, root.intent,
1930 PendingIntent.FLAG_CANCEL_CURRENT));
1931
1932 try {
1933 int[] outId = new int[1];
1934 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1935 notification, outId);
1936 } catch (RuntimeException e) {
1937 Slog.w(ActivityManagerService.TAG,
1938 "Error showing notification for heavy-weight app", e);
1939 } catch (RemoteException e) {
1940 }
1941 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001942 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001943 }
1944 } break;
1945 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1946 INotificationManager inm = NotificationManager.getService();
1947 if (inm == null) {
1948 return;
1949 }
1950 try {
1951 inm.cancelNotification("android",
1952 R.string.heavy_weight_notification);
1953 } catch (RuntimeException e) {
1954 Slog.w(ActivityManagerService.TAG,
1955 "Error canceling notification for service", e);
1956 } catch (RemoteException e) {
1957 }
1958 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001959 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1960 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001961 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001962 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001963 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1964 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001965 }
1966 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001967 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1968 synchronized (ActivityManagerService.this) {
1969 ActivityRecord ar = (ActivityRecord)msg.obj;
1970 if (mCompatModeDialog != null) {
1971 if (mCompatModeDialog.mAppInfo.packageName.equals(
1972 ar.info.applicationInfo.packageName)) {
1973 return;
1974 }
1975 mCompatModeDialog.dismiss();
1976 mCompatModeDialog = null;
1977 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001978 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001979 if (mCompatModePackages.getPackageAskCompatModeLocked(
1980 ar.packageName)) {
1981 int mode = mCompatModePackages.computeCompatModeLocked(
1982 ar.info.applicationInfo);
1983 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1984 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1985 mCompatModeDialog = new CompatModeDialog(
1986 ActivityManagerService.this, mContext,
1987 ar.info.applicationInfo);
1988 mCompatModeDialog.show();
1989 }
1990 }
1991 }
1992 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001993 break;
1994 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001995 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001996 final int pid = msg.arg1;
1997 final int uid = msg.arg2;
1998 final boolean foregroundActivities = (Boolean) msg.obj;
1999 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002000 break;
2001 }
2002 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07002003 final int pid = msg.arg1;
2004 final int uid = msg.arg2;
2005 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002006 break;
2007 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002008 case REPORT_MEM_USAGE: {
2009 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
2010 if (!isDebuggable) {
2011 return;
2012 }
2013 synchronized (ActivityManagerService.this) {
2014 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002015 if (now < (mLastMemUsageReportTime+5*60*1000)) {
2016 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002017 // avoid spamming.
2018 return;
2019 }
2020 mLastMemUsageReportTime = now;
2021 }
2022 Thread thread = new Thread() {
2023 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002024 StringBuilder dropBuilder = new StringBuilder(1024);
2025 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08002026 StringWriter oomSw = new StringWriter();
2027 PrintWriter oomPw = new PrintWriter(oomSw);
2028 StringWriter catSw = new StringWriter();
2029 PrintWriter catPw = new PrintWriter(catSw);
2030 String[] emptyArgs = new String[] { };
2031 StringBuilder tag = new StringBuilder(128);
2032 StringBuilder stack = new StringBuilder(128);
2033 tag.append("Low on memory -- ");
2034 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
2035 tag, stack);
2036 dropBuilder.append(stack);
2037 dropBuilder.append('\n');
2038 dropBuilder.append('\n');
2039 String oomString = oomSw.toString();
2040 dropBuilder.append(oomString);
2041 dropBuilder.append('\n');
2042 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002043 try {
2044 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
2045 "procrank", });
2046 final InputStreamReader converter = new InputStreamReader(
2047 proc.getInputStream());
2048 BufferedReader in = new BufferedReader(converter);
2049 String line;
2050 while (true) {
2051 line = in.readLine();
2052 if (line == null) {
2053 break;
2054 }
2055 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002056 logBuilder.append(line);
2057 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002058 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002059 dropBuilder.append(line);
2060 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002061 }
2062 converter.close();
2063 } catch (IOException e) {
2064 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002065 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08002066 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002067 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002068 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002069 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002070 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002071 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08002072 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002073 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08002074 addErrorToDropBox("lowmem", null, "system_server", null,
2075 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08002076 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002077 synchronized (ActivityManagerService.this) {
2078 long now = SystemClock.uptimeMillis();
2079 if (mLastMemUsageReportTime < now) {
2080 mLastMemUsageReportTime = now;
2081 }
2082 }
2083 }
2084 };
2085 thread.start();
2086 break;
2087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002088 }
2089 }
2090 };
2091
2092 public static void setSystemProcess() {
2093 try {
2094 ActivityManagerService m = mSelf;
2095
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002096 ServiceManager.addService("activity", m, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07002098 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08002099 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100 if (MONITOR_CPU_USAGE) {
2101 ServiceManager.addService("cpuinfo", new CpuBinder(m));
2102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 ServiceManager.addService("permission", new PermissionController(m));
2104
2105 ApplicationInfo info =
2106 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07002107 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07002108 mSystemThread.installSystemApplicationInfo(info);
2109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002110 synchronized (mSelf) {
2111 ProcessRecord app = mSelf.newProcessRecordLocked(
2112 mSystemThread.getApplicationThread(), info,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002113 info.processName, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002115 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07002116 app.maxAdj = ProcessList.SYSTEM_ADJ;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002117 mSelf.mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 synchronized (mSelf.mPidsSelfLocked) {
2119 mSelf.mPidsSelfLocked.put(app.pid, app);
2120 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002121 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 }
2123 } catch (PackageManager.NameNotFoundException e) {
2124 throw new RuntimeException(
2125 "Unable to find android system package", e);
2126 }
2127 }
2128
2129 public void setWindowManager(WindowManagerService wm) {
2130 mWindowManager = wm;
2131 }
2132
2133 public static final Context main(int factoryTest) {
2134 AThread thr = new AThread();
2135 thr.start();
2136
2137 synchronized (thr) {
2138 while (thr.mService == null) {
2139 try {
2140 thr.wait();
2141 } catch (InterruptedException e) {
2142 }
2143 }
2144 }
2145
2146 ActivityManagerService m = thr.mService;
2147 mSelf = m;
2148 ActivityThread at = ActivityThread.systemMain();
2149 mSystemThread = at;
2150 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08002151 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 m.mContext = context;
2153 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002154 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155
2156 m.mBatteryStatsService.publish(context);
2157 m.mUsageStatsService.publish(context);
2158
2159 synchronized (thr) {
2160 thr.mReady = true;
2161 thr.notifyAll();
2162 }
2163
2164 m.startRunning(null, null, null, null);
2165
2166 return context;
2167 }
2168
2169 public static ActivityManagerService self() {
2170 return mSelf;
2171 }
2172
2173 static class AThread extends Thread {
2174 ActivityManagerService mService;
2175 boolean mReady = false;
2176
2177 public AThread() {
2178 super("ActivityManager");
2179 }
2180
2181 public void run() {
2182 Looper.prepare();
2183
2184 android.os.Process.setThreadPriority(
2185 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07002186 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187
2188 ActivityManagerService m = new ActivityManagerService();
2189
2190 synchronized (this) {
2191 mService = m;
2192 notifyAll();
2193 }
2194
2195 synchronized (this) {
2196 while (!mReady) {
2197 try {
2198 wait();
2199 } catch (InterruptedException e) {
2200 }
2201 }
2202 }
2203
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07002204 // For debug builds, log event loop stalls to dropbox for analysis.
2205 if (StrictMode.conditionallyEnableDebugLogging()) {
2206 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
2207 }
2208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 Looper.loop();
2210 }
2211 }
2212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 static class MemBinder extends Binder {
2214 ActivityManagerService mActivityManagerService;
2215 MemBinder(ActivityManagerService activityManagerService) {
2216 mActivityManagerService = activityManagerService;
2217 }
2218
2219 @Override
2220 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002221 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2222 != PackageManager.PERMISSION_GRANTED) {
2223 pw.println("Permission Denial: can't dump meminfo from from pid="
2224 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2225 + " without permission " + android.Manifest.permission.DUMP);
2226 return;
2227 }
2228
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08002229 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08002230 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 }
2232 }
2233
Chet Haase9c1e23b2011-03-24 10:51:31 -07002234 static class GraphicsBinder extends Binder {
2235 ActivityManagerService mActivityManagerService;
2236 GraphicsBinder(ActivityManagerService activityManagerService) {
2237 mActivityManagerService = activityManagerService;
2238 }
2239
2240 @Override
2241 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002242 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2243 != PackageManager.PERMISSION_GRANTED) {
2244 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2245 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2246 + " without permission " + android.Manifest.permission.DUMP);
2247 return;
2248 }
2249
Dianne Hackborne17aeb32011-04-07 15:11:57 -07002250 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07002251 }
2252 }
2253
Jeff Brown6754ba22011-12-14 20:20:01 -08002254 static class DbBinder extends Binder {
2255 ActivityManagerService mActivityManagerService;
2256 DbBinder(ActivityManagerService activityManagerService) {
2257 mActivityManagerService = activityManagerService;
2258 }
2259
2260 @Override
2261 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2262 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2263 != PackageManager.PERMISSION_GRANTED) {
2264 pw.println("Permission Denial: can't dump dbinfo from from pid="
2265 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2266 + " without permission " + android.Manifest.permission.DUMP);
2267 return;
2268 }
2269
2270 mActivityManagerService.dumpDbInfo(fd, pw, args);
2271 }
2272 }
2273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 static class CpuBinder extends Binder {
2275 ActivityManagerService mActivityManagerService;
2276 CpuBinder(ActivityManagerService activityManagerService) {
2277 mActivityManagerService = activityManagerService;
2278 }
2279
2280 @Override
2281 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002282 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2283 != PackageManager.PERMISSION_GRANTED) {
2284 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2285 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2286 + " without permission " + android.Manifest.permission.DUMP);
2287 return;
2288 }
2289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002291 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
2292 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
2293 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 }
2295 }
2296 }
2297
2298 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002299 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07002300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 File dataDir = Environment.getDataDirectory();
2302 File systemDir = new File(dataDir, "system");
2303 systemDir.mkdirs();
2304 mBatteryStatsService = new BatteryStatsService(new File(
2305 systemDir, "batterystats.bin").toString());
2306 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002307 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07002308 mOnBattery = DEBUG_POWER ? true
2309 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002310 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002312 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07002313 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314
Jack Palevichb90d28c2009-07-22 15:35:24 -07002315 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2316 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08002318 mConfiguration.setToDefaults();
2319 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08002320 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 mProcessStats.init();
2322
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002323 mCompatModePackages = new CompatModePackages(this, systemDir);
2324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 // Add ourself to the Watchdog monitors.
2326 Watchdog.getInstance().addMonitor(this);
2327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 mProcessStatsThread = new Thread("ProcessStats") {
2329 public void run() {
2330 while (true) {
2331 try {
2332 try {
2333 synchronized(this) {
2334 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002335 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002337 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 // + ", write delay=" + nextWriteDelay);
2339 if (nextWriteDelay < nextCpuDelay) {
2340 nextCpuDelay = nextWriteDelay;
2341 }
2342 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002343 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 this.wait(nextCpuDelay);
2345 }
2346 }
2347 } catch (InterruptedException e) {
2348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 updateCpuStatsNow();
2350 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002351 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 }
2353 }
2354 }
2355 };
2356 mProcessStatsThread.start();
2357 }
2358
2359 @Override
2360 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2361 throws RemoteException {
2362 try {
2363 return super.onTransact(code, data, reply, flags);
2364 } catch (RuntimeException e) {
2365 // The activity manager only throws security exceptions, so let's
2366 // log all others.
2367 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002368 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 }
2370 throw e;
2371 }
2372 }
2373
2374 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002375 final long now = SystemClock.uptimeMillis();
2376 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2377 return;
2378 }
2379 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
2380 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 mProcessStatsThread.notify();
2382 }
2383 }
2384 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 void updateCpuStatsNow() {
2387 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002388 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 final long now = SystemClock.uptimeMillis();
2390 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002393 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2394 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 haveNewCpuStats = true;
2396 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002397 //Slog.i(TAG, mProcessStats.printCurrentState());
2398 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 // + mProcessStats.getTotalCpuPercent() + "%");
2400
Joe Onorato8a9b2202010-02-26 18:56:32 -08002401 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 if ("true".equals(SystemProperties.get("events.cpu"))) {
2403 int user = mProcessStats.getLastUserTime();
2404 int system = mProcessStats.getLastSystemTime();
2405 int iowait = mProcessStats.getLastIoWaitTime();
2406 int irq = mProcessStats.getLastIrqTime();
2407 int softIrq = mProcessStats.getLastSoftIrqTime();
2408 int idle = mProcessStats.getLastIdleTime();
2409
2410 int total = user + system + iowait + irq + softIrq + idle;
2411 if (total == 0) total = 1;
2412
Doug Zongker2bec3d42009-12-04 12:52:44 -08002413 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 ((user+system+iowait+irq+softIrq) * 100) / total,
2415 (user * 100) / total,
2416 (system * 100) / total,
2417 (iowait * 100) / total,
2418 (irq * 100) / total,
2419 (softIrq * 100) / total);
2420 }
2421 }
2422
Amith Yamasanie43530a2009-08-21 13:11:37 -07002423 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07002424 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002425 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 synchronized(mPidsSelfLocked) {
2427 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002428 if (mOnBattery) {
2429 int perc = bstats.startAddingCpuLocked();
2430 int totalUTime = 0;
2431 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07002432 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002434 ProcessStats.Stats st = mProcessStats.getStats(i);
2435 if (!st.working) {
2436 continue;
2437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002439 int otherUTime = (st.rel_utime*perc)/100;
2440 int otherSTime = (st.rel_stime*perc)/100;
2441 totalUTime += otherUTime;
2442 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 if (pr != null) {
2444 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002445 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2446 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002447 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002448 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002449 } else {
2450 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07002451 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002452 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002453 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2454 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002455 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 }
2458 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002459 bstats.finishAddingCpuLocked(perc, totalUTime,
2460 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 }
2462 }
2463 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2466 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002467 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 }
2469 }
2470 }
2471 }
2472
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002473 @Override
2474 public void batteryNeedsCpuUpdate() {
2475 updateCpuStatsNow();
2476 }
2477
2478 @Override
2479 public void batteryPowerChanged(boolean onBattery) {
2480 // When plugging in, update the CPU stats first before changing
2481 // the plug state.
2482 updateCpuStatsNow();
2483 synchronized (this) {
2484 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002485 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002486 }
2487 }
2488 }
2489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 /**
2491 * Initialize the application bind args. These are passed to each
2492 * process when the bindApplication() IPC is sent to the process. They're
2493 * lazily setup to make sure the services are running when they're asked for.
2494 */
2495 private HashMap<String, IBinder> getCommonServicesLocked() {
2496 if (mAppBindArgs == null) {
2497 mAppBindArgs = new HashMap<String, IBinder>();
2498
2499 // Setup the application init args
2500 mAppBindArgs.put("package", ServiceManager.getService("package"));
2501 mAppBindArgs.put("window", ServiceManager.getService("window"));
2502 mAppBindArgs.put(Context.ALARM_SERVICE,
2503 ServiceManager.getService(Context.ALARM_SERVICE));
2504 }
2505 return mAppBindArgs;
2506 }
2507
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002508 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 if (mFocusedActivity != r) {
2510 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002511 if (r != null) {
2512 mWindowManager.setFocusedApp(r.appToken, true);
2513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 }
2515 }
2516
Dianne Hackborn906497c2010-05-10 15:57:38 -07002517 private final void updateLruProcessInternalLocked(ProcessRecord app,
2518 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002520 int lrui = mLruProcesses.indexOf(app);
2521 if (lrui >= 0) mLruProcesses.remove(lrui);
2522
2523 int i = mLruProcesses.size()-1;
2524 int skipTop = 0;
2525
Dianne Hackborn906497c2010-05-10 15:57:38 -07002526 app.lruSeq = mLruSeq;
2527
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002528 // compute the new weight for this process.
2529 if (updateActivityTime) {
2530 app.lastActivityTime = SystemClock.uptimeMillis();
2531 }
2532 if (app.activities.size() > 0) {
2533 // If this process has activities, we more strongly want to keep
2534 // it around.
2535 app.lruWeight = app.lastActivityTime;
2536 } else if (app.pubProviders.size() > 0) {
2537 // If this process contains content providers, we want to keep
2538 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002539 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002540 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002541 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002542 } else {
2543 // If this process doesn't have activities, we less strongly
2544 // want to keep it around, and generally want to avoid getting
2545 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002546 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002547 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002548 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002549 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07002550
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002551 while (i >= 0) {
2552 ProcessRecord p = mLruProcesses.get(i);
2553 // If this app shouldn't be in front of the first N background
2554 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002555 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002556 skipTop--;
2557 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07002558 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002559 mLruProcesses.add(i+1, app);
2560 break;
2561 }
2562 i--;
2563 }
2564 if (i < 0) {
2565 mLruProcesses.add(0, app);
2566 }
2567
Dianne Hackborn906497c2010-05-10 15:57:38 -07002568 // If the app is currently using a content provider or service,
2569 // bump those processes as well.
2570 if (app.connections.size() > 0) {
2571 for (ConnectionRecord cr : app.connections) {
2572 if (cr.binding != null && cr.binding.service != null
2573 && cr.binding.service.app != null
2574 && cr.binding.service.app.lruSeq != mLruSeq) {
2575 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
2576 updateActivityTime, i+1);
2577 }
2578 }
2579 }
2580 if (app.conProviders.size() > 0) {
2581 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07002582 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
2583 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07002584 updateActivityTime, i+1);
2585 }
2586 }
2587 }
2588
Joe Onorato8a9b2202010-02-26 18:56:32 -08002589 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 if (oomAdj) {
2591 updateOomAdjLocked();
2592 }
2593 }
2594
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002595 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07002596 boolean oomAdj, boolean updateActivityTime) {
2597 mLruSeq++;
2598 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
2599 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002600
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002601 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 String processName, int uid) {
2603 if (uid == Process.SYSTEM_UID) {
2604 // The system gets to run in any process. If there are multiple
2605 // processes with the same uid, just pick the first (this
2606 // should never happen).
2607 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
2608 processName);
2609 return procs != null ? procs.valueAt(0) : null;
2610 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002611 // uid = applyUserId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 ProcessRecord proc = mProcessNames.get(processName, uid);
2613 return proc;
2614 }
2615
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002616 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002617 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07002618 try {
2619 if (pm.performDexOpt(packageName)) {
2620 mDidDexOpt = true;
2621 }
2622 } catch (RemoteException e) {
2623 }
2624 }
2625
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002626 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 int transit = mWindowManager.getPendingAppTransition();
2628 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2629 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
2630 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
2631 }
2632
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002633 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002635 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2636 boolean isolated) {
2637 ProcessRecord app;
2638 if (!isolated) {
2639 app = getProcessRecordLocked(processName, info.uid);
2640 } else {
2641 // If this is an isolated process, it can't re-use an existing process.
2642 app = null;
2643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 // We don't have to do anything more if:
2645 // (1) There is an existing application record; and
2646 // (2) The caller doesn't think it is dead, OR there is no thread
2647 // object attached to it so we know it couldn't have crashed; and
2648 // (3) There is a pid assigned to it, so it is either starting or
2649 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002650 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 + " app=" + app + " knownToBeDead=" + knownToBeDead
2652 + " thread=" + (app != null ? app.thread : null)
2653 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01002654 if (app != null && app.pid > 0) {
2655 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08002656 // We already have the app running, or are waiting for it to
2657 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002658 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002659 // If this is a new package in the process, add the package to the list
2660 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002661 return app;
2662 } else {
2663 // An application record is attached to a previous process,
2664 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002665 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002666 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 String hostingNameStr = hostingName != null
2671 ? hostingName.flattenToShortString() : null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002672
2673 if (!isolated) {
2674 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2675 // If we are in the background, then check to see if this process
2676 // is bad. If so, we will just silently fail.
2677 if (mBadProcesses.get(info.processName, info.uid) != null) {
2678 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2679 + "/" + info.processName);
2680 return null;
2681 }
2682 } else {
2683 // When the user is explicitly starting a process, then clear its
2684 // crash count so that we won't make it bad until they see at
2685 // least one crash dialog again, and make the process good again
2686 // if it had been bad.
2687 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002688 + "/" + info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002689 mProcessCrashTimes.remove(info.processName, info.uid);
2690 if (mBadProcesses.get(info.processName, info.uid) != null) {
2691 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
2692 info.processName);
2693 mBadProcesses.remove(info.processName, info.uid);
2694 if (app != null) {
2695 app.bad = false;
2696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 }
2698 }
2699 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002702 app = newProcessRecordLocked(null, info, processName, isolated);
2703 if (app == null) {
2704 Slog.w(TAG, "Failed making new process record for "
2705 + processName + "/" + info.uid + " isolated=" + isolated);
2706 return null;
2707 }
2708 mProcessNames.put(processName, app.uid, app);
2709 if (isolated) {
2710 mIsolatedProcesses.put(app.uid, app);
2711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 } else {
2713 // If this is a new package in the process, add the package to the list
2714 app.addPackage(info.packageName);
2715 }
2716
2717 // If the system is not ready yet, then hold off on starting this
2718 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002719 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002720 && !isAllowedWhileBooting(info)
2721 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 if (!mProcessesOnHold.contains(app)) {
2723 mProcessesOnHold.add(app);
2724 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002725 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 return app;
2727 }
2728
2729 startProcessLocked(app, hostingType, hostingNameStr);
2730 return (app.pid != 0) ? app : null;
2731 }
2732
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002733 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2734 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2735 }
2736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 private final void startProcessLocked(ProcessRecord app,
2738 String hostingType, String hostingNameStr) {
2739 if (app.pid > 0 && app.pid != MY_PID) {
2740 synchronized (mPidsSelfLocked) {
2741 mPidsSelfLocked.remove(app.pid);
2742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2743 }
2744 app.pid = 0;
2745 }
2746
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002747 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2748 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 mProcessesOnHold.remove(app);
2750
2751 updateCpuStats();
2752
2753 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2754 mProcDeaths[0] = 0;
2755
2756 try {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002757 int uid = app.uid;
Amith Yamasani742a6712011-05-04 14:49:28 -07002758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 int[] gids = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002760 if (!app.isolated) {
2761 try {
2762 gids = mContext.getPackageManager().getPackageGids(
2763 app.info.packageName);
2764 } catch (PackageManager.NameNotFoundException e) {
2765 Slog.w(TAG, "Unable to retrieve gids", e);
2766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 }
2768 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2769 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2770 && mTopComponent != null
2771 && app.processName.equals(mTopComponent.getPackageName())) {
2772 uid = 0;
2773 }
2774 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2775 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2776 uid = 0;
2777 }
2778 }
2779 int debugFlags = 0;
2780 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2781 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07002782 // Also turn on CheckJNI for debuggable apps. It's quite
2783 // awkward to turn on otherwise.
2784 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08002786 // Run the app in safe mode if its manifest requests so or the
2787 // system is booted in safe mode.
2788 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2789 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08002790 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2793 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2794 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07002795 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2796 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 if ("1".equals(SystemProperties.get("debug.assert"))) {
2799 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2800 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07002801
2802 // Start the process. It will either succeed and return a result containing
2803 // the PID of the new process, or else throw a RuntimeException.
2804 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07002805 app.processName, uid, uid, gids, debugFlags,
2806 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2809 synchronized (bs) {
2810 if (bs.isOnBattery()) {
2811 app.batteryStats.incStartsLocked();
2812 }
2813 }
2814
Jeff Brown3f9dd282011-07-08 20:02:19 -07002815 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 app.processName, hostingType,
2817 hostingNameStr != null ? hostingNameStr : "");
2818
2819 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002820 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 }
2822
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002823 StringBuilder buf = mStringBuilder;
2824 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 buf.append("Start proc ");
2826 buf.append(app.processName);
2827 buf.append(" for ");
2828 buf.append(hostingType);
2829 if (hostingNameStr != null) {
2830 buf.append(" ");
2831 buf.append(hostingNameStr);
2832 }
2833 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002834 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 buf.append(" uid=");
2836 buf.append(uid);
2837 buf.append(" gids={");
2838 if (gids != null) {
2839 for (int gi=0; gi<gids.length; gi++) {
2840 if (gi != 0) buf.append(", ");
2841 buf.append(gids[gi]);
2842
2843 }
2844 }
2845 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002846 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002847 app.pid = startResult.pid;
2848 app.usingWrapper = startResult.usingWrapper;
2849 app.removed = false;
2850 synchronized (mPidsSelfLocked) {
2851 this.mPidsSelfLocked.put(startResult.pid, app);
2852 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2853 msg.obj = app;
2854 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2855 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 }
2857 } catch (RuntimeException e) {
2858 // XXX do better error recovery.
2859 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002860 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002861 }
2862 }
2863
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002864 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 if (resumed) {
2866 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2867 } else {
2868 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2869 }
2870 }
2871
Amith Yamasani742a6712011-05-04 14:49:28 -07002872 boolean startHomeActivityLocked(int userId) {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002873 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2874 && mTopAction == null) {
2875 // We are running in factory test mode, but unable to find
2876 // the factory test app, so just sit around displaying the
2877 // error message and don't try to start anything.
2878 return false;
2879 }
2880 Intent intent = new Intent(
2881 mTopAction,
2882 mTopData != null ? Uri.parse(mTopData) : null);
2883 intent.setComponent(mTopComponent);
2884 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2885 intent.addCategory(Intent.CATEGORY_HOME);
2886 }
2887 ActivityInfo aInfo =
2888 intent.resolveActivityInfo(mContext.getPackageManager(),
2889 STOCK_PM_FLAGS);
2890 if (aInfo != null) {
2891 intent.setComponent(new ComponentName(
2892 aInfo.applicationInfo.packageName, aInfo.name));
2893 // Don't do this if the home app is currently being
2894 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002895 aInfo = new ActivityInfo(aInfo);
2896 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002897 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2898 aInfo.applicationInfo.uid);
2899 if (app == null || app.instrumentationClass == null) {
2900 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002901 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002902 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002903 }
2904 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002905
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002906 return true;
2907 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002908
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002909 /**
2910 * Starts the "new version setup screen" if appropriate.
2911 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002912 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002913 // Only do this once per boot.
2914 if (mCheckedForSetup) {
2915 return;
2916 }
2917
2918 // We will show this screen if the current one is a different
2919 // version than the last one shown, and we are not running in
2920 // low-level factory test mode.
2921 final ContentResolver resolver = mContext.getContentResolver();
2922 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2923 Settings.Secure.getInt(resolver,
2924 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2925 mCheckedForSetup = true;
2926
2927 // See if we should be showing the platform update setup UI.
2928 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2929 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2930 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2931
2932 // We don't allow third party apps to replace this.
2933 ResolveInfo ri = null;
2934 for (int i=0; ris != null && i<ris.size(); i++) {
2935 if ((ris.get(i).activityInfo.applicationInfo.flags
2936 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2937 ri = ris.get(i);
2938 break;
2939 }
2940 }
2941
2942 if (ri != null) {
2943 String vers = ri.activityInfo.metaData != null
2944 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2945 : null;
2946 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2947 vers = ri.activityInfo.applicationInfo.metaData.getString(
2948 Intent.METADATA_SETUP_VERSION);
2949 }
2950 String lastVers = Settings.Secure.getString(
2951 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2952 if (vers != null && !vers.equals(lastVers)) {
2953 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2954 intent.setComponent(new ComponentName(
2955 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002956 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002957 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002958 }
2959 }
2960 }
2961 }
2962
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002963 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002964 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002965 }
2966
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002967 void enforceNotIsolatedCaller(String caller) {
2968 if (UserId.isIsolated(Binder.getCallingUid())) {
2969 throw new SecurityException("Isolated process not allowed to call " + caller);
2970 }
2971 }
2972
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002973 public int getFrontActivityScreenCompatMode() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002974 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002975 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002976 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2977 }
2978 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002979
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002980 public void setFrontActivityScreenCompatMode(int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002981 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2982 "setFrontActivityScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002983 synchronized (this) {
2984 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2985 }
2986 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002987
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002988 public int getPackageScreenCompatMode(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002989 enforceNotIsolatedCaller("getPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002990 synchronized (this) {
2991 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2992 }
2993 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002994
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002995 public void setPackageScreenCompatMode(String packageName, int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002996 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2997 "setPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002998 synchronized (this) {
2999 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003000 }
3001 }
3002
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003003 public boolean getPackageAskScreenCompat(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003004 enforceNotIsolatedCaller("getPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003005 synchronized (this) {
3006 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3007 }
3008 }
3009
3010 public void setPackageAskScreenCompat(String packageName, boolean ask) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003011 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3012 "setPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003013 synchronized (this) {
3014 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3015 }
3016 }
3017
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003018 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003019 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003020
3021 final int identHash = System.identityHashCode(r);
3022 updateUsageStats(r, true);
3023
3024 int i = mWatchers.beginBroadcast();
3025 while (i > 0) {
3026 i--;
3027 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3028 if (w != null) {
3029 try {
3030 w.activityResuming(identHash);
3031 } catch (RemoteException e) {
3032 }
3033 }
3034 }
3035 mWatchers.finishBroadcast();
3036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037
Jeff Sharkeya4620792011-05-20 15:29:23 -07003038 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
3039 int i = mProcessObservers.beginBroadcast();
3040 while (i > 0) {
3041 i--;
3042 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3043 if (observer != null) {
3044 try {
3045 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
3046 } catch (RemoteException e) {
3047 }
3048 }
3049 }
3050 mProcessObservers.finishBroadcast();
3051 }
3052
3053 private void dispatchProcessDied(int pid, int uid) {
3054 int i = mProcessObservers.beginBroadcast();
3055 while (i > 0) {
3056 i--;
3057 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3058 if (observer != null) {
3059 try {
3060 observer.onProcessDied(pid, uid);
3061 } catch (RemoteException e) {
3062 }
3063 }
3064 }
3065 mProcessObservers.finishBroadcast();
3066 }
3067
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003068 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003069 final int N = mPendingActivityLaunches.size();
3070 if (N <= 0) {
3071 return;
3072 }
3073 for (int i=0; i<N; i++) {
3074 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003075 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003076 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3077 doResume && i == (N-1));
3078 }
3079 mPendingActivityLaunches.clear();
3080 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003081
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003082 public final int startActivity(IApplicationThread caller,
3083 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3084 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003085 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3086 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003087 enforceNotIsolatedCaller("startActivity");
Amith Yamasani742a6712011-05-04 14:49:28 -07003088 int userId = 0;
3089 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
3090 // Requesting home, set the identity to the current user
3091 // HACK!
3092 userId = mCurrentUserId;
3093 } else {
3094 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
3095 // the current user's userId
3096 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
3097 userId = 0;
3098 } else {
3099 userId = Binder.getOrigCallingUser();
3100 }
3101 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003102 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -07003103 grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded,
3104 debug, profileFile, profileFd, autoStopProfiler, null, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003105 }
3106
3107 public final WaitResult startActivityAndWait(IApplicationThread caller,
3108 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3109 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003110 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3111 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003112 enforceNotIsolatedCaller("startActivityAndWait");
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003113 WaitResult res = new WaitResult();
Amith Yamasani742a6712011-05-04 14:49:28 -07003114 int userId = Binder.getOrigCallingUser();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003115 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003116 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003117 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
Amith Yamasani742a6712011-05-04 14:49:28 -07003118 res, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003119 return res;
3120 }
3121
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003122 public final int startActivityWithConfig(IApplicationThread caller,
3123 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3124 int grantedMode, IBinder resultTo,
3125 String resultWho, int requestCode, boolean onlyIfNeeded,
3126 boolean debug, Configuration config) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003127 enforceNotIsolatedCaller("startActivityWithConfig");
Amith Yamasani742a6712011-05-04 14:49:28 -07003128 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003129 grantedUriPermissions, grantedMode, resultTo, resultWho,
Amith Yamasani742a6712011-05-04 14:49:28 -07003130 requestCode, onlyIfNeeded,
3131 debug, null, null, false, null, config, Binder.getOrigCallingUser());
3132 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003133 }
3134
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003135 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003136 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003137 IBinder resultTo, String resultWho, int requestCode,
3138 int flagsMask, int flagsValues) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003139 enforceNotIsolatedCaller("startActivityIntentSender");
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003140 // Refuse possible leaked file descriptors
3141 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3142 throw new IllegalArgumentException("File descriptors passed in Intent");
3143 }
3144
3145 IIntentSender sender = intent.getTarget();
3146 if (!(sender instanceof PendingIntentRecord)) {
3147 throw new IllegalArgumentException("Bad PendingIntent object");
3148 }
3149
3150 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003151
3152 synchronized (this) {
3153 // If this is coming from the currently resumed activity, it is
3154 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003155 if (mMainStack.mResumedActivity != null
3156 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003157 Binder.getCallingUid()) {
3158 mAppSwitchesAllowedTime = 0;
3159 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003160 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003161 int ret = pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003162 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
Amith Yamasani742a6712011-05-04 14:49:28 -07003163 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003164 }
3165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003166 public boolean startNextMatchingActivity(IBinder callingActivity,
3167 Intent intent) {
3168 // Refuse possible leaked file descriptors
3169 if (intent != null && intent.hasFileDescriptors() == true) {
3170 throw new IllegalArgumentException("File descriptors passed in Intent");
3171 }
3172
3173 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003174 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
3175 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 return false;
3177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 if (r.app == null || r.app.thread == null) {
3179 // The caller is not running... d'oh!
3180 return false;
3181 }
3182 intent = new Intent(intent);
3183 // The caller is not allowed to change the data.
3184 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3185 // And we are resetting to find the next component...
3186 intent.setComponent(null);
3187
3188 ActivityInfo aInfo = null;
3189 try {
3190 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003191 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003192 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07003193 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194
3195 // Look for the original activity in the list...
3196 final int N = resolves != null ? resolves.size() : 0;
3197 for (int i=0; i<N; i++) {
3198 ResolveInfo rInfo = resolves.get(i);
3199 if (rInfo.activityInfo.packageName.equals(r.packageName)
3200 && rInfo.activityInfo.name.equals(r.info.name)) {
3201 // We found the current one... the next matching is
3202 // after it.
3203 i++;
3204 if (i<N) {
3205 aInfo = resolves.get(i).activityInfo;
3206 }
3207 break;
3208 }
3209 }
3210 } catch (RemoteException e) {
3211 }
3212
3213 if (aInfo == null) {
3214 // Nobody who is next!
3215 return false;
3216 }
3217
3218 intent.setComponent(new ComponentName(
3219 aInfo.applicationInfo.packageName, aInfo.name));
3220 intent.setFlags(intent.getFlags()&~(
3221 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3222 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3223 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3224 Intent.FLAG_ACTIVITY_NEW_TASK));
3225
3226 // Okay now we need to start the new activity, replacing the
3227 // currently running activity. This is a little tricky because
3228 // we want to start the new one as if the current one is finished,
3229 // but not finish the current one first so that there is no flicker.
3230 // And thus...
3231 final boolean wasFinishing = r.finishing;
3232 r.finishing = true;
3233
3234 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003235 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003236 final String resultWho = r.resultWho;
3237 final int requestCode = r.requestCode;
3238 r.resultTo = null;
3239 if (resultTo != null) {
3240 resultTo.removeResultsLocked(r, resultWho, requestCode);
3241 }
3242
3243 final long origId = Binder.clearCallingIdentity();
3244 // XXX we are not dealing with propagating grantedUriPermissions...
3245 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003246 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003247 r.resolvedType, null, 0, aInfo,
3248 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003249 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003250 Binder.restoreCallingIdentity(origId);
3251
3252 r.finishing = wasFinishing;
3253 if (res != START_SUCCESS) {
3254 return false;
3255 }
3256 return true;
3257 }
3258 }
3259
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003260 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003261 Intent intent, String resolvedType, IBinder resultTo,
3262 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003263
3264 // This is so super not safe, that only the system (or okay root)
3265 // can do it.
Amith Yamasani742a6712011-05-04 14:49:28 -07003266 int userId = Binder.getOrigCallingUser();
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003267 final int callingUid = Binder.getCallingUid();
3268 if (callingUid != 0 && callingUid != Process.myUid()) {
3269 throw new SecurityException(
3270 "startActivityInPackage only available to the system");
3271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003272
Amith Yamasani742a6712011-05-04 14:49:28 -07003273 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003274 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
Amith Yamasani742a6712011-05-04 14:49:28 -07003275 null, null, false, null, null, userId);
3276 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003277 }
3278
3279 public final int startActivities(IApplicationThread caller,
3280 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003281 enforceNotIsolatedCaller("startActivities");
Amith Yamasani742a6712011-05-04 14:49:28 -07003282 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
3283 Binder.getOrigCallingUser());
3284 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003285 }
3286
3287 public final int startActivitiesInPackage(int uid,
3288 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
3289
3290 // This is so super not safe, that only the system (or okay root)
3291 // can do it.
3292 final int callingUid = Binder.getCallingUid();
3293 if (callingUid != 0 && callingUid != Process.myUid()) {
3294 throw new SecurityException(
3295 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003297 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
3298 UserId.getUserId(uid));
3299 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003300 }
3301
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003302 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08003304 // Quick case: check if the top-most recent task is the same.
3305 if (N > 0 && mRecentTasks.get(0) == task) {
3306 return;
3307 }
3308 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 for (int i=0; i<N; i++) {
3310 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07003311 if (task.userId == tr.userId
3312 && ((task.affinity != null && task.affinity.equals(tr.affinity))
3313 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003314 mRecentTasks.remove(i);
3315 i--;
3316 N--;
3317 if (task.intent == null) {
3318 // If the new recent task we are adding is not fully
3319 // specified, then replace it with the existing recent task.
3320 task = tr;
3321 }
3322 }
3323 }
3324 if (N >= MAX_RECENT_TASKS) {
3325 mRecentTasks.remove(N-1);
3326 }
3327 mRecentTasks.add(0, task);
3328 }
3329
3330 public void setRequestedOrientation(IBinder token,
3331 int requestedOrientation) {
3332 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003333 ActivityRecord r = mMainStack.isInStackLocked(token);
3334 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 return;
3336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003337 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003338 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003340 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003341 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003342 if (config != null) {
3343 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08003344 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003345 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 }
3347 }
3348 Binder.restoreCallingIdentity(origId);
3349 }
3350 }
3351
3352 public int getRequestedOrientation(IBinder token) {
3353 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003354 ActivityRecord r = mMainStack.isInStackLocked(token);
3355 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3357 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08003358 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003359 }
3360 }
3361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 /**
3363 * This is the internal entry point for handling Activity.finish().
3364 *
3365 * @param token The Binder token referencing the Activity we want to finish.
3366 * @param resultCode Result code, if any, from this Activity.
3367 * @param resultData Result data (Intent), if any, from this Activity.
3368 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11003369 * @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 -08003370 */
3371 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3372 // Refuse possible leaked file descriptors
3373 if (resultData != null && resultData.hasFileDescriptors() == true) {
3374 throw new IllegalArgumentException("File descriptors passed in Intent");
3375 }
3376
3377 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003378 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003380 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 if (next != null) {
3382 // ask watcher if this is allowed
3383 boolean resumeOK = true;
3384 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003385 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003387 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 }
3389
3390 if (!resumeOK) {
3391 return false;
3392 }
3393 }
3394 }
3395 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003396 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 resultData, "app-request");
3398 Binder.restoreCallingIdentity(origId);
3399 return res;
3400 }
3401 }
3402
Dianne Hackborn860755f2010-06-03 18:47:52 -07003403 public final void finishHeavyWeightApp() {
3404 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3405 != PackageManager.PERMISSION_GRANTED) {
3406 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3407 + Binder.getCallingPid()
3408 + ", uid=" + Binder.getCallingUid()
3409 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3410 Slog.w(TAG, msg);
3411 throw new SecurityException(msg);
3412 }
3413
3414 synchronized(this) {
3415 if (mHeavyWeightProcess == null) {
3416 return;
3417 }
3418
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003419 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07003420 mHeavyWeightProcess.activities);
3421 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003422 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003423 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003424 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003425 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003426 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07003427 null, "finish-heavy");
3428 }
3429 }
3430 }
3431
3432 mHeavyWeightProcess = null;
3433 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3434 }
3435 }
3436
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003437 public void crashApplication(int uid, int initialPid, String packageName,
3438 String message) {
3439 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3440 != PackageManager.PERMISSION_GRANTED) {
3441 String msg = "Permission Denial: crashApplication() from pid="
3442 + Binder.getCallingPid()
3443 + ", uid=" + Binder.getCallingUid()
3444 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3445 Slog.w(TAG, msg);
3446 throw new SecurityException(msg);
3447 }
3448
3449 synchronized(this) {
3450 ProcessRecord proc = null;
3451
3452 // Figure out which process to kill. We don't trust that initialPid
3453 // still has any relation to current pids, so must scan through the
3454 // list.
3455 synchronized (mPidsSelfLocked) {
3456 for (int i=0; i<mPidsSelfLocked.size(); i++) {
3457 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003458 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003459 continue;
3460 }
3461 if (p.pid == initialPid) {
3462 proc = p;
3463 break;
3464 }
3465 for (String str : p.pkgList) {
3466 if (str.equals(packageName)) {
3467 proc = p;
3468 }
3469 }
3470 }
3471 }
3472
3473 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07003474 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003475 + " initialPid=" + initialPid
3476 + " packageName=" + packageName);
3477 return;
3478 }
3479
3480 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07003481 if (proc.pid == Process.myPid()) {
3482 Log.w(TAG, "crashApplication: trying to crash self!");
3483 return;
3484 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003485 long ident = Binder.clearCallingIdentity();
3486 try {
3487 proc.thread.scheduleCrash(message);
3488 } catch (RemoteException e) {
3489 }
3490 Binder.restoreCallingIdentity(ident);
3491 }
3492 }
3493 }
3494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 public final void finishSubActivity(IBinder token, String resultWho,
3496 int requestCode) {
3497 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003498 ActivityRecord self = mMainStack.isInStackLocked(token);
3499 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 return;
3501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003502
3503 final long origId = Binder.clearCallingIdentity();
3504
3505 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003506 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3507 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003508 if (r.resultTo == self && r.requestCode == requestCode) {
3509 if ((r.resultWho == null && resultWho == null) ||
3510 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003511 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 Activity.RESULT_CANCELED, null, "request-sub");
3513 }
3514 }
3515 }
3516
3517 Binder.restoreCallingIdentity(origId);
3518 }
3519 }
3520
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003521 public boolean willActivityBeVisible(IBinder token) {
3522 synchronized(this) {
3523 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003524 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3525 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08003526 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003527 return true;
3528 }
3529 if (r.fullscreen && !r.finishing) {
3530 return false;
3531 }
3532 }
3533 return true;
3534 }
3535 }
3536
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003537 public void overridePendingTransition(IBinder token, String packageName,
3538 int enterAnim, int exitAnim) {
3539 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003540 ActivityRecord self = mMainStack.isInStackLocked(token);
3541 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003542 return;
3543 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003544
3545 final long origId = Binder.clearCallingIdentity();
3546
3547 if (self.state == ActivityState.RESUMED
3548 || self.state == ActivityState.PAUSING) {
3549 mWindowManager.overridePendingAppTransition(packageName,
3550 enterAnim, exitAnim);
3551 }
3552
3553 Binder.restoreCallingIdentity(origId);
3554 }
3555 }
3556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 * Main function for removing an existing process from the activity manager
3559 * as a result of that process going away. Clears out all connections
3560 * to the process.
3561 */
3562 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003563 boolean restarting, boolean allowRestart) {
3564 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003566 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 }
3568
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003569 if (mProfileProc == app) {
3570 clearProfilerLocked();
3571 }
3572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 // Just in case...
Dianne Hackborncbb722e2012-02-07 18:33:49 -08003574 mMainStack.appDiedLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575
3576 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003577 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003578
3579 boolean atTop = true;
3580 boolean hasVisibleActivities = false;
3581
3582 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003583 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003584 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 TAG, "Removing app " + app + " from history with " + i + " entries");
3586 while (i > 0) {
3587 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003588 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003589 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003590 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3591 if (r.app == app) {
3592 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003593 if (ActivityStack.DEBUG_ADD_REMOVE) {
3594 RuntimeException here = new RuntimeException("here");
3595 here.fillInStackTrace();
3596 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
3597 + ": haveState=" + r.haveState
3598 + " stateNotNeeded=" + r.stateNotNeeded
3599 + " finishing=" + r.finishing
3600 + " state=" + r.state, here);
3601 }
3602 if (!r.finishing) {
3603 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08003604 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3605 System.identityHashCode(r),
3606 r.task.taskId, r.shortComponentName,
3607 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003608 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003609 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003610 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003611 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003612 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003614 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003616 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617
3618 } else {
3619 // We have the current state for this activity, so
3620 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003621 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 TAG, "Keeping entry, setting app to null");
3623 if (r.visible) {
3624 hasVisibleActivities = true;
3625 }
3626 r.app = null;
3627 r.nowVisible = false;
3628 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003629 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
3630 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003631 r.icicle = null;
3632 }
3633 }
3634
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003635 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636 }
3637 atTop = false;
3638 }
3639
3640 app.activities.clear();
3641
3642 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003643 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 + " running instrumentation " + app.instrumentationClass);
3645 Bundle info = new Bundle();
3646 info.putString("shortMsg", "Process crashed.");
3647 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3648 }
3649
3650 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003651 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 // If there was nothing to resume, and we are not already
3653 // restarting this process, but there is a visible activity that
3654 // is hosted by the process... then make sure all visible
3655 // activities are running, taking care of restarting this
3656 // process.
3657 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003658 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 }
3660 }
3661 }
3662 }
3663
3664 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3665 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003667 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3668 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3670 return i;
3671 }
3672 }
3673 return -1;
3674 }
3675
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003676 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 IApplicationThread thread) {
3678 if (thread == null) {
3679 return null;
3680 }
3681
3682 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003683 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003686 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 IApplicationThread thread) {
3688
3689 mProcDeaths[0]++;
3690
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003691 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3692 synchronized (stats) {
3693 stats.noteProcessDiedLocked(app.info.uid, pid);
3694 }
3695
Magnus Edlund7bb25812010-02-24 15:45:06 +01003696 // Clean up already done if the process has been re-started.
3697 if (app.pid == pid && app.thread != null &&
3698 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07003699 if (!app.killedBackground) {
3700 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3701 + ") has died.");
3702 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08003703 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003704 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 TAG, "Dying app: " + app + ", pid: " + pid
3706 + ", thread: " + thread.asBinder());
3707 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003708 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709
3710 if (doLowMem) {
3711 // If there are no longer any background processes running,
3712 // and the app that died was not running instrumentation,
3713 // then tell everyone we are now low on memory.
3714 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003715 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3716 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07003717 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 haveBg = true;
3719 break;
3720 }
3721 }
3722
3723 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003724 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003725 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003726 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3727 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07003728 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003729 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3730 // The low memory report is overriding any current
3731 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003732 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07003733 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003734 rec.lastRequestedGc = 0;
3735 } else {
3736 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003738 rec.reportLowMemory = true;
3739 rec.lastLowMemory = now;
3740 mProcessesToGc.remove(rec);
3741 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 }
3743 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003744 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003745 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 }
3747 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003748 } else if (app.pid != pid) {
3749 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003750 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003751 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08003752 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003753 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003754 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 + thread.asBinder());
3756 }
3757 }
3758
Dan Egnor42471dd2010-01-07 17:25:22 -08003759 /**
3760 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003761 * @param clearTraces causes the dump file to be erased prior to the new
3762 * traces being written, if true; when false, the new traces will be
3763 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003764 * @param firstPids of dalvik VM processes to dump stack traces for first
3765 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08003766 * @return file containing stack traces, or null if no dump file is configured
3767 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003768 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3769 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003770 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3771 if (tracesPath == null || tracesPath.length() == 0) {
3772 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003774
3775 File tracesFile = new File(tracesPath);
3776 try {
3777 File tracesDir = tracesFile.getParentFile();
3778 if (!tracesDir.exists()) tracesFile.mkdirs();
3779 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3780
Christopher Tate6ee412d2010-05-28 12:01:56 -07003781 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003782 tracesFile.createNewFile();
3783 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3784 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003785 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003786 return null;
3787 }
3788
3789 // Use a FileObserver to detect when traces finish writing.
3790 // The order of traces is considered important to maintain for legibility.
3791 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3792 public synchronized void onEvent(int event, String path) { notify(); }
3793 };
3794
3795 try {
3796 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003797
3798 // First collect all of the stacks of the most important pids.
3799 try {
3800 int num = firstPids.size();
3801 for (int i = 0; i < num; i++) {
3802 synchronized (observer) {
3803 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3804 observer.wait(200); // Wait for write-close, give up after 200msec
3805 }
3806 }
3807 } catch (InterruptedException e) {
3808 Log.wtf(TAG, e);
3809 }
3810
3811 // Next measure CPU usage.
3812 if (processStats != null) {
3813 processStats.init();
3814 System.gc();
3815 processStats.update();
3816 try {
3817 synchronized (processStats) {
3818 processStats.wait(500); // measure over 1/2 second.
3819 }
3820 } catch (InterruptedException e) {
3821 }
3822 processStats.update();
3823
3824 // We'll take the stack crawls of just the top apps using CPU.
3825 final int N = processStats.countWorkingStats();
3826 int numProcs = 0;
3827 for (int i=0; i<N && numProcs<5; i++) {
3828 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3829 if (lastPids.indexOfKey(stats.pid) >= 0) {
3830 numProcs++;
3831 try {
3832 synchronized (observer) {
3833 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3834 observer.wait(200); // Wait for write-close, give up after 200msec
3835 }
3836 } catch (InterruptedException e) {
3837 Log.wtf(TAG, e);
3838 }
3839
3840 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003841 }
3842 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003843
3844 return tracesFile;
3845
Dan Egnor42471dd2010-01-07 17:25:22 -08003846 } finally {
3847 observer.stopWatching();
3848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 }
3850
Jeff Brown4d94a762010-09-23 11:33:28 -07003851 private final class AppNotResponding implements Runnable {
3852 private final ProcessRecord mApp;
3853 private final String mAnnotation;
3854
3855 public AppNotResponding(ProcessRecord app, String annotation) {
3856 mApp = app;
3857 mAnnotation = annotation;
3858 }
3859
3860 @Override
3861 public void run() {
3862 appNotResponding(mApp, null, null, mAnnotation);
3863 }
3864 }
3865
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003866 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3867 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003868 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3869 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3870
Dianne Hackborn287952c2010-09-22 22:34:31 -07003871 if (mController != null) {
3872 try {
3873 // 0 == continue, -1 = kill process immediately
3874 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3875 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3876 } catch (RemoteException e) {
3877 mController = null;
3878 }
3879 }
3880
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003881 long anrTime = SystemClock.uptimeMillis();
3882 if (MONITOR_CPU_USAGE) {
3883 updateCpuStatsNow();
3884 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003885
3886 synchronized (this) {
3887 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3888 if (mShuttingDown) {
3889 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3890 return;
3891 } else if (app.notResponding) {
3892 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3893 return;
3894 } else if (app.crashing) {
3895 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3896 return;
3897 }
3898
3899 // In case we come through here for the same app before completing
3900 // this one, mark as anring now so we will bail out.
3901 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003902
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003903 // Log the ANR to the event log.
3904 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3905 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003906
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003907 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003908 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003909
3910 int parentPid = app.pid;
3911 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003912 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003913
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003914 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003915
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003916 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3917 ProcessRecord r = mLruProcesses.get(i);
3918 if (r != null && r.thread != null) {
3919 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003920 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3921 if (r.persistent) {
3922 firstPids.add(pid);
3923 } else {
3924 lastPids.put(pid, Boolean.TRUE);
3925 }
3926 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003928 }
3929 }
3930
Dan Egnor42471dd2010-01-07 17:25:22 -08003931 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003932 StringBuilder info = mStringBuilder;
3933 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003934 info.append("ANR in ").append(app.processName);
3935 if (activity != null && activity.shortComponentName != null) {
3936 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003937 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003938 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003940 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003942 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003943 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945
Dianne Hackborn287952c2010-09-22 22:34:31 -07003946 final ProcessStats processStats = new ProcessStats(true);
3947
3948 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3949
Dan Egnor42471dd2010-01-07 17:25:22 -08003950 String cpuInfo = null;
3951 if (MONITOR_CPU_USAGE) {
3952 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003953 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003954 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003955 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003956 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003957 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003960 info.append(processStats.printCurrentState(anrTime));
3961
Joe Onorato8a9b2202010-02-26 18:56:32 -08003962 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003963 if (tracesFile == null) {
3964 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3965 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3966 }
3967
Jeff Sharkeya353d262011-10-28 11:12:06 -07003968 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3969 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003970
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003971 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003973 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3974 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003975 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003976 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3977 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 }
3979 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003980 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 }
3982 }
3983
Dan Egnor42471dd2010-01-07 17:25:22 -08003984 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3985 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3986 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003987
3988 synchronized (this) {
3989 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003990 Slog.w(TAG, "Killing " + app + ": background ANR");
3991 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3992 app.processName, app.setAdj, "background ANR");
3993 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003994 return;
3995 }
3996
3997 // Set the app's notResponding state, and look up the errorReportReceiver
3998 makeAppNotRespondingLocked(app,
3999 activity != null ? activity.shortComponentName : null,
4000 annotation != null ? "ANR " + annotation : "ANR",
4001 info.toString());
4002
4003 // Bring up the infamous App Not Responding dialog
4004 Message msg = Message.obtain();
4005 HashMap map = new HashMap();
4006 msg.what = SHOW_NOT_RESPONDING_MSG;
4007 msg.obj = map;
4008 map.put("app", app);
4009 if (activity != null) {
4010 map.put("activity", activity);
4011 }
4012
4013 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08004014 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 }
4016
Dianne Hackborn0dad3642010-09-09 21:25:35 -07004017 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4018 if (!mLaunchWarningShown) {
4019 mLaunchWarningShown = true;
4020 mHandler.post(new Runnable() {
4021 @Override
4022 public void run() {
4023 synchronized (ActivityManagerService.this) {
4024 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4025 d.show();
4026 mHandler.postDelayed(new Runnable() {
4027 @Override
4028 public void run() {
4029 synchronized (ActivityManagerService.this) {
4030 d.dismiss();
4031 mLaunchWarningShown = false;
4032 }
4033 }
4034 }, 4000);
4035 }
4036 }
4037 });
4038 }
4039 }
4040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 public boolean clearApplicationUserData(final String packageName,
Amith Yamasani742a6712011-05-04 14:49:28 -07004042 final IPackageDataObserver observer, final int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004043 enforceNotIsolatedCaller("clearApplicationUserData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004044 int uid = Binder.getCallingUid();
4045 int pid = Binder.getCallingPid();
4046 long callingId = Binder.clearCallingIdentity();
4047 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004048 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 int pkgUid = -1;
4050 synchronized(this) {
4051 try {
4052 pkgUid = pm.getPackageUid(packageName);
4053 } catch (RemoteException e) {
4054 }
4055 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004056 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 return false;
4058 }
4059 if (uid == pkgUid || checkComponentPermission(
4060 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004061 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004062 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004063 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 } else {
4065 throw new SecurityException(pid+" does not have permission:"+
4066 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4067 "for process:"+packageName);
4068 }
4069 }
4070
4071 try {
4072 //clear application user data
4073 pm.clearApplicationUserData(packageName, observer);
4074 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4075 Uri.fromParts("package", packageName, null));
4076 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004077 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07004078 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 } catch (RemoteException e) {
4080 }
4081 } finally {
4082 Binder.restoreCallingIdentity(callingId);
4083 }
4084 return true;
4085 }
4086
Dianne Hackborn03abb812010-01-04 18:43:19 -08004087 public void killBackgroundProcesses(final String packageName) {
4088 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4089 != PackageManager.PERMISSION_GRANTED &&
4090 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4091 != PackageManager.PERMISSION_GRANTED) {
4092 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 + Binder.getCallingPid()
4094 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08004095 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004096 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 throw new SecurityException(msg);
4098 }
4099
4100 long callingId = Binder.clearCallingIdentity();
4101 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004102 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103 int pkgUid = -1;
4104 synchronized(this) {
4105 try {
4106 pkgUid = pm.getPackageUid(packageName);
4107 } catch (RemoteException e) {
4108 }
4109 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004110 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 return;
4112 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004113 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004114 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4115 }
4116 } finally {
4117 Binder.restoreCallingIdentity(callingId);
4118 }
4119 }
4120
4121 public void killAllBackgroundProcesses() {
4122 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4123 != PackageManager.PERMISSION_GRANTED) {
4124 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4125 + Binder.getCallingPid()
4126 + ", uid=" + Binder.getCallingUid()
4127 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4128 Slog.w(TAG, msg);
4129 throw new SecurityException(msg);
4130 }
4131
4132 long callingId = Binder.clearCallingIdentity();
4133 try {
4134 synchronized(this) {
4135 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4136 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4137 final int NA = apps.size();
4138 for (int ia=0; ia<NA; ia++) {
4139 ProcessRecord app = apps.valueAt(ia);
4140 if (app.persistent) {
4141 // we don't kill persistent processes
4142 continue;
4143 }
4144 if (app.removed) {
4145 procs.add(app);
4146 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
4147 app.removed = true;
4148 procs.add(app);
4149 }
4150 }
4151 }
4152
4153 int N = procs.size();
4154 for (int i=0; i<N; i++) {
4155 removeProcessLocked(procs.get(i), false, true, "kill all background");
4156 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004157 }
4158 } finally {
4159 Binder.restoreCallingIdentity(callingId);
4160 }
4161 }
4162
4163 public void forceStopPackage(final String packageName) {
4164 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4165 != PackageManager.PERMISSION_GRANTED) {
4166 String msg = "Permission Denial: forceStopPackage() from pid="
4167 + Binder.getCallingPid()
4168 + ", uid=" + Binder.getCallingUid()
4169 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004170 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004171 throw new SecurityException(msg);
4172 }
Amith Yamasani742a6712011-05-04 14:49:28 -07004173 final int userId = Binder.getOrigCallingUser();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004174 long callingId = Binder.clearCallingIdentity();
4175 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004176 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004177 int pkgUid = -1;
4178 synchronized(this) {
4179 try {
4180 pkgUid = pm.getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07004181 // Convert the uid to the one for the calling user
4182 pkgUid = UserId.getUid(userId, pkgUid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004183 } catch (RemoteException e) {
4184 }
4185 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004186 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004187 return;
4188 }
4189 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004190 try {
4191 pm.setPackageStoppedState(packageName, true);
4192 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08004193 } catch (IllegalArgumentException e) {
4194 Slog.w(TAG, "Failed trying to unstop package "
4195 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 }
4198 } finally {
4199 Binder.restoreCallingIdentity(callingId);
4200 }
4201 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004202
4203 /*
4204 * The pkg name and uid have to be specified.
4205 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4206 */
4207 public void killApplicationWithUid(String pkg, int uid) {
4208 if (pkg == null) {
4209 return;
4210 }
4211 // Make sure the uid is valid.
4212 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004213 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004214 return;
4215 }
4216 int callerUid = Binder.getCallingUid();
4217 // Only the system server can kill an application
4218 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07004219 // Post an aysnc message to kill the application
4220 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4221 msg.arg1 = uid;
4222 msg.arg2 = 0;
4223 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07004224 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004225 } else {
4226 throw new SecurityException(callerUid + " cannot kill pkg: " +
4227 pkg);
4228 }
4229 }
4230
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004231 public void closeSystemDialogs(String reason) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004232 enforceNotIsolatedCaller("closeSystemDialogs");
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004233 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004234 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004235 if (reason != null) {
4236 intent.putExtra("reason", reason);
4237 }
4238
4239 final int uid = Binder.getCallingUid();
4240 final long origId = Binder.clearCallingIdentity();
4241 synchronized (this) {
4242 int i = mWatchers.beginBroadcast();
4243 while (i > 0) {
4244 i--;
4245 IActivityWatcher w = mWatchers.getBroadcastItem(i);
4246 if (w != null) {
4247 try {
4248 w.closingSystemDialogs(reason);
4249 } catch (RemoteException e) {
4250 }
4251 }
4252 }
4253 mWatchers.finishBroadcast();
4254
Dianne Hackbornffa42482009-09-23 22:20:11 -07004255 mWindowManager.closeSystemDialogs(reason);
4256
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004257 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
4258 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004259 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004260 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07004261 Activity.RESULT_CANCELED, null, "close-sys");
4262 }
4263 }
4264
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004265 broadcastIntentLocked(null, null, intent, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004266 null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004267 }
4268 Binder.restoreCallingIdentity(origId);
4269 }
4270
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004271 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004272 throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004273 enforceNotIsolatedCaller("getProcessMemoryInfo");
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004274 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4275 for (int i=pids.length-1; i>=0; i--) {
4276 infos[i] = new Debug.MemoryInfo();
4277 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004278 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004279 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004280 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07004281
Dianne Hackbornb437e092011-08-05 17:50:29 -07004282 public long[] getProcessPss(int[] pids) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004283 enforceNotIsolatedCaller("getProcessPss");
Dianne Hackbornb437e092011-08-05 17:50:29 -07004284 long[] pss = new long[pids.length];
4285 for (int i=pids.length-1; i>=0; i--) {
4286 pss[i] = Debug.getPss(pids[i]);
4287 }
4288 return pss;
4289 }
4290
Christopher Tate5e1ab332009-09-01 20:32:49 -07004291 public void killApplicationProcess(String processName, int uid) {
4292 if (processName == null) {
4293 return;
4294 }
4295
4296 int callerUid = Binder.getCallingUid();
4297 // Only the system server can kill an application
4298 if (callerUid == Process.SYSTEM_UID) {
4299 synchronized (this) {
4300 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07004301 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07004302 try {
4303 app.thread.scheduleSuicide();
4304 } catch (RemoteException e) {
4305 // If the other end already died, then our work here is done.
4306 }
4307 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004308 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07004309 + processName + " / " + uid);
4310 }
4311 }
4312 } else {
4313 throw new SecurityException(callerUid + " cannot kill app process: " +
4314 processName);
4315 }
4316 }
4317
Dianne Hackborn03abb812010-01-04 18:43:19 -08004318 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004319 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4321 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004322 if (!mProcessesReady) {
4323 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 intent.putExtra(Intent.EXTRA_UID, uid);
4326 broadcastIntentLocked(null, null, intent,
4327 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004328 false, false,
4329 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004330 }
4331
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004332 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004333 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004334 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004335 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336
Dianne Hackborn03abb812010-01-04 18:43:19 -08004337 // Remove all processes this package may have touched: all with the
4338 // same UID (except for the system or root user), and all whose name
4339 // matches the package name.
4340 final String procNamePrefix = packageName + ":";
4341 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4342 final int NA = apps.size();
4343 for (int ia=0; ia<NA; ia++) {
4344 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07004345 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07004346 // we don't kill persistent processes
4347 continue;
4348 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004349 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004350 if (doit) {
4351 procs.add(app);
4352 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004353 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
4354 || app.processName.equals(packageName)
4355 || app.processName.startsWith(procNamePrefix)) {
4356 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004357 if (!doit) {
4358 return true;
4359 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004360 app.removed = true;
4361 procs.add(app);
4362 }
4363 }
4364 }
4365 }
4366
4367 int N = procs.size();
4368 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004369 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004370 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004371 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08004372 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004373
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004374 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004375 boolean callerWillRestart, boolean purgeCache, boolean doit,
4376 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004377 int i;
4378 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 if (uid < 0) {
4381 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004382 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 } catch (RemoteException e) {
4384 }
4385 }
4386
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004387 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004388 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004389
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004390 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
4391 while (badApps.hasNext()) {
4392 SparseArray<Long> ba = badApps.next();
4393 if (ba.get(uid) != null) {
4394 badApps.remove();
4395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 }
4397 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004398
4399 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004400 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004402 TaskRecord lastTask = null;
4403 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004404 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004405 final boolean samePackage = r.packageName.equals(name);
4406 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07004407 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004408 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07004409 if (r.finishing) {
4410 // If this activity is just finishing, then it is not
4411 // interesting as far as something to stop.
4412 continue;
4413 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004414 return true;
4415 }
4416 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004417 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004418 if (samePackage) {
4419 if (r.app != null) {
4420 r.app.removed = true;
4421 }
4422 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004424 lastTask = r.task;
4425 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
4426 null, "force-stop")) {
4427 i--;
4428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004429 }
4430 }
4431
4432 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07004433 int userId = UserId.getUserId(uid);
4434 for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
Christopher Tate064d8422011-07-26 15:38:07 -07004435 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07004436 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004437 if (!doit) {
4438 return true;
4439 }
4440 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004441 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 if (service.app != null) {
4443 service.app.removed = true;
4444 }
4445 service.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004446 service.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 services.add(service);
4448 }
4449 }
4450
4451 N = services.size();
4452 for (i=0; i<N; i++) {
4453 bringDownServiceLocked(services.get(i), true);
4454 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07004455
4456 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4457 for (ContentProviderRecord provider : mProvidersByClass.values()) {
4458 if (provider.info.packageName.equals(name)
4459 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
4460 if (!doit) {
4461 return true;
4462 }
4463 didSomething = true;
4464 providers.add(provider);
4465 }
4466 }
4467
4468 N = providers.size();
4469 for (i=0; i<N; i++) {
4470 removeDyingProviderLocked(null, providers.get(i));
4471 }
4472
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004473 if (doit) {
4474 if (purgeCache) {
4475 AttributeCache ac = AttributeCache.instance();
4476 if (ac != null) {
4477 ac.removePackage(name);
4478 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004479 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004480 if (mBooted) {
4481 mMainStack.resumeTopActivityLocked(null);
4482 mMainStack.scheduleIdleLocked();
4483 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004484 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004485
4486 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004487 }
4488
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004489 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004490 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004492 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004493 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004494 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 + "/" + uid + ")");
4496
4497 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004498 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004499 if (mHeavyWeightProcess == app) {
4500 mHeavyWeightProcess = null;
4501 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4502 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 boolean needRestart = false;
4504 if (app.pid > 0 && app.pid != MY_PID) {
4505 int pid = app.pid;
4506 synchronized (mPidsSelfLocked) {
4507 mPidsSelfLocked.remove(pid);
4508 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4509 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004510 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004511 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004512 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004513 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004515 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004517 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004518 } else {
4519 needRestart = true;
4520 }
4521 }
4522 } else {
4523 mRemovedProcesses.add(app);
4524 }
4525
4526 return needRestart;
4527 }
4528
4529 private final void processStartTimedOutLocked(ProcessRecord app) {
4530 final int pid = app.pid;
4531 boolean gone = false;
4532 synchronized (mPidsSelfLocked) {
4533 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4534 if (knownApp != null && knownApp.thread == null) {
4535 mPidsSelfLocked.remove(pid);
4536 gone = true;
4537 }
4538 }
4539
4540 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004541 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004542 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004543 app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004544 mProcessNames.remove(app.processName, app.uid);
4545 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004546 if (mHeavyWeightProcess == app) {
4547 mHeavyWeightProcess = null;
4548 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4549 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004550 // Take care of any launching providers waiting for this process.
4551 checkAppInLaunchingProvidersLocked(app, true);
4552 // Take care of any services that are waiting for the process.
4553 for (int i=0; i<mPendingServices.size(); i++) {
4554 ServiceRecord sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004555 if ((app.uid == sr.appInfo.uid
4556 && app.processName.equals(sr.processName))
4557 || sr.isolatedProc == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004558 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004559 sr.isolatedProc = null;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004560 mPendingServices.remove(i);
4561 i--;
4562 bringDownServiceLocked(sr, true);
4563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004565 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4566 app.processName, app.setAdj, "start timeout");
4567 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07004568 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004569 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07004570 try {
4571 IBackupManager bm = IBackupManager.Stub.asInterface(
4572 ServiceManager.getService(Context.BACKUP_SERVICE));
4573 bm.agentDisconnected(app.info.packageName);
4574 } catch (RemoteException e) {
4575 // Can't happen; the backup manager is local
4576 }
4577 }
Christopher Tatef46723b2012-01-26 14:19:24 -08004578 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004579 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08004580 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004583 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 }
4585 }
4586
4587 private final boolean attachApplicationLocked(IApplicationThread thread,
4588 int pid) {
4589
4590 // Find the application record that is being attached... either via
4591 // the pid if we are running in multiple processes, or just pull the
4592 // next app record if we are emulating process with anonymous threads.
4593 ProcessRecord app;
4594 if (pid != MY_PID && pid >= 0) {
4595 synchronized (mPidsSelfLocked) {
4596 app = mPidsSelfLocked.get(pid);
4597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 } else {
4599 app = null;
4600 }
4601
4602 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004603 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004604 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08004605 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004607 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004608 } else {
4609 try {
4610 thread.scheduleExit();
4611 } catch (Exception e) {
4612 // Ignore exceptions.
4613 }
4614 }
4615 return false;
4616 }
4617
4618 // If this application record is still attached to a previous
4619 // process, clean it up now.
4620 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004621 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 }
4623
4624 // Tell the process all about itself.
4625
Joe Onorato8a9b2202010-02-26 18:56:32 -08004626 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 TAG, "Binding process pid " + pid + " to record " + app);
4628
4629 String processName = app.processName;
4630 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004631 AppDeathRecipient adr = new AppDeathRecipient(
4632 app, pid, thread);
4633 thread.asBinder().linkToDeath(adr, 0);
4634 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 } catch (RemoteException e) {
4636 app.resetPackageList();
4637 startProcessLocked(app, "link fail", processName);
4638 return false;
4639 }
4640
Doug Zongker2bec3d42009-12-04 12:52:44 -08004641 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642
4643 app.thread = thread;
4644 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08004645 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4646 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 app.forcingToForeground = null;
4648 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07004649 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 app.debugging = false;
4651
4652 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4653
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004654 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004655 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004657 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004658 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004659 }
4660
Joe Onorato8a9b2202010-02-26 18:56:32 -08004661 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 TAG, "New app record " + app
4663 + " thread=" + thread.asBinder() + " pid=" + pid);
4664 try {
4665 int testMode = IApplicationThread.DEBUG_OFF;
4666 if (mDebugApp != null && mDebugApp.equals(processName)) {
4667 testMode = mWaitForDebugger
4668 ? IApplicationThread.DEBUG_WAIT
4669 : IApplicationThread.DEBUG_ON;
4670 app.debugging = true;
4671 if (mDebugTransient) {
4672 mDebugApp = mOrigDebugApp;
4673 mWaitForDebugger = mOrigWaitForDebugger;
4674 }
4675 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004676 String profileFile = app.instrumentationProfileFile;
4677 ParcelFileDescriptor profileFd = null;
4678 boolean profileAutoStop = false;
4679 if (mProfileApp != null && mProfileApp.equals(processName)) {
4680 mProfileProc = app;
4681 profileFile = mProfileFile;
4682 profileFd = mProfileFd;
4683 profileAutoStop = mAutoStopProfiler;
4684 }
4685
Christopher Tate181fafa2009-05-14 11:12:14 -07004686 // If the app is being launched for restore or full backup, set it up specially
4687 boolean isRestrictedBackupMode = false;
4688 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4689 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004690 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004691 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4692 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004693
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004694 ensurePackageDexOpt(app.instrumentationInfo != null
4695 ? app.instrumentationInfo.packageName
4696 : app.info.packageName);
4697 if (app.instrumentationClass != null) {
4698 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004699 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004700 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004701 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004702 ApplicationInfo appInfo = app.instrumentationInfo != null
4703 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004704 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004705 if (profileFd != null) {
4706 profileFd = profileFd.dup();
4707 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004708 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004709 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004711 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004712 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004713 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004714 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004715 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004716 } catch (Exception e) {
4717 // todo: Yikes! What should we do? For now we will try to
4718 // start another process, but that could easily get us in
4719 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004720 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004721
4722 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004723 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004724 startProcessLocked(app, "bind fail", processName);
4725 return false;
4726 }
4727
4728 // Remove this record from the list of starting applications.
4729 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004730 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4731 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 mProcessesOnHold.remove(app);
4733
4734 boolean badApp = false;
4735 boolean didSomething = false;
4736
4737 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004738 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004739 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004740 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 && processName.equals(hr.processName)) {
4742 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004743 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 didSomething = true;
4745 }
4746 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004747 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 + hr.intent.getComponent().flattenToShortString(), e);
4749 badApp = true;
4750 }
4751 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004752 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 }
4754 }
4755
4756 // Find any services that should be running in this process...
4757 if (!badApp && mPendingServices.size() > 0) {
4758 ServiceRecord sr = null;
4759 try {
4760 for (int i=0; i<mPendingServices.size(); i++) {
4761 sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004762 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4763 || !processName.equals(sr.processName))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 continue;
4765 }
4766
4767 mPendingServices.remove(i);
4768 i--;
4769 realStartServiceLocked(sr, app);
4770 didSomething = true;
4771 }
4772 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004773 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004774 + sr.shortName, e);
4775 badApp = true;
4776 }
4777 }
4778
Christopher Tatef46723b2012-01-26 14:19:24 -08004779 // Check if a next-broadcast receiver is in this process...
4780 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004782 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004784 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004785 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 }
4787 }
4788
Christopher Tate181fafa2009-05-14 11:12:14 -07004789 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004790 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004791 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004792 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004793 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004794 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4795 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4796 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004797 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004798 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004799 e.printStackTrace();
4800 }
4801 }
4802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 if (badApp) {
4804 // todo: Also need to kill application to deal with all
4805 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004806 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 return false;
4808 }
4809
4810 if (!didSomething) {
4811 updateOomAdjLocked();
4812 }
4813
4814 return true;
4815 }
4816
4817 public final void attachApplication(IApplicationThread thread) {
4818 synchronized (this) {
4819 int callingPid = Binder.getCallingPid();
4820 final long origId = Binder.clearCallingIdentity();
4821 attachApplicationLocked(thread, callingPid);
4822 Binder.restoreCallingIdentity(origId);
4823 }
4824 }
4825
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004826 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004828 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4829 if (stopProfiling) {
4830 synchronized (this) {
4831 if (mProfileProc == r.app) {
4832 if (mProfileFd != null) {
4833 try {
4834 mProfileFd.close();
4835 } catch (IOException e) {
4836 }
4837 clearProfilerLocked();
4838 }
4839 }
4840 }
4841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 Binder.restoreCallingIdentity(origId);
4843 }
4844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004845 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004846 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004847 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 mWindowManager.enableScreenAfterBoot();
4849 }
4850
Dianne Hackborn661cd522011-08-22 00:26:20 -07004851 public void showBootMessage(final CharSequence msg, final boolean always) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004852 enforceNotIsolatedCaller("showBootMessage");
Dianne Hackborn661cd522011-08-22 00:26:20 -07004853 mWindowManager.showBootMessage(msg, always);
4854 }
4855
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004856 public void dismissKeyguardOnNextActivity() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004857 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004858 synchronized (this) {
4859 mMainStack.dismissKeyguardOnNextActivityLocked();
4860 }
4861 }
4862
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004863 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004864 IntentFilter pkgFilter = new IntentFilter();
4865 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4866 pkgFilter.addDataScheme("package");
4867 mContext.registerReceiver(new BroadcastReceiver() {
4868 @Override
4869 public void onReceive(Context context, Intent intent) {
4870 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4871 if (pkgs != null) {
4872 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004873 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004874 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004875 setResultCode(Activity.RESULT_OK);
4876 return;
4877 }
4878 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004879 }
4880 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004881 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004882 }, pkgFilter);
4883
4884 synchronized (this) {
4885 // Ensure that any processes we had put on hold are now started
4886 // up.
4887 final int NP = mProcessesOnHold.size();
4888 if (NP > 0) {
4889 ArrayList<ProcessRecord> procs =
4890 new ArrayList<ProcessRecord>(mProcessesOnHold);
4891 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004892 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4893 + procs.get(ip));
4894 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004895 }
4896 }
4897
4898 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004899 // Start looking for apps that are abusing wake locks.
4900 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004901 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004902 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004903 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004904 SystemProperties.set("dev.bootcomplete", "1");
Amith Yamasani742a6712011-05-04 14:49:28 -07004905 /* TODO: Send this to all users that are to be logged in on startup */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004906 broadcastIntentLocked(null, null,
4907 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4908 null, null, 0, null, null,
4909 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Amith Yamasani742a6712011-05-04 14:49:28 -07004910 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004911 }
4912 }
4913 }
4914
4915 final void ensureBootCompleted() {
4916 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004917 boolean enableScreen;
4918 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004919 booting = mBooting;
4920 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004921 enableScreen = !mBooted;
4922 mBooted = true;
4923 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004924
4925 if (booting) {
4926 finishBooting();
4927 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004928
4929 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004930 enableScreenAfterBoot();
4931 }
4932 }
4933
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004934 public final void activityPaused(IBinder token) {
4935 final long origId = Binder.clearCallingIdentity();
4936 mMainStack.activityPaused(token, false);
4937 Binder.restoreCallingIdentity(origId);
4938 }
4939
4940 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4941 CharSequence description) {
4942 if (localLOGV) Slog.v(
4943 TAG, "Activity stopped: token=" + token);
4944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 // Refuse possible leaked file descriptors
4946 if (icicle != null && icicle.hasFileDescriptors()) {
4947 throw new IllegalArgumentException("File descriptors passed in Bundle");
4948 }
4949
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004950 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951
4952 final long origId = Binder.clearCallingIdentity();
4953
4954 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004955 r = mMainStack.isInStackLocked(token);
4956 if (r != null) {
4957 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 }
4959 }
4960
4961 if (r != null) {
4962 sendPendingThumbnail(r, null, null, null, false);
4963 }
4964
4965 trimApplications();
4966
4967 Binder.restoreCallingIdentity(origId);
4968 }
4969
4970 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004971 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004972 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004973 }
4974
4975 public String getCallingPackage(IBinder token) {
4976 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004977 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004978 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004979 }
4980 }
4981
4982 public ComponentName getCallingActivity(IBinder token) {
4983 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004984 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 return r != null ? r.intent.getComponent() : null;
4986 }
4987 }
4988
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004989 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004990 ActivityRecord r = mMainStack.isInStackLocked(token);
4991 if (r == null) {
4992 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004994 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 }
4996
4997 public ComponentName getActivityClassForToken(IBinder token) {
4998 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004999 ActivityRecord r = mMainStack.isInStackLocked(token);
5000 if (r == null) {
5001 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005003 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005004 }
5005 }
5006
5007 public String getPackageForToken(IBinder token) {
5008 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005009 ActivityRecord r = mMainStack.isInStackLocked(token);
5010 if (r == null) {
5011 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005012 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005013 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005014 }
5015 }
5016
5017 public IIntentSender getIntentSender(int type,
5018 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005019 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005020 enforceNotIsolatedCaller("getIntentSender");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005021 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005022 if (intents != null) {
5023 if (intents.length < 1) {
5024 throw new IllegalArgumentException("Intents array length must be >= 1");
5025 }
5026 for (int i=0; i<intents.length; i++) {
5027 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07005028 if (intent != null) {
5029 if (intent.hasFileDescriptors()) {
5030 throw new IllegalArgumentException("File descriptors passed in Intent");
5031 }
5032 if (type == INTENT_SENDER_BROADCAST &&
5033 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5034 throw new IllegalArgumentException(
5035 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5036 }
5037 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005038 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005039 }
5040 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005041 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005042 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005043 }
5044 }
5045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005046 synchronized(this) {
5047 int callingUid = Binder.getCallingUid();
5048 try {
Jeff Brown10e89712011-07-08 18:52:57 -07005049 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005050 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005051 .getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07005052 if (UserId.getAppId(callingUid) != uid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 String msg = "Permission Denial: getIntentSender() from pid="
5054 + Binder.getCallingPid()
5055 + ", uid=" + Binder.getCallingUid()
5056 + ", (need uid=" + uid + ")"
5057 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005058 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059 throw new SecurityException(msg);
5060 }
5061 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005062
Amith Yamasani742a6712011-05-04 14:49:28 -07005063 if (DEBUG_MU)
5064 Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
5065 + Binder.getOrigCallingUid());
5066 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005067 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005069 } catch (RemoteException e) {
5070 throw new SecurityException(e);
5071 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005072 }
5073 }
5074
5075 IIntentSender getIntentSenderLocked(int type,
5076 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005077 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07005078 if (DEBUG_MU)
5079 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005080 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07005081 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005082 activity = mMainStack.isInStackLocked(token);
5083 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005084 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005086 if (activity.finishing) {
5087 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005088 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005089 }
5090
5091 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5092 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5093 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5094 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5095 |PendingIntent.FLAG_UPDATE_CURRENT);
5096
5097 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5098 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005099 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005100 WeakReference<PendingIntentRecord> ref;
5101 ref = mIntentSenderRecords.get(key);
5102 PendingIntentRecord rec = ref != null ? ref.get() : null;
5103 if (rec != null) {
5104 if (!cancelCurrent) {
5105 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005106 if (rec.key.requestIntent != null) {
5107 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
5108 }
5109 if (intents != null) {
5110 intents[intents.length-1] = rec.key.requestIntent;
5111 rec.key.allIntents = intents;
5112 rec.key.allResolvedTypes = resolvedTypes;
5113 } else {
5114 rec.key.allIntents = null;
5115 rec.key.allResolvedTypes = null;
5116 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005118 return rec;
5119 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005120 rec.canceled = true;
5121 mIntentSenderRecords.remove(key);
5122 }
5123 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 return rec;
5125 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005126 rec = new PendingIntentRecord(this, key, callingUid);
5127 mIntentSenderRecords.put(key, rec.ref);
5128 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5129 if (activity.pendingResults == null) {
5130 activity.pendingResults
5131 = new HashSet<WeakReference<PendingIntentRecord>>();
5132 }
5133 activity.pendingResults.add(rec.ref);
5134 }
5135 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005136 }
5137
5138 public void cancelIntentSender(IIntentSender sender) {
5139 if (!(sender instanceof PendingIntentRecord)) {
5140 return;
5141 }
5142 synchronized(this) {
5143 PendingIntentRecord rec = (PendingIntentRecord)sender;
5144 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005145 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005146 .getPackageUid(rec.key.packageName);
5147 if (uid != Binder.getCallingUid()) {
5148 String msg = "Permission Denial: cancelIntentSender() from pid="
5149 + Binder.getCallingPid()
5150 + ", uid=" + Binder.getCallingUid()
5151 + " is not allowed to cancel packges "
5152 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005153 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005154 throw new SecurityException(msg);
5155 }
5156 } catch (RemoteException e) {
5157 throw new SecurityException(e);
5158 }
5159 cancelIntentSenderLocked(rec, true);
5160 }
5161 }
5162
5163 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5164 rec.canceled = true;
5165 mIntentSenderRecords.remove(rec.key);
5166 if (cleanActivity && rec.key.activity != null) {
5167 rec.key.activity.pendingResults.remove(rec.ref);
5168 }
5169 }
5170
5171 public String getPackageForIntentSender(IIntentSender pendingResult) {
5172 if (!(pendingResult instanceof PendingIntentRecord)) {
5173 return null;
5174 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07005175 try {
5176 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5177 return res.key.packageName;
5178 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 }
5180 return null;
5181 }
5182
Dianne Hackborn6c418d52011-06-29 14:05:33 -07005183 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5184 if (!(pendingResult instanceof PendingIntentRecord)) {
5185 return false;
5186 }
5187 try {
5188 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5189 if (res.key.allIntents == null) {
5190 return false;
5191 }
5192 for (int i=0; i<res.key.allIntents.length; i++) {
5193 Intent intent = res.key.allIntents[i];
5194 if (intent.getPackage() != null && intent.getComponent() != null) {
5195 return false;
5196 }
5197 }
5198 return true;
5199 } catch (ClassCastException e) {
5200 }
5201 return false;
5202 }
5203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 public void setProcessLimit(int max) {
5205 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5206 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005207 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005208 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005209 mProcessLimitOverride = max;
5210 }
5211 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005212 }
5213
5214 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005215 synchronized (this) {
5216 return mProcessLimitOverride;
5217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 }
5219
5220 void foregroundTokenDied(ForegroundToken token) {
5221 synchronized (ActivityManagerService.this) {
5222 synchronized (mPidsSelfLocked) {
5223 ForegroundToken cur
5224 = mForegroundProcesses.get(token.pid);
5225 if (cur != token) {
5226 return;
5227 }
5228 mForegroundProcesses.remove(token.pid);
5229 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5230 if (pr == null) {
5231 return;
5232 }
5233 pr.forcingToForeground = null;
5234 pr.foregroundServices = false;
5235 }
5236 updateOomAdjLocked();
5237 }
5238 }
5239
5240 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5241 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5242 "setProcessForeground()");
5243 synchronized(this) {
5244 boolean changed = false;
5245
5246 synchronized (mPidsSelfLocked) {
5247 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005248 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005249 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 return;
5251 }
5252 ForegroundToken oldToken = mForegroundProcesses.get(pid);
5253 if (oldToken != null) {
5254 oldToken.token.unlinkToDeath(oldToken, 0);
5255 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005256 if (pr != null) {
5257 pr.forcingToForeground = null;
5258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 changed = true;
5260 }
5261 if (isForeground && token != null) {
5262 ForegroundToken newToken = new ForegroundToken() {
5263 public void binderDied() {
5264 foregroundTokenDied(this);
5265 }
5266 };
5267 newToken.pid = pid;
5268 newToken.token = token;
5269 try {
5270 token.linkToDeath(newToken, 0);
5271 mForegroundProcesses.put(pid, newToken);
5272 pr.forcingToForeground = token;
5273 changed = true;
5274 } catch (RemoteException e) {
5275 // If the process died while doing this, we will later
5276 // do the cleanup with the process death link.
5277 }
5278 }
5279 }
5280
5281 if (changed) {
5282 updateOomAdjLocked();
5283 }
5284 }
5285 }
5286
5287 // =========================================================
5288 // PERMISSIONS
5289 // =========================================================
5290
5291 static class PermissionController extends IPermissionController.Stub {
5292 ActivityManagerService mActivityManagerService;
5293 PermissionController(ActivityManagerService activityManagerService) {
5294 mActivityManagerService = activityManagerService;
5295 }
5296
5297 public boolean checkPermission(String permission, int pid, int uid) {
5298 return mActivityManagerService.checkPermission(permission, pid,
5299 uid) == PackageManager.PERMISSION_GRANTED;
5300 }
5301 }
5302
5303 /**
5304 * This can be called with or without the global lock held.
5305 */
5306 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005307 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005308 // We might be performing an operation on behalf of an indirect binder
5309 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
5310 // client identity accordingly before proceeding.
5311 Identity tlsIdentity = sCallerIdentity.get();
5312 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005313 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005314 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5315 uid = tlsIdentity.uid;
5316 pid = tlsIdentity.pid;
5317 }
5318
5319 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005320 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 return PackageManager.PERMISSION_GRANTED;
5322 }
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005323 // Isolated processes don't get any permissions.
5324 if (UserId.isIsolated(uid)) {
5325 return PackageManager.PERMISSION_DENIED;
5326 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005327 // If there is a uid that owns whatever is being accessed, it has
5328 // blanket access to it regardless of the permissions it requires.
Amith Yamasani742a6712011-05-04 14:49:28 -07005329 if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005330 return PackageManager.PERMISSION_GRANTED;
5331 }
5332 // If the target is not exported, then nobody else can get to it.
5333 if (!exported) {
5334 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335 return PackageManager.PERMISSION_DENIED;
5336 }
5337 if (permission == null) {
5338 return PackageManager.PERMISSION_GRANTED;
5339 }
5340 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005341 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 .checkUidPermission(permission, uid);
5343 } catch (RemoteException e) {
5344 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08005345 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005346 }
5347 return PackageManager.PERMISSION_DENIED;
5348 }
5349
5350 /**
5351 * As the only public entry point for permissions checking, this method
5352 * can enforce the semantic that requesting a check on a null global
5353 * permission is automatically denied. (Internally a null permission
5354 * string is used when calling {@link #checkComponentPermission} in cases
5355 * when only uid-based security is needed.)
5356 *
5357 * This can be called with or without the global lock held.
5358 */
5359 public int checkPermission(String permission, int pid, int uid) {
5360 if (permission == null) {
5361 return PackageManager.PERMISSION_DENIED;
5362 }
Amith Yamasani742a6712011-05-04 14:49:28 -07005363 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 }
5365
5366 /**
5367 * Binder IPC calls go through the public entry point.
5368 * This can be called with or without the global lock held.
5369 */
5370 int checkCallingPermission(String permission) {
5371 return checkPermission(permission,
5372 Binder.getCallingPid(),
Amith Yamasani742a6712011-05-04 14:49:28 -07005373 UserId.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 }
5375
5376 /**
5377 * This can be called with or without the global lock held.
5378 */
5379 void enforceCallingPermission(String permission, String func) {
5380 if (checkCallingPermission(permission)
5381 == PackageManager.PERMISSION_GRANTED) {
5382 return;
5383 }
5384
5385 String msg = "Permission Denial: " + func + " from pid="
5386 + Binder.getCallingPid()
5387 + ", uid=" + Binder.getCallingUid()
5388 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005389 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005390 throw new SecurityException(msg);
5391 }
5392
5393 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07005394 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5395 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5396 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5397 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5398 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07005400 // Is the component private from the target uid?
5401 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
5402
5403 // Acceptable if the there is no read permission needed from the
5404 // target or the target is holding the read permission.
5405 if (!readPerm) {
5406 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005408 == PackageManager.PERMISSION_GRANTED)) {
5409 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 }
5411 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005412
5413 // Acceptable if the there is no write permission needed from the
5414 // target or the target is holding the read permission.
5415 if (!writePerm) {
5416 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005418 == PackageManager.PERMISSION_GRANTED)) {
5419 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 }
5421 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005422
5423 // Acceptable if there is a path permission matching the URI that
5424 // the target holds the permission on.
5425 PathPermission[] pps = pi.pathPermissions;
5426 if (pps != null && (!readPerm || !writePerm)) {
5427 final String path = uri.getPath();
5428 int i = pps.length;
5429 while (i > 0 && (!readPerm || !writePerm)) {
5430 i--;
5431 PathPermission pp = pps[i];
5432 if (!readPerm) {
5433 final String pprperm = pp.getReadPermission();
5434 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5435 + pprperm + " for " + pp.getPath()
5436 + ": match=" + pp.match(path)
5437 + " check=" + pm.checkUidPermission(pprperm, uid));
5438 if (pprperm != null && pp.match(path) &&
5439 (pm.checkUidPermission(pprperm, uid)
5440 == PackageManager.PERMISSION_GRANTED)) {
5441 readPerm = true;
5442 }
5443 }
5444 if (!writePerm) {
5445 final String ppwperm = pp.getWritePermission();
5446 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5447 + ppwperm + " for " + pp.getPath()
5448 + ": match=" + pp.match(path)
5449 + " check=" + pm.checkUidPermission(ppwperm, uid));
5450 if (ppwperm != null && pp.match(path) &&
5451 (pm.checkUidPermission(ppwperm, uid)
5452 == PackageManager.PERMISSION_GRANTED)) {
5453 writePerm = true;
5454 }
5455 }
5456 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005458 } catch (RemoteException e) {
5459 return false;
5460 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005461
5462 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 }
5464
5465 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5466 int modeFlags) {
5467 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005468 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005469 return true;
5470 }
5471 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5472 if (perms == null) return false;
5473 UriPermission perm = perms.get(uri);
5474 if (perm == null) return false;
5475 return (modeFlags&perm.modeFlags) == modeFlags;
5476 }
5477
5478 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005479 enforceNotIsolatedCaller("checkUriPermission");
5480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005481 // Another redirected-binder-call permissions check as in
5482 // {@link checkComponentPermission}.
5483 Identity tlsIdentity = sCallerIdentity.get();
5484 if (tlsIdentity != null) {
5485 uid = tlsIdentity.uid;
5486 pid = tlsIdentity.pid;
5487 }
5488
Amith Yamasani742a6712011-05-04 14:49:28 -07005489 uid = UserId.getAppId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005490 // Our own process gets to do everything.
5491 if (pid == MY_PID) {
5492 return PackageManager.PERMISSION_GRANTED;
5493 }
5494 synchronized(this) {
5495 return checkUriPermissionLocked(uri, uid, modeFlags)
5496 ? PackageManager.PERMISSION_GRANTED
5497 : PackageManager.PERMISSION_DENIED;
5498 }
5499 }
5500
Dianne Hackborn39792d22010-08-19 18:01:52 -07005501 /**
5502 * Check if the targetPkg can be granted permission to access uri by
5503 * the callingUid using the given modeFlags. Throws a security exception
5504 * if callingUid is not allowed to do this. Returns the uid of the target
5505 * if the URI permission grant should be performed; returns -1 if it is not
5506 * needed (for example targetPkg already has permission to access the URI).
5507 */
5508 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5509 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5511 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5512 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005513 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005514 }
5515
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005516 if (targetPkg != null) {
5517 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5518 "Checking grant " + targetPkg + " permission to " + uri);
5519 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005520
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005521 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522
5523 // If this is not a content: uri, we can't do anything with it.
5524 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005525 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005526 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005527 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005528 }
5529
5530 String name = uri.getAuthority();
5531 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005532 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5533 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005534 if (cpr != null) {
5535 pi = cpr.info;
5536 } else {
5537 try {
5538 pi = pm.resolveContentProvider(name,
5539 PackageManager.GET_URI_PERMISSION_PATTERNS);
5540 } catch (RemoteException ex) {
5541 }
5542 }
5543 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005544 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07005545 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005546 }
5547
5548 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005549 if (targetPkg != null) {
5550 try {
5551 targetUid = pm.getPackageUid(targetPkg);
5552 if (targetUid < 0) {
5553 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5554 "Can't grant URI permission no uid for: " + targetPkg);
5555 return -1;
5556 }
5557 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005558 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005559 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005560 } else {
5561 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 }
5563
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005564 if (targetUid >= 0) {
5565 // First... does the target actually need this permission?
5566 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5567 // No need to grant the target this permission.
5568 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5569 "Target " + targetPkg + " already has full permission to " + uri);
5570 return -1;
5571 }
5572 } else {
5573 // First... there is no target package, so can anyone access it?
5574 boolean allowed = pi.exported;
5575 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5576 if (pi.readPermission != null) {
5577 allowed = false;
5578 }
5579 }
5580 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5581 if (pi.writePermission != null) {
5582 allowed = false;
5583 }
5584 }
5585 if (allowed) {
5586 return -1;
5587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005588 }
5589
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005590 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 if (!pi.grantUriPermissions) {
5592 throw new SecurityException("Provider " + pi.packageName
5593 + "/" + pi.name
5594 + " does not allow granting of Uri permissions (uri "
5595 + uri + ")");
5596 }
5597 if (pi.uriPermissionPatterns != null) {
5598 final int N = pi.uriPermissionPatterns.length;
5599 boolean allowed = false;
5600 for (int i=0; i<N; i++) {
5601 if (pi.uriPermissionPatterns[i] != null
5602 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5603 allowed = true;
5604 break;
5605 }
5606 }
5607 if (!allowed) {
5608 throw new SecurityException("Provider " + pi.packageName
5609 + "/" + pi.name
5610 + " does not allow granting of permission to path of Uri "
5611 + uri);
5612 }
5613 }
5614
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005615 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005616 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005617 if (callingUid != Process.myUid()) {
5618 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5619 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5620 throw new SecurityException("Uid " + callingUid
5621 + " does not have permission to uri " + uri);
5622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 }
5624 }
5625
Dianne Hackborn39792d22010-08-19 18:01:52 -07005626 return targetUid;
5627 }
5628
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005629 public int checkGrantUriPermission(int callingUid, String targetPkg,
5630 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005631 enforceNotIsolatedCaller("checkGrantUriPermission");
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005632 synchronized(this) {
5633 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5634 }
5635 }
5636
Dianne Hackborn39792d22010-08-19 18:01:52 -07005637 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5638 Uri uri, int modeFlags, UriPermissionOwner owner) {
5639 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5640 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5641 if (modeFlags == 0) {
5642 return;
5643 }
5644
5645 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005646 // to the uri, and the target doesn't. Let's now give this to
5647 // the target.
5648
Joe Onorato8a9b2202010-02-26 18:56:32 -08005649 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005650 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005652 HashMap<Uri, UriPermission> targetUris
5653 = mGrantedUriPermissions.get(targetUid);
5654 if (targetUris == null) {
5655 targetUris = new HashMap<Uri, UriPermission>();
5656 mGrantedUriPermissions.put(targetUid, targetUris);
5657 }
5658
5659 UriPermission perm = targetUris.get(uri);
5660 if (perm == null) {
5661 perm = new UriPermission(targetUid, uri);
5662 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005663 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005666 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005667 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005668 } else {
5669 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5670 perm.readOwners.add(owner);
5671 owner.addReadPermission(perm);
5672 }
5673 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5674 perm.writeOwners.add(owner);
5675 owner.addWritePermission(perm);
5676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 }
5678 }
5679
Dianne Hackborn39792d22010-08-19 18:01:52 -07005680 void grantUriPermissionLocked(int callingUid,
5681 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005682 if (targetPkg == null) {
5683 throw new NullPointerException("targetPkg");
5684 }
5685
Dianne Hackborn39792d22010-08-19 18:01:52 -07005686 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5687 if (targetUid < 0) {
5688 return;
5689 }
5690
5691 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5692 }
5693
5694 /**
5695 * Like checkGrantUriPermissionLocked, but takes an Intent.
5696 */
5697 int checkGrantUriPermissionFromIntentLocked(int callingUid,
5698 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005699 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005700 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005701 + " from " + intent + "; flags=0x"
5702 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5703
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005704 if (targetPkg == null) {
5705 throw new NullPointerException("targetPkg");
5706 }
5707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005709 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 }
5711 Uri data = intent.getData();
5712 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005713 return -1;
5714 }
5715 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5716 intent.getFlags());
5717 }
5718
5719 /**
5720 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5721 */
5722 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
5723 String targetPkg, Intent intent, UriPermissionOwner owner) {
5724 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
5725 intent.getFlags(), owner);
5726 }
5727
5728 void grantUriPermissionFromIntentLocked(int callingUid,
5729 String targetPkg, Intent intent, UriPermissionOwner owner) {
5730 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
5731 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005732 return;
5733 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005734
5735 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 }
5737
5738 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5739 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005740 enforceNotIsolatedCaller("grantUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741 synchronized(this) {
5742 final ProcessRecord r = getRecordForAppLocked(caller);
5743 if (r == null) {
5744 throw new SecurityException("Unable to find app for caller "
5745 + caller
5746 + " when granting permission to uri " + uri);
5747 }
5748 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005749 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005750 }
5751 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005752 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753 }
5754
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005755 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005756 null);
5757 }
5758 }
5759
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005760 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5762 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5763 HashMap<Uri, UriPermission> perms
5764 = mGrantedUriPermissions.get(perm.uid);
5765 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005766 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005767 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005768 perms.remove(perm.uri);
5769 if (perms.size() == 0) {
5770 mGrantedUriPermissions.remove(perm.uid);
5771 }
5772 }
5773 }
5774 }
5775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5777 int modeFlags) {
5778 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5779 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5780 if (modeFlags == 0) {
5781 return;
5782 }
5783
Joe Onorato8a9b2202010-02-26 18:56:32 -08005784 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005785 "Revoking all granted permissions to " + uri);
5786
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005787 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788
5789 final String authority = uri.getAuthority();
5790 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005791 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority,
5792 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793 if (cpr != null) {
5794 pi = cpr.info;
5795 } else {
5796 try {
5797 pi = pm.resolveContentProvider(authority,
5798 PackageManager.GET_URI_PERMISSION_PATTERNS);
5799 } catch (RemoteException ex) {
5800 }
5801 }
5802 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005803 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 return;
5805 }
5806
5807 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005808 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 // Right now, if you are not the original owner of the permission,
5810 // you are not allowed to revoke it.
5811 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5812 throw new SecurityException("Uid " + callingUid
5813 + " does not have permission to uri " + uri);
5814 //}
5815 }
5816
5817 // Go through all of the permissions and remove any that match.
5818 final List<String> SEGMENTS = uri.getPathSegments();
5819 if (SEGMENTS != null) {
5820 final int NS = SEGMENTS.size();
5821 int N = mGrantedUriPermissions.size();
5822 for (int i=0; i<N; i++) {
5823 HashMap<Uri, UriPermission> perms
5824 = mGrantedUriPermissions.valueAt(i);
5825 Iterator<UriPermission> it = perms.values().iterator();
5826 toploop:
5827 while (it.hasNext()) {
5828 UriPermission perm = it.next();
5829 Uri targetUri = perm.uri;
5830 if (!authority.equals(targetUri.getAuthority())) {
5831 continue;
5832 }
5833 List<String> targetSegments = targetUri.getPathSegments();
5834 if (targetSegments == null) {
5835 continue;
5836 }
5837 if (targetSegments.size() < NS) {
5838 continue;
5839 }
5840 for (int j=0; j<NS; j++) {
5841 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5842 continue toploop;
5843 }
5844 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005845 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005846 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005847 perm.clearModes(modeFlags);
5848 if (perm.modeFlags == 0) {
5849 it.remove();
5850 }
5851 }
5852 if (perms.size() == 0) {
5853 mGrantedUriPermissions.remove(
5854 mGrantedUriPermissions.keyAt(i));
5855 N--;
5856 i--;
5857 }
5858 }
5859 }
5860 }
5861
5862 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5863 int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005864 enforceNotIsolatedCaller("revokeUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 synchronized(this) {
5866 final ProcessRecord r = getRecordForAppLocked(caller);
5867 if (r == null) {
5868 throw new SecurityException("Unable to find app for caller "
5869 + caller
5870 + " when revoking permission to uri " + uri);
5871 }
5872 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005873 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005874 return;
5875 }
5876
5877 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5878 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5879 if (modeFlags == 0) {
5880 return;
5881 }
5882
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005883 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884
5885 final String authority = uri.getAuthority();
5886 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005887 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888 if (cpr != null) {
5889 pi = cpr.info;
5890 } else {
5891 try {
5892 pi = pm.resolveContentProvider(authority,
5893 PackageManager.GET_URI_PERMISSION_PATTERNS);
5894 } catch (RemoteException ex) {
5895 }
5896 }
5897 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005898 Slog.w(TAG, "No content provider found for permission revoke: "
5899 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 return;
5901 }
5902
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005903 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005904 }
5905 }
5906
Dianne Hackborn7e269642010-08-25 19:50:20 -07005907 @Override
5908 public IBinder newUriPermissionOwner(String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005909 enforceNotIsolatedCaller("newUriPermissionOwner");
Dianne Hackborn7e269642010-08-25 19:50:20 -07005910 synchronized(this) {
5911 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5912 return owner.getExternalTokenLocked();
5913 }
5914 }
5915
5916 @Override
5917 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5918 Uri uri, int modeFlags) {
5919 synchronized(this) {
5920 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5921 if (owner == null) {
5922 throw new IllegalArgumentException("Unknown owner: " + token);
5923 }
5924 if (fromUid != Binder.getCallingUid()) {
5925 if (Binder.getCallingUid() != Process.myUid()) {
5926 // Only system code can grant URI permissions on behalf
5927 // of other users.
5928 throw new SecurityException("nice try");
5929 }
5930 }
5931 if (targetPkg == null) {
5932 throw new IllegalArgumentException("null target");
5933 }
5934 if (uri == null) {
5935 throw new IllegalArgumentException("null uri");
5936 }
5937
5938 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5939 }
5940 }
5941
5942 @Override
5943 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5944 synchronized(this) {
5945 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5946 if (owner == null) {
5947 throw new IllegalArgumentException("Unknown owner: " + token);
5948 }
5949
5950 if (uri == null) {
5951 owner.removeUriPermissionsLocked(mode);
5952 } else {
5953 owner.removeUriPermissionLocked(uri, mode);
5954 }
5955 }
5956 }
5957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5959 synchronized (this) {
5960 ProcessRecord app =
5961 who != null ? getRecordForAppLocked(who) : null;
5962 if (app == null) return;
5963
5964 Message msg = Message.obtain();
5965 msg.what = WAIT_FOR_DEBUGGER_MSG;
5966 msg.obj = app;
5967 msg.arg1 = waiting ? 1 : 0;
5968 mHandler.sendMessage(msg);
5969 }
5970 }
5971
5972 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005973 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5974 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005976 outInfo.threshold = homeAppMem;
5977 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5978 outInfo.hiddenAppThreshold = hiddenAppMem;
5979 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005980 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005981 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5982 ProcessList.VISIBLE_APP_ADJ);
5983 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5984 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 }
5986
5987 // =========================================================
5988 // TASK MANAGEMENT
5989 // =========================================================
5990
5991 public List getTasks(int maxNum, int flags,
5992 IThumbnailReceiver receiver) {
5993 ArrayList list = new ArrayList();
5994
5995 PendingThumbnailsRecord pending = null;
5996 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005997 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005998
5999 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006000 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006001 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6002 + ", receiver=" + receiver);
6003
6004 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6005 != PackageManager.PERMISSION_GRANTED) {
6006 if (receiver != null) {
6007 // If the caller wants to wait for pending thumbnails,
6008 // it ain't gonna get them.
6009 try {
6010 receiver.finished();
6011 } catch (RemoteException ex) {
6012 }
6013 }
6014 String msg = "Permission Denial: getTasks() from pid="
6015 + Binder.getCallingPid()
6016 + ", uid=" + Binder.getCallingUid()
6017 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006018 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 throw new SecurityException(msg);
6020 }
6021
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006022 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006023 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006024 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006025 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 TaskRecord curTask = null;
6027 int numActivities = 0;
6028 int numRunning = 0;
6029 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006030 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006031 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006032 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033
6034 // Initialize state for next task if needed.
6035 if (top == null ||
6036 (top.state == ActivityState.INITIALIZING
6037 && top.task == r.task)) {
6038 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039 curTask = r.task;
6040 numActivities = numRunning = 0;
6041 }
6042
6043 // Add 'r' into the current task.
6044 numActivities++;
6045 if (r.app != null && r.app.thread != null) {
6046 numRunning++;
6047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048
Joe Onorato8a9b2202010-02-26 18:56:32 -08006049 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006050 TAG, r.intent.getComponent().flattenToShortString()
6051 + ": task=" + r.task);
6052
6053 // If the next one is a different task, generate a new
6054 // TaskInfo entry for what we have.
6055 if (next == null || next.task != curTask) {
6056 ActivityManager.RunningTaskInfo ci
6057 = new ActivityManager.RunningTaskInfo();
6058 ci.id = curTask.taskId;
6059 ci.baseActivity = r.intent.getComponent();
6060 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006061 if (top.thumbHolder != null) {
6062 ci.description = top.thumbHolder.lastDescription;
6063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 ci.numActivities = numActivities;
6065 ci.numRunning = numRunning;
6066 //System.out.println(
6067 // "#" + maxNum + ": " + " descr=" + ci.description);
6068 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006069 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 TAG, "State=" + top.state + "Idle=" + top.idle
6071 + " app=" + top.app
6072 + " thr=" + (top.app != null ? top.app.thread : null));
6073 if (top.state == ActivityState.RESUMED
6074 || top.state == ActivityState.PAUSING) {
6075 if (top.idle && top.app != null
6076 && top.app.thread != null) {
6077 topRecord = top;
6078 topThumbnail = top.app.thread;
6079 } else {
6080 top.thumbnailNeeded = true;
6081 }
6082 }
6083 if (pending == null) {
6084 pending = new PendingThumbnailsRecord(receiver);
6085 }
6086 pending.pendingRecords.add(top);
6087 }
6088 list.add(ci);
6089 maxNum--;
6090 top = null;
6091 }
6092 }
6093
6094 if (pending != null) {
6095 mPendingThumbnails.add(pending);
6096 }
6097 }
6098
Joe Onorato8a9b2202010-02-26 18:56:32 -08006099 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100
6101 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006102 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08006104 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006106 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006107 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006108 }
6109 }
6110
6111 if (pending == null && receiver != null) {
6112 // In this case all thumbnails were available and the client
6113 // is being asked to be told when the remaining ones come in...
6114 // which is unusually, since the top-most currently running
6115 // activity should never have a canned thumbnail! Oh well.
6116 try {
6117 receiver.finished();
6118 } catch (RemoteException ex) {
6119 }
6120 }
6121
6122 return list;
6123 }
6124
6125 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6126 int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006127 final int callingUid = Binder.getCallingUid();
6128 // If it's the system uid asking, then use the current user id.
6129 // TODO: Make sure that there aren't any other legitimate calls from the system uid that
6130 // require the entire list.
6131 final int callingUserId = callingUid == Process.SYSTEM_UID
6132 ? mCurrentUserId : UserId.getUserId(callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 synchronized (this) {
6134 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6135 "getRecentTasks()");
6136
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006137 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006139 final int N = mRecentTasks.size();
6140 ArrayList<ActivityManager.RecentTaskInfo> res
6141 = new ArrayList<ActivityManager.RecentTaskInfo>(
6142 maxNum < N ? maxNum : N);
6143 for (int i=0; i<N && maxNum > 0; i++) {
6144 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006145 // Only add calling user's recent tasks
6146 if (tr.userId != callingUserId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07006147 // Return the entry if desired by the caller. We always return
6148 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07006149 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07006150 // not supplied RECENT_WITH_EXCLUDED and there is some reason
6151 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07006152
Dianne Hackborn905577f2011-09-07 18:31:28 -07006153 if (i == 0
6154 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 || (tr.intent == null)
6156 || ((tr.intent.getFlags()
6157 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6158 ActivityManager.RecentTaskInfo rti
6159 = new ActivityManager.RecentTaskInfo();
6160 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006161 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 rti.baseIntent = new Intent(
6163 tr.intent != null ? tr.intent : tr.affinityIntent);
6164 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08006165 rti.description = tr.lastDescription;
6166
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006167 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6168 // Check whether this activity is currently available.
6169 try {
6170 if (rti.origActivity != null) {
6171 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
6172 continue;
6173 }
6174 } else if (rti.baseIntent != null) {
6175 if (pm.queryIntentActivities(rti.baseIntent,
6176 null, 0) == null) {
6177 continue;
6178 }
6179 }
6180 } catch (RemoteException e) {
6181 // Will never happen.
6182 }
6183 }
6184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006185 res.add(rti);
6186 maxNum--;
6187 }
6188 }
6189 return res;
6190 }
6191 }
6192
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006193 private TaskRecord taskForIdLocked(int id) {
6194 final int N = mRecentTasks.size();
6195 for (int i=0; i<N; i++) {
6196 TaskRecord tr = mRecentTasks.get(i);
6197 if (tr.taskId == id) {
6198 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006199 }
6200 }
6201 return null;
6202 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006203
6204 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6205 synchronized (this) {
6206 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6207 "getTaskThumbnails()");
6208 TaskRecord tr = taskForIdLocked(id);
6209 if (tr != null) {
6210 return mMainStack.getTaskThumbnailsLocked(tr);
6211 }
6212 }
6213 return null;
6214 }
6215
6216 public boolean removeSubTask(int taskId, int subTaskIndex) {
6217 synchronized (this) {
6218 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6219 "removeSubTask()");
6220 long ident = Binder.clearCallingIdentity();
6221 try {
6222 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
6223 } finally {
6224 Binder.restoreCallingIdentity(ident);
6225 }
6226 }
6227 }
6228
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006229 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006230 TaskRecord tr = root.task;
6231 Intent baseIntent = new Intent(
6232 tr.intent != null ? tr.intent : tr.affinityIntent);
6233 ComponentName component = baseIntent.getComponent();
6234 if (component == null) {
6235 Slog.w(TAG, "Now component for base intent of task: " + tr);
6236 return;
6237 }
6238
6239 // Find any running services associated with this app.
6240 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07006241 for (ServiceRecord sr : mServiceMap.getAllServices(root.userId)) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006242 if (sr.packageName.equals(component.getPackageName())) {
6243 services.add(sr);
6244 }
6245 }
6246
6247 // Take care of any running services associated with the app.
6248 for (int i=0; i<services.size(); i++) {
6249 ServiceRecord sr = services.get(i);
6250 if (sr.startRequested) {
6251 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006252 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006253 stopServiceLocked(sr);
6254 } else {
6255 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
6256 sr.makeNextStartId(), baseIntent, -1));
6257 if (sr.app != null && sr.app.thread != null) {
6258 sendServiceArgsLocked(sr, false);
6259 }
6260 }
6261 }
6262 }
6263
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006264 if (killProcesses) {
6265 // Find any running processes associated with this app.
6266 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6267 SparseArray<ProcessRecord> appProcs
6268 = mProcessNames.getMap().get(component.getPackageName());
6269 if (appProcs != null) {
6270 for (int i=0; i<appProcs.size(); i++) {
6271 procs.add(appProcs.valueAt(i));
6272 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006273 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006274
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006275 // Kill the running processes.
6276 for (int i=0; i<procs.size(); i++) {
6277 ProcessRecord pr = procs.get(i);
6278 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6279 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
6280 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
6281 pr.processName, pr.setAdj, "remove task");
6282 Process.killProcessQuiet(pr.pid);
6283 } else {
6284 pr.waitingToKill = "remove task";
6285 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006286 }
6287 }
6288 }
6289
6290 public boolean removeTask(int taskId, int flags) {
6291 synchronized (this) {
6292 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6293 "removeTask()");
6294 long ident = Binder.clearCallingIdentity();
6295 try {
6296 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
6297 if (r != null) {
6298 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006299 cleanUpRemovedTaskLocked(r,
6300 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006301 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07006302 } else {
6303 TaskRecord tr = null;
6304 int i=0;
6305 while (i < mRecentTasks.size()) {
6306 TaskRecord t = mRecentTasks.get(i);
6307 if (t.taskId == taskId) {
6308 tr = t;
6309 break;
6310 }
6311 i++;
6312 }
6313 if (tr != null) {
6314 if (tr.numActivities <= 0) {
6315 // Caller is just removing a recent task that is
6316 // not actively running. That is easy!
6317 mRecentTasks.remove(i);
6318 } else {
6319 Slog.w(TAG, "removeTask: task " + taskId
6320 + " does not have activities to remove, "
6321 + " but numActivities=" + tr.numActivities
6322 + ": " + tr);
6323 }
6324 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006325 }
6326 } finally {
6327 Binder.restoreCallingIdentity(ident);
6328 }
6329 }
6330 return false;
6331 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08006332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006333 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6334 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006335 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 TaskRecord jt = startTask;
6337
6338 // First look backwards
6339 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006340 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006341 if (r.task != jt) {
6342 jt = r.task;
6343 if (affinity.equals(jt.affinity)) {
6344 return j;
6345 }
6346 }
6347 }
6348
6349 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006350 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006351 jt = startTask;
6352 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006353 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006354 if (r.task != jt) {
6355 if (affinity.equals(jt.affinity)) {
6356 return j;
6357 }
6358 jt = r.task;
6359 }
6360 }
6361
6362 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006363 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006364 return N-1;
6365 }
6366
6367 return -1;
6368 }
6369
6370 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006371 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006373 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6375 "moveTaskToFront()");
6376
6377 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006378 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6379 Binder.getCallingUid(), "Task to front")) {
6380 return;
6381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006382 final long origId = Binder.clearCallingIdentity();
6383 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006384 TaskRecord tr = taskForIdLocked(task);
6385 if (tr != null) {
6386 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6387 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006388 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006389 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6390 // Caller wants the home activity moved with it. To accomplish this,
6391 // we'll just move the home task to the top first.
6392 mMainStack.moveHomeToFrontLocked();
6393 }
6394 mMainStack.moveTaskToFrontLocked(tr, null);
6395 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006397 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6398 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08006400 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6401 mMainStack.mUserLeaving = true;
6402 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006403 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6404 // Caller wants the home activity moved with it. To accomplish this,
6405 // we'll just move the home task to the top first.
6406 mMainStack.moveHomeToFrontLocked();
6407 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006408 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006409 return;
6410 }
6411 }
6412 } finally {
6413 Binder.restoreCallingIdentity(origId);
6414 }
6415 }
6416 }
6417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006418 public void moveTaskToBack(int task) {
6419 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6420 "moveTaskToBack()");
6421
6422 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006423 if (mMainStack.mResumedActivity != null
6424 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006425 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6426 Binder.getCallingUid(), "Task to back")) {
6427 return;
6428 }
6429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006431 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 Binder.restoreCallingIdentity(origId);
6433 }
6434 }
6435
6436 /**
6437 * Moves an activity, and all of the other activities within the same task, to the bottom
6438 * of the history stack. The activity's order within the task is unchanged.
6439 *
6440 * @param token A reference to the activity we wish to move
6441 * @param nonRoot If false then this only works if the activity is the root
6442 * of a task; if true it will work for any activity in a task.
6443 * @return Returns true if the move completed, false if not.
6444 */
6445 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006446 enforceNotIsolatedCaller("moveActivityTaskToBack");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 synchronized(this) {
6448 final long origId = Binder.clearCallingIdentity();
6449 int taskId = getTaskForActivityLocked(token, !nonRoot);
6450 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006451 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006452 }
6453 Binder.restoreCallingIdentity(origId);
6454 }
6455 return false;
6456 }
6457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006458 public void moveTaskBackwards(int task) {
6459 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6460 "moveTaskBackwards()");
6461
6462 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006463 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6464 Binder.getCallingUid(), "Task backwards")) {
6465 return;
6466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 final long origId = Binder.clearCallingIdentity();
6468 moveTaskBackwardsLocked(task);
6469 Binder.restoreCallingIdentity(origId);
6470 }
6471 }
6472
6473 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006474 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006475 }
6476
6477 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6478 synchronized(this) {
6479 return getTaskForActivityLocked(token, onlyRoot);
6480 }
6481 }
6482
6483 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006484 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006485 TaskRecord lastTask = null;
6486 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006487 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006488 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006489 if (!onlyRoot || lastTask != r.task) {
6490 return r.task.taskId;
6491 }
6492 return -1;
6493 }
6494 lastTask = r.task;
6495 }
6496
6497 return -1;
6498 }
6499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 public void finishOtherInstances(IBinder token, ComponentName className) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006501 enforceNotIsolatedCaller("finishOtherInstances");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006502 synchronized(this) {
6503 final long origId = Binder.clearCallingIdentity();
6504
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006505 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006506 TaskRecord lastTask = null;
6507 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006508 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08006510 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006511 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006512 null, "others")) {
6513 i--;
6514 N--;
6515 }
6516 }
6517 lastTask = r.task;
6518 }
6519
6520 Binder.restoreCallingIdentity(origId);
6521 }
6522 }
6523
6524 // =========================================================
6525 // THUMBNAILS
6526 // =========================================================
6527
6528 public void reportThumbnail(IBinder token,
6529 Bitmap thumbnail, CharSequence description) {
6530 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6531 final long origId = Binder.clearCallingIdentity();
6532 sendPendingThumbnail(null, token, thumbnail, description, true);
6533 Binder.restoreCallingIdentity(origId);
6534 }
6535
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006536 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006537 Bitmap thumbnail, CharSequence description, boolean always) {
6538 TaskRecord task = null;
6539 ArrayList receivers = null;
6540
6541 //System.out.println("Send pending thumbnail: " + r);
6542
6543 synchronized(this) {
6544 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006545 r = mMainStack.isInStackLocked(token);
6546 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006547 return;
6548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006549 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006550 if (thumbnail == null && r.thumbHolder != null) {
6551 thumbnail = r.thumbHolder.lastThumbnail;
6552 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006553 }
6554 if (thumbnail == null && !always) {
6555 // If there is no thumbnail, and this entry is not actually
6556 // going away, then abort for now and pick up the next
6557 // thumbnail we get.
6558 return;
6559 }
6560 task = r.task;
6561
6562 int N = mPendingThumbnails.size();
6563 int i=0;
6564 while (i<N) {
6565 PendingThumbnailsRecord pr =
6566 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6567 //System.out.println("Looking in " + pr.pendingRecords);
6568 if (pr.pendingRecords.remove(r)) {
6569 if (receivers == null) {
6570 receivers = new ArrayList();
6571 }
6572 receivers.add(pr);
6573 if (pr.pendingRecords.size() == 0) {
6574 pr.finished = true;
6575 mPendingThumbnails.remove(i);
6576 N--;
6577 continue;
6578 }
6579 }
6580 i++;
6581 }
6582 }
6583
6584 if (receivers != null) {
6585 final int N = receivers.size();
6586 for (int i=0; i<N; i++) {
6587 try {
6588 PendingThumbnailsRecord pr =
6589 (PendingThumbnailsRecord)receivers.get(i);
6590 pr.receiver.newThumbnail(
6591 task != null ? task.taskId : -1, thumbnail, description);
6592 if (pr.finished) {
6593 pr.receiver.finished();
6594 }
6595 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006596 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006597 }
6598 }
6599 }
6600 }
6601
6602 // =========================================================
6603 // CONTENT PROVIDERS
6604 // =========================================================
6605
Jeff Brown10e89712011-07-08 18:52:57 -07006606 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6607 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006608 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006609 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006610 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006611 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006612 } catch (RemoteException ex) {
6613 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006614 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006615 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6616 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617 if (providers != null) {
6618 final int N = providers.size();
6619 for (int i=0; i<N; i++) {
6620 ProviderInfo cpi =
6621 (ProviderInfo)providers.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006622
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006623 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006624 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006625 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006626 cpr = new ContentProviderRecord(cpi, app.info, comp);
Amith Yamasani742a6712011-05-04 14:49:28 -07006627 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006629 if (DEBUG_MU)
6630 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 app.pubProviders.put(cpi.name, cpr);
6632 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006633 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 }
6635 }
6636 return providers;
6637 }
6638
6639 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006640 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006642 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006643 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006644 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006645 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006646 return null;
6647 }
6648 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006649 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 == PackageManager.PERMISSION_GRANTED) {
6651 return null;
6652 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006653
6654 PathPermission[] pps = cpi.pathPermissions;
6655 if (pps != null) {
6656 int i = pps.length;
6657 while (i > 0) {
6658 i--;
6659 PathPermission pp = pps[i];
6660 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006661 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006662 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006663 return null;
6664 }
6665 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006666 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006667 == PackageManager.PERMISSION_GRANTED) {
6668 return null;
6669 }
6670 }
6671 }
6672
Dianne Hackbornb424b632010-08-18 15:59:05 -07006673 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6674 if (perms != null) {
6675 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6676 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6677 return null;
6678 }
6679 }
6680 }
6681
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006682 String msg;
6683 if (!cpi.exported) {
6684 msg = "Permission Denial: opening provider " + cpi.name
6685 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6686 + ", uid=" + callingUid + ") that is not exported from uid "
6687 + cpi.applicationInfo.uid;
6688 } else {
6689 msg = "Permission Denial: opening provider " + cpi.name
6690 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6691 + ", uid=" + callingUid + ") requires "
6692 + cpi.readPermission + " or " + cpi.writePermission;
6693 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006694 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 return msg;
6696 }
6697
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006698 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6699 if (r != null) {
6700 Integer cnt = r.conProviders.get(cpr);
6701 if (DEBUG_PROVIDER) Slog.v(TAG,
6702 "Adding provider requested by "
6703 + r.processName + " from process "
6704 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6705 + " cnt=" + (cnt == null ? 1 : cnt));
6706 if (cnt == null) {
6707 cpr.clients.add(r);
6708 r.conProviders.put(cpr, new Integer(1));
6709 return true;
6710 } else {
6711 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
6712 }
6713 } else {
6714 cpr.externals++;
6715 }
6716 return false;
6717 }
6718
6719 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6720 if (r != null) {
6721 Integer cnt = r.conProviders.get(cpr);
6722 if (DEBUG_PROVIDER) Slog.v(TAG,
6723 "Removing provider requested by "
6724 + r.processName + " from process "
6725 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6726 + " cnt=" + cnt);
6727 if (cnt == null || cnt.intValue() <= 1) {
6728 cpr.clients.remove(r);
6729 r.conProviders.remove(cpr);
6730 return true;
6731 } else {
6732 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
6733 }
6734 } else {
6735 cpr.externals++;
6736 }
6737 return false;
6738 }
6739
Amith Yamasani742a6712011-05-04 14:49:28 -07006740 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6741 String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 ContentProviderRecord cpr;
6743 ProviderInfo cpi = null;
6744
6745 synchronized(this) {
6746 ProcessRecord r = null;
6747 if (caller != null) {
6748 r = getRecordForAppLocked(caller);
6749 if (r == null) {
6750 throw new SecurityException(
6751 "Unable to find app for caller " + caller
6752 + " (pid=" + Binder.getCallingPid()
6753 + ") when getting content provider " + name);
6754 }
6755 }
6756
6757 // First check if this content provider has been published...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006758 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
Amith Yamasani742a6712011-05-04 14:49:28 -07006759 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006760 boolean providerRunning = cpr != null;
6761 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006763 String msg;
6764 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6765 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006766 }
6767
6768 if (r != null && cpr.canRunHere(r)) {
6769 // This provider has been published or is in the process
6770 // of being published... but it is also allowed to run
6771 // in the caller's process, so don't make a connection
6772 // and just let the caller instantiate its own instance.
6773 if (cpr.provider != null) {
6774 // don't give caller the provider object, it needs
6775 // to make its own.
6776 cpr = new ContentProviderRecord(cpr);
6777 }
6778 return cpr;
6779 }
6780
6781 final long origId = Binder.clearCallingIdentity();
6782
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006783 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006784 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006785 final boolean countChanged = incProviderCount(r, cpr);
6786 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006787 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006788 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006789 // make sure to count it as being accessed and thus
6790 // back up on the LRU list. This is good because
6791 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006792 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006793 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006794 }
6795
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006796 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006797 if (false) {
6798 if (cpr.name.flattenToShortString().equals(
6799 "com.android.providers.calendar/.CalendarProvider2")) {
6800 Slog.v(TAG, "****************** KILLING "
6801 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006802 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006803 }
6804 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006805 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006806 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6807 // NOTE: there is still a race here where a signal could be
6808 // pending on the process even though we managed to update its
6809 // adj level. Not sure what to do about this, but at least
6810 // the race is now smaller.
6811 if (!success) {
6812 // Uh oh... it looks like the provider's process
6813 // has been killed on us. We need to wait for a new
6814 // process to be started, and make sure its death
6815 // doesn't kill our process.
6816 Slog.i(TAG,
6817 "Existing provider " + cpr.name.flattenToShortString()
6818 + " is crashing; detaching " + r);
6819 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006820 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006821 if (!lastRef) {
6822 // This wasn't the last ref our process had on
6823 // the provider... we have now been killed, bail.
6824 return null;
6825 }
6826 providerRunning = false;
6827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006828 }
6829
6830 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006833 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006835 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006836 resolveContentProvider(name,
6837 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006838 } catch (RemoteException ex) {
6839 }
6840 if (cpi == null) {
6841 return null;
6842 }
6843
Amith Yamasani742a6712011-05-04 14:49:28 -07006844 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo,
6845 Binder.getOrigCallingUser());
6846
Dianne Hackbornb424b632010-08-18 15:59:05 -07006847 String msg;
6848 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6849 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006850 }
6851
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006852 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006853 && !cpi.processName.equals("system")) {
6854 // If this content provider does not run in the system
6855 // process, and the system is not yet ready to run other
6856 // processes, then fail fast instead of hanging.
6857 throw new IllegalArgumentException(
6858 "Attempt to launch content provider before system ready");
6859 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006860
6861 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006862 cpr = mProviderMap.getProviderByClass(comp, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 final boolean firstClass = cpr == null;
6864 if (firstClass) {
6865 try {
6866 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006867 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 getApplicationInfo(
6869 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006870 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006872 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 + cpi.name);
6874 return null;
6875 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006876 ai = getAppInfoForUser(ai, Binder.getOrigCallingUser());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006877 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006878 } catch (RemoteException ex) {
6879 // pm is in same process, this will never happen.
6880 }
6881 }
6882
6883 if (r != null && cpr.canRunHere(r)) {
6884 // If this is a multiprocess provider, then just return its
6885 // info and allow the caller to instantiate it. Only do
6886 // this if the provider is the same user as the caller's
6887 // process, or can run as root (so can be in any process).
6888 return cpr;
6889 }
6890
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006891 if (DEBUG_PROVIDER) {
6892 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006893 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006894 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 }
6896
6897 // This is single process, and our app is now connecting to it.
6898 // See if we are already in the process of launching this
6899 // provider.
6900 final int N = mLaunchingProviders.size();
6901 int i;
6902 for (i=0; i<N; i++) {
6903 if (mLaunchingProviders.get(i) == cpr) {
6904 break;
6905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 }
6907
6908 // If the provider is not already being launched, then get it
6909 // started.
6910 if (i >= N) {
6911 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006912
6913 try {
6914 // Content provider is now in use, its package can't be stopped.
6915 try {
6916 AppGlobals.getPackageManager().setPackageStoppedState(
6917 cpr.appInfo.packageName, false);
6918 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006919 } catch (IllegalArgumentException e) {
6920 Slog.w(TAG, "Failed trying to unstop package "
6921 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006922 }
6923
6924 ProcessRecord proc = startProcessLocked(cpi.processName,
6925 cpr.appInfo, false, 0, "content provider",
6926 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006927 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006928 if (proc == null) {
6929 Slog.w(TAG, "Unable to launch app "
6930 + cpi.applicationInfo.packageName + "/"
6931 + cpi.applicationInfo.uid + " for provider "
6932 + name + ": process is bad");
6933 return null;
6934 }
6935 cpr.launchingApp = proc;
6936 mLaunchingProviders.add(cpr);
6937 } finally {
6938 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006940 }
6941
6942 // Make sure the provider is published (the same provider class
6943 // may be published under multiple names).
6944 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006945 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006947 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006948 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006949 }
6950 }
6951
6952 // Wait for the provider to be published...
6953 synchronized (cpr) {
6954 while (cpr.provider == null) {
6955 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006956 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 + cpi.applicationInfo.packageName + "/"
6958 + cpi.applicationInfo.uid + " for provider "
6959 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006960 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006961 cpi.applicationInfo.packageName,
6962 cpi.applicationInfo.uid, name);
6963 return null;
6964 }
6965 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006966 if (DEBUG_MU) {
6967 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6968 + cpr.launchingApp);
6969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006970 cpr.wait();
6971 } catch (InterruptedException ex) {
6972 }
6973 }
6974 }
6975 return cpr;
6976 }
6977
6978 public final ContentProviderHolder getContentProvider(
6979 IApplicationThread caller, String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006980 enforceNotIsolatedCaller("getContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006981 if (caller == null) {
6982 String msg = "null IApplicationThread when getting content provider "
6983 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006984 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 throw new SecurityException(msg);
6986 }
6987
Amith Yamasani742a6712011-05-04 14:49:28 -07006988 ContentProviderHolder contentProvider = getContentProviderImpl(caller, name);
6989 return contentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 }
6991
6992 private ContentProviderHolder getContentProviderExternal(String name) {
6993 return getContentProviderImpl(null, name);
6994 }
6995
6996 /**
6997 * Drop a content provider from a ProcessRecord's bookkeeping
6998 * @param cpr
6999 */
7000 public void removeContentProvider(IApplicationThread caller, String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007001 enforceNotIsolatedCaller("removeContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007003 int userId = UserId.getUserId(Binder.getCallingUid());
7004 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07007006 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08007007 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07007008 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 return;
7010 }
7011 final ProcessRecord r = getRecordForAppLocked(caller);
7012 if (r == null) {
7013 throw new SecurityException(
7014 "Unable to find app for caller " + caller +
7015 " when removing content provider " + name);
7016 }
7017 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007018 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007019 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7020 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
7021 + r.info.processName + " from process "
7022 + localCpr.appInfo.processName);
7023 if (localCpr.launchingApp == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08007025 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07007026 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 return;
7028 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07007029 if (decProviderCount(r, localCpr)) {
7030 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07007031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033 }
7034 }
7035
7036 private void removeContentProviderExternal(String name) {
7037 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007038 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
7039 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 if(cpr == null) {
7041 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08007042 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007043 return;
7044 }
7045
7046 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007047 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007048 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
7049 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 localCpr.externals--;
7051 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007052 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 }
7054 updateOomAdjLocked();
7055 }
7056 }
7057
7058 public final void publishContentProviders(IApplicationThread caller,
7059 List<ContentProviderHolder> providers) {
7060 if (providers == null) {
7061 return;
7062 }
7063
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007064 enforceNotIsolatedCaller("publishContentProviders");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007065 synchronized(this) {
7066 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07007067 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007068 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007069 if (r == null) {
7070 throw new SecurityException(
7071 "Unable to find app for caller " + caller
7072 + " (pid=" + Binder.getCallingPid()
7073 + ") when publishing content providers");
7074 }
7075
7076 final long origId = Binder.clearCallingIdentity();
7077
7078 final int N = providers.size();
7079 for (int i=0; i<N; i++) {
7080 ContentProviderHolder src = providers.get(i);
7081 if (src == null || src.info == null || src.provider == null) {
7082 continue;
7083 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07007084 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007085 if (DEBUG_MU)
7086 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007087 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007088 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007089 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007090 String names[] = dst.info.authority.split(";");
7091 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007092 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093 }
7094
7095 int NL = mLaunchingProviders.size();
7096 int j;
7097 for (j=0; j<NL; j++) {
7098 if (mLaunchingProviders.get(j) == dst) {
7099 mLaunchingProviders.remove(j);
7100 j--;
7101 NL--;
7102 }
7103 }
7104 synchronized (dst) {
7105 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07007106 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 dst.notifyAll();
7108 }
7109 updateOomAdjLocked(r);
7110 }
7111 }
7112
7113 Binder.restoreCallingIdentity(origId);
7114 }
7115 }
7116
7117 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07007118 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06007119 synchronized (mSelf) {
7120 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7121 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08007122 if (providers != null) {
7123 for (int i=providers.size()-1; i>=0; i--) {
7124 ProviderInfo pi = (ProviderInfo)providers.get(i);
7125 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7126 Slog.w(TAG, "Not installing system proc provider " + pi.name
7127 + ": not system .apk");
7128 providers.remove(i);
7129 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08007130 }
7131 }
7132 }
Josh Bartel2ecce342010-02-25 10:55:48 -06007133 if (providers != null) {
7134 mSystemThread.installSystemProviders(providers);
7135 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08007136
7137 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01007138
7139 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007140 }
7141
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007142 /**
7143 * Allows app to retrieve the MIME type of a URI without having permission
7144 * to access its content provider.
7145 *
7146 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7147 *
7148 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7149 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7150 */
7151 public String getProviderMimeType(Uri uri) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007152 enforceNotIsolatedCaller("getProviderMimeType");
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007153 final String name = uri.getAuthority();
7154 final long ident = Binder.clearCallingIdentity();
7155 ContentProviderHolder holder = null;
7156
7157 try {
7158 holder = getContentProviderExternal(name);
7159 if (holder != null) {
7160 return holder.provider.getType(uri);
7161 }
7162 } catch (RemoteException e) {
7163 Log.w(TAG, "Content provider dead retrieving " + uri, e);
7164 return null;
7165 } finally {
7166 if (holder != null) {
7167 removeContentProviderExternal(name);
7168 }
7169 Binder.restoreCallingIdentity(ident);
7170 }
7171
7172 return null;
7173 }
7174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007175 // =========================================================
7176 // GLOBAL MANAGEMENT
7177 // =========================================================
7178
7179 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007180 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007181 String proc = customProcess != null ? customProcess : info.processName;
7182 BatteryStatsImpl.Uid.Proc ps = null;
7183 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007184 int uid = info.uid;
7185 if (isolated) {
7186 int userId = UserId.getUserId(uid);
7187 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7188 uid = 0;
7189 while (true) {
7190 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7191 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7192 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7193 }
7194 uid = UserId.getUid(userId, mNextIsolatedProcessUid);
7195 mNextIsolatedProcessUid++;
7196 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7197 // No process for this uid, use it.
7198 break;
7199 }
7200 stepsLeft--;
7201 if (stepsLeft <= 0) {
7202 return null;
7203 }
7204 }
7205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007206 synchronized (stats) {
7207 ps = stats.getProcessStatsLocked(info.uid, proc);
7208 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007209 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 }
7211
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007212 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7213 ProcessRecord app;
7214 if (!isolated) {
7215 app = getProcessRecordLocked(info.processName, info.uid);
7216 } else {
7217 app = null;
7218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007219
7220 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007221 app = newProcessRecordLocked(null, info, null, isolated);
7222 mProcessNames.put(info.processName, app.uid, app);
7223 if (isolated) {
7224 mIsolatedProcesses.put(app.uid, app);
7225 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007226 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007227 }
7228
Dianne Hackborne7f97212011-02-24 14:40:20 -08007229 // This package really, really can not be stopped.
7230 try {
7231 AppGlobals.getPackageManager().setPackageStoppedState(
7232 info.packageName, false);
7233 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08007234 } catch (IllegalArgumentException e) {
7235 Slog.w(TAG, "Failed trying to unstop package "
7236 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08007237 }
7238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007239 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7240 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7241 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007242 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007243 }
7244 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7245 mPersistentStartingProcesses.add(app);
7246 startProcessLocked(app, "added application", app.processName);
7247 }
7248
7249 return app;
7250 }
7251
7252 public void unhandledBack() {
7253 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7254 "unhandledBack()");
7255
7256 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007257 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007258 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 TAG, "Performing unhandledBack(): stack size = " + count);
7260 if (count > 1) {
7261 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007262 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007263 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7264 Binder.restoreCallingIdentity(origId);
7265 }
7266 }
7267 }
7268
7269 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007270 enforceNotIsolatedCaller("openContentUri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007271 String name = uri.getAuthority();
7272 ContentProviderHolder cph = getContentProviderExternal(name);
7273 ParcelFileDescriptor pfd = null;
7274 if (cph != null) {
7275 // We record the binder invoker's uid in thread-local storage before
7276 // going to the content provider to open the file. Later, in the code
7277 // that handles all permissions checks, we look for this uid and use
7278 // that rather than the Activity Manager's own uid. The effect is that
7279 // we do the check against the caller's permissions even though it looks
7280 // to the content provider like the Activity Manager itself is making
7281 // the request.
7282 sCallerIdentity.set(new Identity(
7283 Binder.getCallingPid(), Binder.getCallingUid()));
7284 try {
7285 pfd = cph.provider.openFile(uri, "r");
7286 } catch (FileNotFoundException e) {
7287 // do nothing; pfd will be returned null
7288 } finally {
7289 // Ensure that whatever happens, we clean up the identity state
7290 sCallerIdentity.remove();
7291 }
7292
7293 // We've got the fd now, so we're done with the provider.
7294 removeContentProviderExternal(name);
7295 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007296 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007297 }
7298 return pfd;
7299 }
7300
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007301 // Actually is sleeping or shutting down or whatever else in the future
7302 // is an inactive state.
7303 public boolean isSleeping() {
7304 return mSleeping || mShuttingDown;
7305 }
7306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007307 public void goingToSleep() {
7308 synchronized(this) {
7309 mSleeping = true;
7310 mWindowManager.setEventDispatching(false);
7311
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007312 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007313
7314 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07007315 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007316 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7317 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007318 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007319 }
7320 }
7321
Dianne Hackborn55280a92009-05-07 15:53:46 -07007322 public boolean shutdown(int timeout) {
7323 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7324 != PackageManager.PERMISSION_GRANTED) {
7325 throw new SecurityException("Requires permission "
7326 + android.Manifest.permission.SHUTDOWN);
7327 }
7328
7329 boolean timedout = false;
7330
7331 synchronized(this) {
7332 mShuttingDown = true;
7333 mWindowManager.setEventDispatching(false);
7334
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007335 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007336 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07007337 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007338 while (mMainStack.mResumedActivity != null
Dianne Hackborncbb722e2012-02-07 18:33:49 -08007339 || mMainStack.mPausingActivities.size() > 0) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07007340 long delay = endTime - System.currentTimeMillis();
7341 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007342 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07007343 timedout = true;
7344 break;
7345 }
7346 try {
7347 this.wait();
7348 } catch (InterruptedException e) {
7349 }
7350 }
7351 }
7352 }
7353
7354 mUsageStatsService.shutdown();
7355 mBatteryStatsService.shutdown();
7356
7357 return timedout;
7358 }
7359
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007360 public final void activitySlept(IBinder token) {
7361 if (localLOGV) Slog.v(
7362 TAG, "Activity slept: token=" + token);
7363
7364 ActivityRecord r = null;
7365
7366 final long origId = Binder.clearCallingIdentity();
7367
7368 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007369 r = mMainStack.isInStackLocked(token);
7370 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007371 mMainStack.activitySleptLocked(r);
7372 }
7373 }
7374
7375 Binder.restoreCallingIdentity(origId);
7376 }
7377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 public void wakingUp() {
7379 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 mWindowManager.setEventDispatching(true);
7381 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007382 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007383 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 }
7385 }
7386
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007387 public void stopAppSwitches() {
7388 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7389 != PackageManager.PERMISSION_GRANTED) {
7390 throw new SecurityException("Requires permission "
7391 + android.Manifest.permission.STOP_APP_SWITCHES);
7392 }
7393
7394 synchronized(this) {
7395 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7396 + APP_SWITCH_DELAY_TIME;
7397 mDidAppSwitch = false;
7398 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7399 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7400 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7401 }
7402 }
7403
7404 public void resumeAppSwitches() {
7405 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7406 != PackageManager.PERMISSION_GRANTED) {
7407 throw new SecurityException("Requires permission "
7408 + android.Manifest.permission.STOP_APP_SWITCHES);
7409 }
7410
7411 synchronized(this) {
7412 // Note that we don't execute any pending app switches... we will
7413 // let those wait until either the timeout, or the next start
7414 // activity request.
7415 mAppSwitchesAllowedTime = 0;
7416 }
7417 }
7418
7419 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7420 String name) {
7421 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7422 return true;
7423 }
7424
7425 final int perm = checkComponentPermission(
7426 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007427 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007428 if (perm == PackageManager.PERMISSION_GRANTED) {
7429 return true;
7430 }
7431
Joe Onorato8a9b2202010-02-26 18:56:32 -08007432 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007433 return false;
7434 }
7435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007436 public void setDebugApp(String packageName, boolean waitForDebugger,
7437 boolean persistent) {
7438 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7439 "setDebugApp()");
7440
7441 // Note that this is not really thread safe if there are multiple
7442 // callers into it at the same time, but that's not a situation we
7443 // care about.
7444 if (persistent) {
7445 final ContentResolver resolver = mContext.getContentResolver();
7446 Settings.System.putString(
7447 resolver, Settings.System.DEBUG_APP,
7448 packageName);
7449 Settings.System.putInt(
7450 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7451 waitForDebugger ? 1 : 0);
7452 }
7453
7454 synchronized (this) {
7455 if (!persistent) {
7456 mOrigDebugApp = mDebugApp;
7457 mOrigWaitForDebugger = mWaitForDebugger;
7458 }
7459 mDebugApp = packageName;
7460 mWaitForDebugger = waitForDebugger;
7461 mDebugTransient = !persistent;
7462 if (packageName != null) {
7463 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07007464 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 Binder.restoreCallingIdentity(origId);
7466 }
7467 }
7468 }
7469
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007470 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7471 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7472 synchronized (this) {
7473 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7474 if (!isDebuggable) {
7475 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7476 throw new SecurityException("Process not debuggable: " + app.packageName);
7477 }
7478 }
7479 mProfileApp = processName;
7480 mProfileFile = profileFile;
7481 if (mProfileFd != null) {
7482 try {
7483 mProfileFd.close();
7484 } catch (IOException e) {
7485 }
7486 mProfileFd = null;
7487 }
7488 mProfileFd = profileFd;
7489 mProfileType = 0;
7490 mAutoStopProfiler = autoStopProfiler;
7491 }
7492 }
7493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 public void setAlwaysFinish(boolean enabled) {
7495 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7496 "setAlwaysFinish()");
7497
7498 Settings.System.putInt(
7499 mContext.getContentResolver(),
7500 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7501
7502 synchronized (this) {
7503 mAlwaysFinishActivities = enabled;
7504 }
7505 }
7506
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007507 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007508 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007509 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007510 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007511 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 }
7513 }
7514
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007515 public boolean isUserAMonkey() {
7516 // For now the fact that there is a controller implies
7517 // we have a monkey.
7518 synchronized (this) {
7519 return mController != null;
7520 }
7521 }
7522
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007523 public void registerActivityWatcher(IActivityWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007524 enforceNotIsolatedCaller("registerActivityWatcher");
Josh Bartel2ecce342010-02-25 10:55:48 -06007525 synchronized (this) {
7526 mWatchers.register(watcher);
7527 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007528 }
7529
7530 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06007531 synchronized (this) {
7532 mWatchers.unregister(watcher);
7533 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007534 }
7535
Jeff Sharkeya4620792011-05-20 15:29:23 -07007536 public void registerProcessObserver(IProcessObserver observer) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007537 enforceNotIsolatedCaller("registerProcessObserver");
Jeff Sharkeya4620792011-05-20 15:29:23 -07007538 mProcessObservers.register(observer);
7539 }
7540
7541 public void unregisterProcessObserver(IProcessObserver observer) {
7542 mProcessObservers.unregister(observer);
7543 }
7544
Daniel Sandler69a48172010-06-23 16:29:36 -04007545 public void setImmersive(IBinder token, boolean immersive) {
7546 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007547 ActivityRecord r = mMainStack.isInStackLocked(token);
7548 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007549 throw new IllegalArgumentException();
7550 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007551 r.immersive = immersive;
7552 }
7553 }
7554
7555 public boolean isImmersive(IBinder token) {
7556 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007557 ActivityRecord r = mMainStack.isInStackLocked(token);
7558 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007559 throw new IllegalArgumentException();
7560 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007561 return r.immersive;
7562 }
7563 }
7564
7565 public boolean isTopActivityImmersive() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007566 enforceNotIsolatedCaller("startActivity");
Daniel Sandler69a48172010-06-23 16:29:36 -04007567 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007568 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007569 return (r != null) ? r.immersive : false;
7570 }
7571 }
7572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 public final void enterSafeMode() {
7574 synchronized(this) {
7575 // It only makes sense to do this before the system is ready
7576 // and started launching other packages.
7577 if (!mSystemReady) {
7578 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007579 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 } catch (RemoteException e) {
7581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007582 }
7583 }
7584 }
7585
Jeff Brownb09abc12011-01-13 21:08:27 -08007586 public final void showSafeModeOverlay() {
7587 View v = LayoutInflater.from(mContext).inflate(
7588 com.android.internal.R.layout.safe_mode, null);
7589 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7590 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7591 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7592 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7593 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7594 lp.format = v.getBackground().getOpacity();
7595 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7596 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7597 ((WindowManager)mContext.getSystemService(
7598 Context.WINDOW_SERVICE)).addView(v, lp);
7599 }
7600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007601 public void noteWakeupAlarm(IIntentSender sender) {
7602 if (!(sender instanceof PendingIntentRecord)) {
7603 return;
7604 }
7605 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7606 synchronized (stats) {
7607 if (mBatteryStatsService.isOnBattery()) {
7608 mBatteryStatsService.enforceCallingPermission();
7609 PendingIntentRecord rec = (PendingIntentRecord)sender;
7610 int MY_UID = Binder.getCallingUid();
7611 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7612 BatteryStatsImpl.Uid.Pkg pkg =
7613 stats.getPackageStatsLocked(uid, rec.key.packageName);
7614 pkg.incWakeupsLocked();
7615 }
7616 }
7617 }
7618
Dianne Hackborn64825172011-03-02 21:32:58 -08007619 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007620 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007621 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007623 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007624 // XXX Note: don't acquire main activity lock here, because the window
7625 // manager calls in with its locks held.
7626
7627 boolean killed = false;
7628 synchronized (mPidsSelfLocked) {
7629 int[] types = new int[pids.length];
7630 int worstType = 0;
7631 for (int i=0; i<pids.length; i++) {
7632 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7633 if (proc != null) {
7634 int type = proc.setAdj;
7635 types[i] = type;
7636 if (type > worstType) {
7637 worstType = type;
7638 }
7639 }
7640 }
7641
Dianne Hackborn64825172011-03-02 21:32:58 -08007642 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007643 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007644 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7645 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007646 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007647 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007648
7649 // If this is not a secure call, don't let it kill processes that
7650 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007651 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7652 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007653 }
7654
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007655 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007656 for (int i=0; i<pids.length; i++) {
7657 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7658 if (proc == null) {
7659 continue;
7660 }
7661 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007662 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007663 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007664 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7665 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007666 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007667 proc.killedBackground = true;
7668 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 }
7670 }
7671 }
7672 return killed;
7673 }
7674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007675 public final void startRunning(String pkg, String cls, String action,
7676 String data) {
7677 synchronized(this) {
7678 if (mStartRunning) {
7679 return;
7680 }
7681 mStartRunning = true;
7682 mTopComponent = pkg != null && cls != null
7683 ? new ComponentName(pkg, cls) : null;
7684 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7685 mTopData = data;
7686 if (!mSystemReady) {
7687 return;
7688 }
7689 }
7690
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007691 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007692 }
7693
7694 private void retrieveSettings() {
7695 final ContentResolver resolver = mContext.getContentResolver();
7696 String debugApp = Settings.System.getString(
7697 resolver, Settings.System.DEBUG_APP);
7698 boolean waitForDebugger = Settings.System.getInt(
7699 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7700 boolean alwaysFinishActivities = Settings.System.getInt(
7701 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7702
7703 Configuration configuration = new Configuration();
7704 Settings.System.getConfiguration(resolver, configuration);
7705
7706 synchronized (this) {
7707 mDebugApp = mOrigDebugApp = debugApp;
7708 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7709 mAlwaysFinishActivities = alwaysFinishActivities;
7710 // This happens before any activities are started, so we can
7711 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007712 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007713 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 }
7715 }
7716
7717 public boolean testIsSystemReady() {
7718 // no need to synchronize(this) just to read & return the value
7719 return mSystemReady;
7720 }
7721
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007722 private static File getCalledPreBootReceiversFile() {
7723 File dataDir = Environment.getDataDirectory();
7724 File systemDir = new File(dataDir, "system");
7725 File fname = new File(systemDir, "called_pre_boots.dat");
7726 return fname;
7727 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007728
7729 static final int LAST_DONE_VERSION = 10000;
7730
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007731 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7732 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7733 File file = getCalledPreBootReceiversFile();
7734 FileInputStream fis = null;
7735 try {
7736 fis = new FileInputStream(file);
7737 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007738 int fvers = dis.readInt();
7739 if (fvers == LAST_DONE_VERSION) {
7740 String vers = dis.readUTF();
7741 String codename = dis.readUTF();
7742 String build = dis.readUTF();
7743 if (android.os.Build.VERSION.RELEASE.equals(vers)
7744 && android.os.Build.VERSION.CODENAME.equals(codename)
7745 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7746 int num = dis.readInt();
7747 while (num > 0) {
7748 num--;
7749 String pkg = dis.readUTF();
7750 String cls = dis.readUTF();
7751 lastDoneReceivers.add(new ComponentName(pkg, cls));
7752 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007753 }
7754 }
7755 } catch (FileNotFoundException e) {
7756 } catch (IOException e) {
7757 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7758 } finally {
7759 if (fis != null) {
7760 try {
7761 fis.close();
7762 } catch (IOException e) {
7763 }
7764 }
7765 }
7766 return lastDoneReceivers;
7767 }
7768
7769 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7770 File file = getCalledPreBootReceiversFile();
7771 FileOutputStream fos = null;
7772 DataOutputStream dos = null;
7773 try {
7774 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7775 fos = new FileOutputStream(file);
7776 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007777 dos.writeInt(LAST_DONE_VERSION);
7778 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007779 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007780 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007781 dos.writeInt(list.size());
7782 for (int i=0; i<list.size(); i++) {
7783 dos.writeUTF(list.get(i).getPackageName());
7784 dos.writeUTF(list.get(i).getClassName());
7785 }
7786 } catch (IOException e) {
7787 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7788 file.delete();
7789 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007790 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007791 if (dos != null) {
7792 try {
7793 dos.close();
7794 } catch (IOException e) {
7795 // TODO Auto-generated catch block
7796 e.printStackTrace();
7797 }
7798 }
7799 }
7800 }
7801
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007802 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007803 synchronized(this) {
7804 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007805 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007806 return;
7807 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007808
7809 // Check to see if there are any update receivers to run.
7810 if (!mDidUpdate) {
7811 if (mWaitingUpdate) {
7812 return;
7813 }
7814 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7815 List<ResolveInfo> ris = null;
7816 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007817 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007818 intent, null, 0);
7819 } catch (RemoteException e) {
7820 }
7821 if (ris != null) {
7822 for (int i=ris.size()-1; i>=0; i--) {
7823 if ((ris.get(i).activityInfo.applicationInfo.flags
7824 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7825 ris.remove(i);
7826 }
7827 }
7828 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007829
7830 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7831
7832 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007833 for (int i=0; i<ris.size(); i++) {
7834 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007835 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7836 if (lastDoneReceivers.contains(comp)) {
7837 ris.remove(i);
7838 i--;
7839 }
7840 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007841
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007842 for (int i=0; i<ris.size(); i++) {
7843 ActivityInfo ai = ris.get(i).activityInfo;
7844 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7845 doneReceivers.add(comp);
7846 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007847 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08007848 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007849 finisher = new IIntentReceiver.Stub() {
7850 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07007851 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007852 boolean sticky) {
7853 // The raw IIntentReceiver interface is called
7854 // with the AM lock held, so redispatch to
7855 // execute our code without the lock.
7856 mHandler.post(new Runnable() {
7857 public void run() {
7858 synchronized (ActivityManagerService.this) {
7859 mDidUpdate = true;
7860 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007861 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007862 showBootMessage(mContext.getText(
7863 R.string.android_upgrading_complete),
7864 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007865 systemReady(goingCallback);
7866 }
7867 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007868 }
7869 };
7870 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007871 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Amith Yamasani742a6712011-05-04 14:49:28 -07007872 /* TODO: Send this to all users */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007873 broadcastIntentLocked(null, null, intent, null, finisher,
Amith Yamasani742a6712011-05-04 14:49:28 -07007874 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7875 Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08007876 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007877 mWaitingUpdate = true;
7878 }
7879 }
7880 }
7881 if (mWaitingUpdate) {
7882 return;
7883 }
7884 mDidUpdate = true;
7885 }
7886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887 mSystemReady = true;
7888 if (!mStartRunning) {
7889 return;
7890 }
7891 }
7892
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007893 ArrayList<ProcessRecord> procsToKill = null;
7894 synchronized(mPidsSelfLocked) {
7895 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7896 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7897 if (!isAllowedWhileBooting(proc.info)){
7898 if (procsToKill == null) {
7899 procsToKill = new ArrayList<ProcessRecord>();
7900 }
7901 procsToKill.add(proc);
7902 }
7903 }
7904 }
7905
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007906 synchronized(this) {
7907 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007908 for (int i=procsToKill.size()-1; i>=0; i--) {
7909 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007910 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007911 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007912 }
7913 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007914
7915 // Now that we have cleaned up any update processes, we
7916 // are ready to start launching real processes and know that
7917 // we won't trample on them any more.
7918 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007919 }
7920
Joe Onorato8a9b2202010-02-26 18:56:32 -08007921 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007922 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007923 SystemClock.uptimeMillis());
7924
7925 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007926 // Make sure we have no pre-ready processes sitting around.
7927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007928 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7929 ResolveInfo ri = mContext.getPackageManager()
7930 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007931 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932 CharSequence errorMsg = null;
7933 if (ri != null) {
7934 ActivityInfo ai = ri.activityInfo;
7935 ApplicationInfo app = ai.applicationInfo;
7936 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7937 mTopAction = Intent.ACTION_FACTORY_TEST;
7938 mTopData = null;
7939 mTopComponent = new ComponentName(app.packageName,
7940 ai.name);
7941 } else {
7942 errorMsg = mContext.getResources().getText(
7943 com.android.internal.R.string.factorytest_not_system);
7944 }
7945 } else {
7946 errorMsg = mContext.getResources().getText(
7947 com.android.internal.R.string.factorytest_no_action);
7948 }
7949 if (errorMsg != null) {
7950 mTopAction = null;
7951 mTopData = null;
7952 mTopComponent = null;
7953 Message msg = Message.obtain();
7954 msg.what = SHOW_FACTORY_ERROR_MSG;
7955 msg.getData().putCharSequence("msg", errorMsg);
7956 mHandler.sendMessage(msg);
7957 }
7958 }
7959 }
7960
7961 retrieveSettings();
7962
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007963 if (goingCallback != null) goingCallback.run();
7964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007965 synchronized (this) {
7966 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7967 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007968 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007969 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007970 if (apps != null) {
7971 int N = apps.size();
7972 int i;
7973 for (i=0; i<N; i++) {
7974 ApplicationInfo info
7975 = (ApplicationInfo)apps.get(i);
7976 if (info != null &&
7977 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007978 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007979 }
7980 }
7981 }
7982 } catch (RemoteException ex) {
7983 // pm is in same process, this will never happen.
7984 }
7985 }
7986
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007987 // Start up initial activity.
7988 mBooting = true;
7989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007990 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007991 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007992 Message msg = Message.obtain();
7993 msg.what = SHOW_UID_ERROR_MSG;
7994 mHandler.sendMessage(msg);
7995 }
7996 } catch (RemoteException e) {
7997 }
7998
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007999 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 }
8001 }
8002
Dan Egnorb7f03672009-12-09 16:22:32 -08008003 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008004 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008005 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08008006 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08008007 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008008 startAppProblemLocked(app);
8009 app.stopFreezingAllLocked();
8010 return handleAppCrashLocked(app);
8011 }
8012
Dan Egnorb7f03672009-12-09 16:22:32 -08008013 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008014 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008015 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08008016 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08008017 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8018 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008019 startAppProblemLocked(app);
8020 app.stopFreezingAllLocked();
8021 }
8022
8023 /**
8024 * Generate a process error record, suitable for attachment to a ProcessRecord.
8025 *
8026 * @param app The ProcessRecord in which the error occurred.
8027 * @param condition Crashing, Application Not Responding, etc. Values are defined in
8028 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08008029 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008030 * @param shortMsg Short message describing the crash.
8031 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08008032 * @param stackTrace Full crash stack trace, may be null.
8033 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034 * @return Returns a fully-formed AppErrorStateInfo record.
8035 */
8036 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008037 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008038 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08008039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008040 report.condition = condition;
8041 report.processName = app.processName;
8042 report.pid = app.pid;
8043 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08008044 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008045 report.shortMsg = shortMsg;
8046 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08008047 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048
8049 return report;
8050 }
8051
Dan Egnor42471dd2010-01-07 17:25:22 -08008052 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008053 synchronized (this) {
8054 app.crashing = false;
8055 app.crashingReport = null;
8056 app.notResponding = false;
8057 app.notRespondingReport = null;
8058 if (app.anrDialog == fromDialog) {
8059 app.anrDialog = null;
8060 }
8061 if (app.waitDialog == fromDialog) {
8062 app.waitDialog = null;
8063 }
8064 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08008065 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008066 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07008067 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
8068 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008069 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071 }
8072 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008073
Dan Egnorb7f03672009-12-09 16:22:32 -08008074 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008075 long now = SystemClock.uptimeMillis();
8076
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008077 Long crashTime;
8078 if (!app.isolated) {
8079 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8080 } else {
8081 crashTime = null;
8082 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07008083 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008084 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008085 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08008087 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008088 app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008089 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8090 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008092 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008093 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008094 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008095 }
8096 }
8097 if (!app.persistent) {
8098 // We don't want to start this process again until the user
8099 // explicitly does so... but for persistent process, we really
8100 // need to keep it running. If a persistent process is actually
8101 // repeatedly crashing, then badness for everyone.
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008102 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008104 if (!app.isolated) {
8105 // XXX We don't have a way to mark isolated processes
8106 // as bad, since they don't have a peristent identity.
8107 mBadProcesses.put(app.info.processName, app.uid, now);
8108 mProcessCrashTimes.remove(app.info.processName, app.uid);
8109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008111 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07008112 // Don't let services in this process be restarted and potentially
8113 // annoy the user repeatedly. Unless it is persistent, since those
8114 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08008115 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08008116 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 return false;
8118 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08008119 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008120 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008121 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008122 if (r.app == app) {
8123 // If the top running activity is from this crashing
8124 // process, then terminate it to avoid getting in a loop.
8125 Slog.w(TAG, " Force finishing activity "
8126 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08008127 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008128 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008129 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08008130 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008131 // stopped, to avoid a situation where one will get
8132 // re-start our crashing activity once it gets resumed again.
8133 index--;
8134 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008135 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008136 if (r.state == ActivityState.RESUMED
8137 || r.state == ActivityState.PAUSING
8138 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008139 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008140 Slog.w(TAG, " Force finishing activity "
8141 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008142 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008143 Activity.RESULT_CANCELED, null, "crashed");
8144 }
8145 }
8146 }
8147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148 }
8149
8150 // Bump up the crash count of any services currently running in the proc.
8151 if (app.services.size() != 0) {
8152 // Any services running in the application need to be placed
8153 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008154 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008156 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008157 sr.crashCount++;
8158 }
8159 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02008160
8161 // If the crashing process is what we consider to be the "home process" and it has been
8162 // replaced by a third-party app, clear the package preferred activities from packages
8163 // with a home activity running in the process to prevent a repeatedly crashing app
8164 // from blocking the user to manually clear the list.
8165 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8166 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8167 Iterator it = mHomeProcess.activities.iterator();
8168 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07008169 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02008170 if (r.isHomeActivity) {
8171 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8172 try {
8173 ActivityThread.getPackageManager()
8174 .clearPackagePreferredActivities(r.packageName);
8175 } catch (RemoteException c) {
8176 // pm is in same process, this will never happen.
8177 }
8178 }
8179 }
8180 }
8181
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008182 if (!app.isolated) {
8183 // XXX Can't keep track of crash times for isolated processes,
8184 // because they don't have a perisistent identity.
8185 mProcessCrashTimes.put(app.info.processName, app.uid, now);
8186 }
8187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008188 return true;
8189 }
8190
8191 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08008192 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8193 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 skipCurrentReceiverLocked(app);
8195 }
8196
8197 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08008198 for (BroadcastQueue queue : mBroadcastQueues) {
8199 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008200 }
8201 }
8202
Dan Egnor60d87622009-12-16 16:32:58 -08008203 /**
8204 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8205 * The application process will exit immediately after this call returns.
8206 * @param app object of the crashing app, null for the system server
8207 * @param crashInfo describing the exception
8208 */
8209 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008210 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008211 final String processName = app == null ? "system_server"
8212 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008213
8214 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008215 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008216 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008217 crashInfo.exceptionClassName,
8218 crashInfo.exceptionMessage,
8219 crashInfo.throwFileName,
8220 crashInfo.throwLineNumber);
8221
Jeff Sharkeya353d262011-10-28 11:12:06 -07008222 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008223
8224 crashApplication(r, crashInfo);
8225 }
8226
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008227 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008228 IBinder app,
8229 int violationMask,
8230 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008231 ProcessRecord r = findAppProcess(app, "StrictMode");
8232 if (r == null) {
8233 return;
8234 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008235
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008236 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08008237 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008238 boolean logIt = true;
8239 synchronized (mAlreadyLoggedViolatedStacks) {
8240 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8241 logIt = false;
8242 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008243 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008244 // the relative pain numbers, without logging all
8245 // the stack traces repeatedly. We'd want to do
8246 // likewise in the client code, which also does
8247 // dup suppression, before the Binder call.
8248 } else {
8249 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8250 mAlreadyLoggedViolatedStacks.clear();
8251 }
8252 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8253 }
8254 }
8255 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008256 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008257 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008258 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008259
8260 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8261 AppErrorResult result = new AppErrorResult();
8262 synchronized (this) {
8263 final long origId = Binder.clearCallingIdentity();
8264
8265 Message msg = Message.obtain();
8266 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8267 HashMap<String, Object> data = new HashMap<String, Object>();
8268 data.put("result", result);
8269 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008270 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008271 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008272 msg.obj = data;
8273 mHandler.sendMessage(msg);
8274
8275 Binder.restoreCallingIdentity(origId);
8276 }
8277 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07008278 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008279 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008280 }
8281
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008282 // Depending on the policy in effect, there could be a bunch of
8283 // these in quick succession so we try to batch these together to
8284 // minimize disk writes, number of dropbox entries, and maximize
8285 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008286 private void logStrictModeViolationToDropBox(
8287 ProcessRecord process,
8288 StrictMode.ViolationInfo info) {
8289 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008290 return;
8291 }
8292 final boolean isSystemApp = process == null ||
8293 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8294 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008295 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008296 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8297 final DropBoxManager dbox = (DropBoxManager)
8298 mContext.getSystemService(Context.DROPBOX_SERVICE);
8299
8300 // Exit early if the dropbox isn't configured to accept this report type.
8301 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8302
8303 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008304 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008305 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8306 synchronized (sb) {
8307 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008308 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008309 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8310 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008311 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8312 if (info.violationNumThisLoop != 0) {
8313 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8314 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07008315 if (info.numAnimationsRunning != 0) {
8316 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8317 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07008318 if (info.broadcastIntentAction != null) {
8319 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8320 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008321 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008322 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008323 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08008324 if (info.numInstances != -1) {
8325 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8326 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008327 if (info.tags != null) {
8328 for (String tag : info.tags) {
8329 sb.append("Span-Tag: ").append(tag).append("\n");
8330 }
8331 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008332 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008333 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8334 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008335 }
8336 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008337
8338 // Only buffer up to ~64k. Various logging bits truncate
8339 // things at 128k.
8340 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008341 }
8342
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008343 // Flush immediately if the buffer's grown too large, or this
8344 // is a non-system app. Non-system apps are isolated with a
8345 // different tag & policy and not batched.
8346 //
8347 // Batching is useful during internal testing with
8348 // StrictMode settings turned up high. Without batching,
8349 // thousands of separate files could be created on boot.
8350 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008351 new Thread("Error dump: " + dropboxTag) {
8352 @Override
8353 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008354 String report;
8355 synchronized (sb) {
8356 report = sb.toString();
8357 sb.delete(0, sb.length());
8358 sb.trimToSize();
8359 }
8360 if (report.length() != 0) {
8361 dbox.addText(dropboxTag, report);
8362 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008363 }
8364 }.start();
8365 return;
8366 }
8367
8368 // System app batching:
8369 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008370 // An existing dropbox-writing thread is outstanding, so
8371 // we don't need to start it up. The existing thread will
8372 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008373 return;
8374 }
8375
8376 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8377 // (After this point, we shouldn't access AMS internal data structures.)
8378 new Thread("Error dump: " + dropboxTag) {
8379 @Override
8380 public void run() {
8381 // 5 second sleep to let stacks arrive and be batched together
8382 try {
8383 Thread.sleep(5000); // 5 seconds
8384 } catch (InterruptedException e) {}
8385
8386 String errorReport;
8387 synchronized (mStrictModeBuffer) {
8388 errorReport = mStrictModeBuffer.toString();
8389 if (errorReport.length() == 0) {
8390 return;
8391 }
8392 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8393 mStrictModeBuffer.trimToSize();
8394 }
8395 dbox.addText(dropboxTag, errorReport);
8396 }
8397 }.start();
8398 }
8399
Dan Egnor60d87622009-12-16 16:32:58 -08008400 /**
8401 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8402 * @param app object of the crashing app, null for the system server
8403 * @param tag reported by the caller
8404 * @param crashInfo describing the context of the error
8405 * @return true if the process should exit immediately (WTF is fatal)
8406 */
8407 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008408 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008409 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008410 final String processName = app == null ? "system_server"
8411 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008412
8413 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008414 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008415 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008416 tag, crashInfo.exceptionMessage);
8417
Jeff Sharkeya353d262011-10-28 11:12:06 -07008418 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008419
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008420 if (r != null && r.pid != Process.myPid() &&
8421 Settings.Secure.getInt(mContext.getContentResolver(),
8422 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008423 crashApplication(r, crashInfo);
8424 return true;
8425 } else {
8426 return false;
8427 }
8428 }
8429
8430 /**
8431 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8432 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8433 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008434 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008435 if (app == null) {
8436 return null;
8437 }
8438
8439 synchronized (this) {
8440 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8441 final int NA = apps.size();
8442 for (int ia=0; ia<NA; ia++) {
8443 ProcessRecord p = apps.valueAt(ia);
8444 if (p.thread != null && p.thread.asBinder() == app) {
8445 return p;
8446 }
8447 }
8448 }
8449
Dianne Hackborncb44d962011-03-10 17:02:27 -08008450 Slog.w(TAG, "Can't find mystery application for " + reason
8451 + " from pid=" + Binder.getCallingPid()
8452 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008453 return null;
8454 }
8455 }
8456
8457 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008458 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8459 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008460 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008461 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8462 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008463 // Watchdog thread ends up invoking this function (with
8464 // a null ProcessRecord) to add the stack file to dropbox.
8465 // Do not acquire a lock on this (am) in such cases, as it
8466 // could cause a potential deadlock, if and when watchdog
8467 // is invoked due to unavailability of lock on am and it
8468 // would prevent watchdog from killing system_server.
8469 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008470 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008471 return;
8472 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008473 // Note: ProcessRecord 'process' is guarded by the service
8474 // instance. (notably process.pkgList, which could otherwise change
8475 // concurrently during execution of this method)
8476 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008477 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008478 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008479 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008480 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8481 for (String pkg : process.pkgList) {
8482 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008483 try {
Dan Egnora455d192010-03-12 08:52:28 -08008484 PackageInfo pi = pm.getPackageInfo(pkg, 0);
8485 if (pi != null) {
8486 sb.append(" v").append(pi.versionCode);
8487 if (pi.versionName != null) {
8488 sb.append(" (").append(pi.versionName).append(")");
8489 }
8490 }
8491 } catch (RemoteException e) {
8492 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008493 }
Dan Egnora455d192010-03-12 08:52:28 -08008494 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008495 }
Dan Egnora455d192010-03-12 08:52:28 -08008496 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008497 }
8498
8499 private static String processClass(ProcessRecord process) {
8500 if (process == null || process.pid == MY_PID) {
8501 return "system_server";
8502 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8503 return "system_app";
8504 } else {
8505 return "data_app";
8506 }
8507 }
8508
8509 /**
8510 * Write a description of an error (crash, WTF, ANR) to the drop box.
8511 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8512 * @param process which caused the error, null means the system server
8513 * @param activity which triggered the error, null if unknown
8514 * @param parent activity related to the error, null if unknown
8515 * @param subject line related to the error, null if absent
8516 * @param report in long form describing the error, null if absent
8517 * @param logFile to include in the report, null if none
8518 * @param crashInfo giving an application stack trace, null if absent
8519 */
8520 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008521 ProcessRecord process, String processName, ActivityRecord activity,
8522 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008523 final String report, final File logFile,
8524 final ApplicationErrorReport.CrashInfo crashInfo) {
8525 // NOTE -- this must never acquire the ActivityManagerService lock,
8526 // otherwise the watchdog may be prevented from resetting the system.
8527
8528 final String dropboxTag = processClass(process) + "_" + eventType;
8529 final DropBoxManager dbox = (DropBoxManager)
8530 mContext.getSystemService(Context.DROPBOX_SERVICE);
8531
8532 // Exit early if the dropbox isn't configured to accept this report type.
8533 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8534
8535 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008536 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008537 if (activity != null) {
8538 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8539 }
8540 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8541 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8542 }
8543 if (parent != null && parent != activity) {
8544 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8545 }
8546 if (subject != null) {
8547 sb.append("Subject: ").append(subject).append("\n");
8548 }
8549 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008550 if (Debug.isDebuggerConnected()) {
8551 sb.append("Debugger: Connected\n");
8552 }
Dan Egnora455d192010-03-12 08:52:28 -08008553 sb.append("\n");
8554
8555 // Do the rest in a worker thread to avoid blocking the caller on I/O
8556 // (After this point, we shouldn't access AMS internal data structures.)
8557 Thread worker = new Thread("Error dump: " + dropboxTag) {
8558 @Override
8559 public void run() {
8560 if (report != null) {
8561 sb.append(report);
8562 }
8563 if (logFile != null) {
8564 try {
8565 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8566 } catch (IOException e) {
8567 Slog.e(TAG, "Error reading " + logFile, e);
8568 }
8569 }
8570 if (crashInfo != null && crashInfo.stackTrace != null) {
8571 sb.append(crashInfo.stackTrace);
8572 }
8573
8574 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8575 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8576 if (lines > 0) {
8577 sb.append("\n");
8578
8579 // Merge several logcat streams, and take the last N lines
8580 InputStreamReader input = null;
8581 try {
8582 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8583 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8584 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8585
8586 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8587 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8588 input = new InputStreamReader(logcat.getInputStream());
8589
8590 int num;
8591 char[] buf = new char[8192];
8592 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8593 } catch (IOException e) {
8594 Slog.e(TAG, "Error running logcat", e);
8595 } finally {
8596 if (input != null) try { input.close(); } catch (IOException e) {}
8597 }
8598 }
8599
8600 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008601 }
Dan Egnora455d192010-03-12 08:52:28 -08008602 };
8603
8604 if (process == null || process.pid == MY_PID) {
8605 worker.run(); // We may be about to die -- need to run this synchronously
8606 } else {
8607 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008608 }
8609 }
8610
8611 /**
8612 * Bring up the "unexpected error" dialog box for a crashing app.
8613 * Deal with edge cases (intercepts from instrumented applications,
8614 * ActivityController, error intent receivers, that sort of thing).
8615 * @param r the application crashing
8616 * @param crashInfo describing the failure
8617 */
8618 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008619 long timeMillis = System.currentTimeMillis();
8620 String shortMsg = crashInfo.exceptionClassName;
8621 String longMsg = crashInfo.exceptionMessage;
8622 String stackTrace = crashInfo.stackTrace;
8623 if (shortMsg != null && longMsg != null) {
8624 longMsg = shortMsg + ": " + longMsg;
8625 } else if (shortMsg != null) {
8626 longMsg = shortMsg;
8627 }
8628
Dan Egnor60d87622009-12-16 16:32:58 -08008629 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008630 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008631 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008632 try {
8633 String name = r != null ? r.processName : null;
8634 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008635 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008636 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008637 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 + " at watcher's request");
8639 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008640 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 }
8642 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008643 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 }
8645 }
8646
8647 final long origId = Binder.clearCallingIdentity();
8648
8649 // If this process is running instrumentation, finish it.
8650 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008651 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008652 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008653 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8654 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 Bundle info = new Bundle();
8656 info.putString("shortMsg", shortMsg);
8657 info.putString("longMsg", longMsg);
8658 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8659 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008660 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008661 }
8662
Dan Egnor60d87622009-12-16 16:32:58 -08008663 // If we can't identify the process or it's already exceeded its crash quota,
8664 // quit right away without showing a crash dialog.
8665 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008666 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008667 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008668 }
8669
8670 Message msg = Message.obtain();
8671 msg.what = SHOW_ERROR_MSG;
8672 HashMap data = new HashMap();
8673 data.put("result", result);
8674 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008675 msg.obj = data;
8676 mHandler.sendMessage(msg);
8677
8678 Binder.restoreCallingIdentity(origId);
8679 }
8680
8681 int res = result.get();
8682
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008683 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008684 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008685 if (r != null && !r.isolated) {
8686 // XXX Can't keep track of crash time for isolated processes,
8687 // since they don't have a persistent identity.
8688 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008689 SystemClock.uptimeMillis());
8690 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008691 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008692 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008693 }
8694 }
8695
8696 if (appErrorIntent != null) {
8697 try {
8698 mContext.startActivity(appErrorIntent);
8699 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008700 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008703 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008704
8705 Intent createAppErrorIntentLocked(ProcessRecord r,
8706 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8707 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008708 if (report == null) {
8709 return null;
8710 }
8711 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8712 result.setComponent(r.errorReportReceiver);
8713 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8714 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8715 return result;
8716 }
8717
Dan Egnorb7f03672009-12-09 16:22:32 -08008718 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8719 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008720 if (r.errorReportReceiver == null) {
8721 return null;
8722 }
8723
8724 if (!r.crashing && !r.notResponding) {
8725 return null;
8726 }
8727
Dan Egnorb7f03672009-12-09 16:22:32 -08008728 ApplicationErrorReport report = new ApplicationErrorReport();
8729 report.packageName = r.info.packageName;
8730 report.installerPackageName = r.errorReportReceiver.getPackageName();
8731 report.processName = r.processName;
8732 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008733 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008734
Dan Egnorb7f03672009-12-09 16:22:32 -08008735 if (r.crashing) {
8736 report.type = ApplicationErrorReport.TYPE_CRASH;
8737 report.crashInfo = crashInfo;
8738 } else if (r.notResponding) {
8739 report.type = ApplicationErrorReport.TYPE_ANR;
8740 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008741
Dan Egnorb7f03672009-12-09 16:22:32 -08008742 report.anrInfo.activity = r.notRespondingReport.tag;
8743 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8744 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008745 }
8746
Dan Egnorb7f03672009-12-09 16:22:32 -08008747 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008748 }
8749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008750 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008751 enforceNotIsolatedCaller("getProcessesInErrorState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008752 // assume our apps are happy - lazy create the list
8753 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8754
8755 synchronized (this) {
8756
8757 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008758 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8759 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008760 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8761 // This one's in trouble, so we'll generate a report for it
8762 // crashes are higher priority (in case there's a crash *and* an anr)
8763 ActivityManager.ProcessErrorStateInfo report = null;
8764 if (app.crashing) {
8765 report = app.crashingReport;
8766 } else if (app.notResponding) {
8767 report = app.notRespondingReport;
8768 }
8769
8770 if (report != null) {
8771 if (errList == null) {
8772 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8773 }
8774 errList.add(report);
8775 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008776 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008777 " crashing = " + app.crashing +
8778 " notResponding = " + app.notResponding);
8779 }
8780 }
8781 }
8782 }
8783
8784 return errList;
8785 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008786
8787 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008788 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008789 if (currApp != null) {
8790 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8791 }
8792 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008793 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8794 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008795 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8796 if (currApp != null) {
8797 currApp.lru = 0;
8798 }
8799 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008800 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008801 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8802 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8803 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8804 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8805 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8806 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8807 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8808 } else {
8809 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8810 }
8811 }
8812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008813 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008814 enforceNotIsolatedCaller("getRunningAppProcesses");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 // Lazy instantiation of list
8816 List<ActivityManager.RunningAppProcessInfo> runList = null;
8817 synchronized (this) {
8818 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008819 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8820 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8822 // Generate process state info for running application
8823 ActivityManager.RunningAppProcessInfo currApp =
8824 new ActivityManager.RunningAppProcessInfo(app.processName,
8825 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07008826 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008827 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07008828 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008829 }
Dianne Hackborn42499172010-10-15 18:45:07 -07008830 if (app.persistent) {
8831 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008833 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008834 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008835 currApp.importanceReasonCode = app.adjTypeCode;
8836 if (app.adjSource instanceof ProcessRecord) {
8837 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008838 currApp.importanceReasonImportance = oomAdjToImportance(
8839 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008840 } else if (app.adjSource instanceof ActivityRecord) {
8841 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008842 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8843 }
8844 if (app.adjTarget instanceof ComponentName) {
8845 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8846 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008847 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008848 // + " lru=" + currApp.lru);
8849 if (runList == null) {
8850 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8851 }
8852 runList.add(currApp);
8853 }
8854 }
8855 }
8856 return runList;
8857 }
8858
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008859 public List<ApplicationInfo> getRunningExternalApplications() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008860 enforceNotIsolatedCaller("getRunningExternalApplications");
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008861 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8862 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8863 if (runningApps != null && runningApps.size() > 0) {
8864 Set<String> extList = new HashSet<String>();
8865 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8866 if (app.pkgList != null) {
8867 for (String pkg : app.pkgList) {
8868 extList.add(pkg);
8869 }
8870 }
8871 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008872 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008873 for (String pkg : extList) {
8874 try {
8875 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
8876 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8877 retList.add(info);
8878 }
8879 } catch (RemoteException e) {
8880 }
8881 }
8882 }
8883 return retList;
8884 }
8885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008886 @Override
8887 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008888 if (checkCallingPermission(android.Manifest.permission.DUMP)
8889 != PackageManager.PERMISSION_GRANTED) {
8890 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8891 + Binder.getCallingPid()
8892 + ", uid=" + Binder.getCallingUid()
8893 + " without permission "
8894 + android.Manifest.permission.DUMP);
8895 return;
8896 }
8897
8898 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008899 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008900 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008901
8902 int opti = 0;
8903 while (opti < args.length) {
8904 String opt = args[opti];
8905 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8906 break;
8907 }
8908 opti++;
8909 if ("-a".equals(opt)) {
8910 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008911 } else if ("-c".equals(opt)) {
8912 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008913 } else if ("-h".equals(opt)) {
8914 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008915 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008916 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008917 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008918 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8919 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8920 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008921 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008922 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008923 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008924 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008925 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008926 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008927 pw.println(" all: dump all activities");
8928 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008929 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008930 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8931 pw.println(" a partial substring in a component name, a");
8932 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008933 pw.println(" -a: include all available server state.");
8934 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008935 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008936 } else {
8937 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008938 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008939 }
8940
8941 // Is the caller requesting to dump a particular piece of data?
8942 if (opti < args.length) {
8943 String cmd = args[opti];
8944 opti++;
8945 if ("activities".equals(cmd) || "a".equals(cmd)) {
8946 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008947 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008948 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008949 return;
8950 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008951 String[] newArgs;
8952 String name;
8953 if (opti >= args.length) {
8954 name = null;
8955 newArgs = EMPTY_STRING_ARRAY;
8956 } else {
8957 name = args[opti];
8958 opti++;
8959 newArgs = new String[args.length - opti];
8960 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8961 args.length - opti);
8962 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008963 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008964 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008965 }
8966 return;
8967 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008968 String[] newArgs;
8969 String name;
8970 if (opti >= args.length) {
8971 name = null;
8972 newArgs = EMPTY_STRING_ARRAY;
8973 } else {
8974 name = args[opti];
8975 opti++;
8976 newArgs = new String[args.length - opti];
8977 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8978 args.length - opti);
8979 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008980 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008981 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008982 }
8983 return;
8984 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008985 String[] newArgs;
8986 String name;
8987 if (opti >= args.length) {
8988 name = null;
8989 newArgs = EMPTY_STRING_ARRAY;
8990 } else {
8991 name = args[opti];
8992 opti++;
8993 newArgs = new String[args.length - opti];
8994 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8995 args.length - opti);
8996 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008997 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008998 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008999 }
9000 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009001 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9002 synchronized (this) {
9003 dumpOomLocked(fd, pw, args, opti, true);
9004 }
9005 return;
Marco Nelissen18cb2872011-11-15 11:19:53 -08009006 } else if ("provider".equals(cmd)) {
9007 String[] newArgs;
9008 String name;
9009 if (opti >= args.length) {
9010 name = null;
9011 newArgs = EMPTY_STRING_ARRAY;
9012 } else {
9013 name = args[opti];
9014 opti++;
9015 newArgs = new String[args.length - opti];
9016 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9017 }
9018 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9019 pw.println("No providers match: " + name);
9020 pw.println("Use -h for help.");
9021 }
9022 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009023 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9024 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009025 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009026 }
9027 return;
9028 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009029 String[] newArgs;
9030 String name;
9031 if (opti >= args.length) {
9032 name = null;
9033 newArgs = EMPTY_STRING_ARRAY;
9034 } else {
9035 name = args[opti];
9036 opti++;
9037 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009038 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9039 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009040 }
9041 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9042 pw.println("No services match: " + name);
9043 pw.println("Use -h for help.");
9044 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009045 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009046 } else if ("package".equals(cmd)) {
9047 String[] newArgs;
9048 if (opti >= args.length) {
9049 pw.println("package: no package name specified");
9050 pw.println("Use -h for help.");
9051 return;
9052 } else {
9053 dumpPackage = args[opti];
9054 opti++;
9055 newArgs = new String[args.length - opti];
9056 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9057 args.length - opti);
9058 args = newArgs;
9059 opti = 0;
9060 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009061 } else if ("services".equals(cmd) || "s".equals(cmd)) {
9062 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009063 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009064 }
9065 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07009066 } else {
9067 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009068 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9069 pw.println("Bad activity command, or no activities match: " + cmd);
9070 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009071 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009072 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009073 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009074 }
9075
9076 // No piece of data specified, dump everything.
9077 synchronized (this) {
9078 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009079 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009080 if (needSep) {
9081 pw.println(" ");
9082 }
9083 if (dumpAll) {
9084 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009085 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009086 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009087 if (needSep) {
9088 pw.println(" ");
9089 }
9090 if (dumpAll) {
9091 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009092 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009093 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009094 if (needSep) {
9095 pw.println(" ");
9096 }
9097 if (dumpAll) {
9098 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009099 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009100 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009101 if (needSep) {
9102 pw.println(" ");
9103 }
9104 if (dumpAll) {
9105 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009106 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009107 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009108 if (needSep) {
9109 pw.println(" ");
9110 }
9111 if (dumpAll) {
9112 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009113 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009114 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009115 }
9116 }
9117
9118 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009119 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009120 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9121 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009122 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
9123 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009124 pw.println(" ");
9125 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009126 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
9127 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009128 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009129 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009130 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009131 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009132 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009133 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009134 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009135 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009136 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009137 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009138 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009139 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009140 if (mMainStack.mGoingToSleepActivities.size() > 0) {
9141 pw.println(" ");
9142 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009143 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009144 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009145 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009146 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009147 pw.println(" ");
9148 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009149 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009150 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009153 pw.println(" ");
Dianne Hackborncbb722e2012-02-07 18:33:49 -08009154 if (mMainStack.mPausingActivities.size() > 0) {
9155 pw.println(" mPausingActivities: " + Arrays.toString(
9156 mMainStack.mPausingActivities.toArray()));
9157 }
9158 if (mMainStack.mInputPausedActivities.size() > 0) {
9159 pw.println(" mInputPausedActivities: " + Arrays.toString(
9160 mMainStack.mInputPausedActivities.toArray()));
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009161 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009162 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009163 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009164 if (dumpAll) {
9165 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9166 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009167 pw.println(" mDismissKeyguardOnNextActivity: "
9168 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009170
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009171 if (mRecentTasks.size() > 0) {
9172 pw.println();
9173 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009174
9175 final int N = mRecentTasks.size();
9176 for (int i=0; i<N; i++) {
9177 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009178 if (dumpPackage != null) {
9179 if (tr.realActivity == null ||
9180 !dumpPackage.equals(tr.realActivity)) {
9181 continue;
9182 }
9183 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009184 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
9185 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009186 if (dumpAll) {
9187 mRecentTasks.get(i).dump(pw, " ");
9188 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009189 }
9190 }
9191
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009192 if (dumpAll) {
9193 pw.println(" ");
9194 pw.println(" mCurTask: " + mCurTask);
9195 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009196
9197 return true;
9198 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009199
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009200 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009201 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009202 boolean needSep = false;
9203 int numPers = 0;
9204
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009205 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9206
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009207 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009208 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9209 final int NA = procs.size();
9210 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009211 ProcessRecord r = procs.valueAt(ia);
9212 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9213 continue;
9214 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009215 if (!needSep) {
9216 pw.println(" All known processes:");
9217 needSep = true;
9218 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009219 pw.print(r.persistent ? " *PERS*" : " *APP*");
9220 pw.print(" UID "); pw.print(procs.keyAt(ia));
9221 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222 r.dump(pw, " ");
9223 if (r.persistent) {
9224 numPers++;
9225 }
9226 }
9227 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009228 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08009229
9230 if (mIsolatedProcesses.size() > 0) {
9231 if (needSep) pw.println(" ");
9232 needSep = true;
9233 pw.println(" Isolated process list (sorted by uid):");
9234 for (int i=0; i<mIsolatedProcesses.size(); i++) {
9235 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9236 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9237 continue;
9238 }
9239 pw.println(String.format("%sIsolated #%2d: %s",
9240 " ", i, r.toString()));
9241 }
9242 }
9243
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009244 if (mLruProcesses.size() > 0) {
9245 if (needSep) pw.println(" ");
9246 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07009247 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009248 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009249 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009250 needSep = true;
9251 }
9252
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009253 if (dumpAll) {
9254 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009255 boolean printed = false;
9256 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9257 ProcessRecord r = mPidsSelfLocked.valueAt(i);
9258 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9259 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009260 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009261 if (!printed) {
9262 if (needSep) pw.println(" ");
9263 needSep = true;
9264 pw.println(" PID mappings:");
9265 printed = true;
9266 }
9267 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9268 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009269 }
9270 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009271 }
9272
9273 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009274 synchronized (mPidsSelfLocked) {
9275 boolean printed = false;
9276 for (int i=0; i<mForegroundProcesses.size(); i++) {
9277 ProcessRecord r = mPidsSelfLocked.get(
9278 mForegroundProcesses.valueAt(i).pid);
9279 if (dumpPackage != null && (r == null
9280 || !dumpPackage.equals(r.info.packageName))) {
9281 continue;
9282 }
9283 if (!printed) {
9284 if (needSep) pw.println(" ");
9285 needSep = true;
9286 pw.println(" Foreground Processes:");
9287 printed = true;
9288 }
9289 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9290 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009292 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009293 }
9294
9295 if (mPersistentStartingProcesses.size() > 0) {
9296 if (needSep) pw.println(" ");
9297 needSep = true;
9298 pw.println(" Persisent processes that are starting:");
9299 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009300 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009302
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009303 if (mRemovedProcesses.size() > 0) {
9304 if (needSep) pw.println(" ");
9305 needSep = true;
9306 pw.println(" Processes that are being removed:");
9307 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009308 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009309 }
9310
9311 if (mProcessesOnHold.size() > 0) {
9312 if (needSep) pw.println(" ");
9313 needSep = true;
9314 pw.println(" Processes that are on old until the system is ready:");
9315 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009316 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009319 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009320
9321 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009322 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009323 long now = SystemClock.uptimeMillis();
9324 for (Map.Entry<String, SparseArray<Long>> procs
9325 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009326 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009327 SparseArray<Long> uids = procs.getValue();
9328 final int N = uids.size();
9329 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009330 int puid = uids.keyAt(i);
9331 ProcessRecord r = mProcessNames.get(pname, puid);
9332 if (dumpPackage != null && (r == null
9333 || !dumpPackage.equals(r.info.packageName))) {
9334 continue;
9335 }
9336 if (!printed) {
9337 if (needSep) pw.println(" ");
9338 needSep = true;
9339 pw.println(" Time since processes crashed:");
9340 printed = true;
9341 }
9342 pw.print(" Process "); pw.print(pname);
9343 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009344 pw.print(": last crashed ");
9345 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009346 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009347 }
9348 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009350
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009351 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009352 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009353 for (Map.Entry<String, SparseArray<Long>> procs
9354 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009355 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009356 SparseArray<Long> uids = procs.getValue();
9357 final int N = uids.size();
9358 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009359 int puid = uids.keyAt(i);
9360 ProcessRecord r = mProcessNames.get(pname, puid);
9361 if (dumpPackage != null && (r == null
9362 || !dumpPackage.equals(r.info.packageName))) {
9363 continue;
9364 }
9365 if (!printed) {
9366 if (needSep) pw.println(" ");
9367 needSep = true;
9368 pw.println(" Bad processes:");
9369 }
9370 pw.print(" Bad process "); pw.print(pname);
9371 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009372 pw.print(": crashed at time ");
9373 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009374 }
9375 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009378 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009379 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009380 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009381 if (dumpAll) {
9382 StringBuilder sb = new StringBuilder(128);
9383 sb.append(" mPreviousProcessVisibleTime: ");
9384 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9385 pw.println(sb);
9386 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009387 if (mHeavyWeightProcess != null) {
9388 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9389 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009390 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009391 if (dumpAll) {
9392 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009393 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009394 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009395 for (Map.Entry<String, Integer> entry
9396 : mCompatModePackages.getPackages().entrySet()) {
9397 String pkg = entry.getKey();
9398 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009399 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9400 continue;
9401 }
9402 if (!printed) {
9403 pw.println(" mScreenCompatPackages:");
9404 printed = true;
9405 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009406 pw.print(" "); pw.print(pkg); pw.print(": ");
9407 pw.print(mode); pw.println();
9408 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009409 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009410 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009411 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9412 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9413 || mOrigWaitForDebugger) {
9414 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9415 + " mDebugTransient=" + mDebugTransient
9416 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9417 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009418 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9419 || mProfileFd != null) {
9420 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9421 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9422 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9423 + mAutoStopProfiler);
9424 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009425 if (mAlwaysFinishActivities || mController != null) {
9426 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9427 + " mController=" + mController);
9428 }
9429 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009430 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009432 + " mProcessesReady=" + mProcessesReady
9433 + " mSystemReady=" + mSystemReady);
9434 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009435 + " mBooted=" + mBooted
9436 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009437 pw.print(" mLastPowerCheckRealtime=");
9438 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9439 pw.println("");
9440 pw.print(" mLastPowerCheckUptime=");
9441 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9442 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009443 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9444 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009445 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009446 pw.println(" mNumServiceProcs=" + mNumServiceProcs
9447 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009448 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009449
9450 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009451 }
9452
Dianne Hackborn287952c2010-09-22 22:34:31 -07009453 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009454 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009455 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009456 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009457 long now = SystemClock.uptimeMillis();
9458 for (int i=0; i<mProcessesToGc.size(); i++) {
9459 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009460 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9461 continue;
9462 }
9463 if (!printed) {
9464 if (needSep) pw.println(" ");
9465 needSep = true;
9466 pw.println(" Processes that are waiting to GC:");
9467 printed = true;
9468 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009469 pw.print(" Process "); pw.println(proc);
9470 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9471 pw.print(", last gced=");
9472 pw.print(now-proc.lastRequestedGc);
9473 pw.print(" ms ago, last lowMem=");
9474 pw.print(now-proc.lastLowMemory);
9475 pw.println(" ms ago");
9476
9477 }
9478 }
9479 return needSep;
9480 }
9481
9482 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9483 int opti, boolean dumpAll) {
9484 boolean needSep = false;
9485
9486 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009487 if (needSep) pw.println(" ");
9488 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009489 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009490 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009491 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009492 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9493 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9494 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9495 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9496 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009497 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009498 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009499 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009500 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009501 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009502 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009503
9504 if (needSep) pw.println(" ");
9505 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009506 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009507 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009508 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009509 needSep = true;
9510 }
9511
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009512 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009513
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009514 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009515 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009516 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009517 if (mHeavyWeightProcess != null) {
9518 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9519 }
9520
9521 return true;
9522 }
9523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009524 /**
9525 * There are three ways to call this:
9526 * - no service specified: dump all the services
9527 * - a flattened component name that matched an existing service was specified as the
9528 * first arg: dump that one service
9529 * - the first arg isn't the flattened component name of an existing service:
9530 * dump all services whose component contains the first arg as a substring
9531 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009532 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9533 int opti, boolean dumpAll) {
9534 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009536 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009537 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009538 try {
9539 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9540 for (UserInfo user : users) {
9541 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9542 services.add(r1);
9543 }
9544 }
9545 } catch (RemoteException re) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009546 }
9547 }
9548 } else {
9549 ComponentName componentName = name != null
9550 ? ComponentName.unflattenFromString(name) : null;
9551 int objectId = 0;
9552 if (componentName == null) {
9553 // Not a '/' separated full component name; maybe an object ID?
9554 try {
9555 objectId = Integer.parseInt(name, 16);
9556 name = null;
9557 componentName = null;
9558 } catch (RuntimeException e) {
9559 }
9560 }
9561
9562 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009563 try {
9564 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9565 for (UserInfo user : users) {
9566 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9567 if (componentName != null) {
9568 if (r1.name.equals(componentName)) {
9569 services.add(r1);
9570 }
9571 } else if (name != null) {
9572 if (r1.name.flattenToString().contains(name)) {
9573 services.add(r1);
9574 }
9575 } else if (System.identityHashCode(r1) == objectId) {
9576 services.add(r1);
9577 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009578 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009579 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009580 } catch (RemoteException re) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009581 }
9582 }
9583 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009584
9585 if (services.size() <= 0) {
9586 return false;
9587 }
9588
9589 boolean needSep = false;
9590 for (int i=0; i<services.size(); i++) {
9591 if (needSep) {
9592 pw.println();
9593 }
9594 needSep = true;
9595 dumpService("", fd, pw, services.get(i), args, dumpAll);
9596 }
9597 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009598 }
9599
9600 /**
9601 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9602 * there is a thread associated with the service.
9603 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009604 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9605 final ServiceRecord r, String[] args, boolean dumpAll) {
9606 String innerPrefix = prefix + " ";
9607 synchronized (this) {
9608 pw.print(prefix); pw.print("SERVICE ");
9609 pw.print(r.shortName); pw.print(" ");
9610 pw.print(Integer.toHexString(System.identityHashCode(r)));
9611 pw.print(" pid=");
9612 if (r.app != null) pw.println(r.app.pid);
9613 else pw.println("(not running)");
9614 if (dumpAll) {
9615 r.dump(pw, innerPrefix);
9616 }
9617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009619 pw.print(prefix); pw.println(" Client:");
9620 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009621 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009622 TransferPipe tp = new TransferPipe();
9623 try {
9624 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9625 tp.setBufferPrefix(prefix + " ");
9626 tp.go(fd);
9627 } finally {
9628 tp.kill();
9629 }
9630 } catch (IOException e) {
9631 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009633 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 }
9635 }
9636 }
9637
Marco Nelissen18cb2872011-11-15 11:19:53 -08009638 /**
9639 * There are three ways to call this:
9640 * - no provider specified: dump all the providers
9641 * - a flattened component name that matched an existing provider was specified as the
9642 * first arg: dump that one provider
9643 * - the first arg isn't the flattened component name of an existing provider:
9644 * dump all providers whose component contains the first arg as a substring
9645 */
9646 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9647 int opti, boolean dumpAll) {
9648 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
9649
9650 if ("all".equals(name)) {
9651 synchronized (this) {
9652 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
9653 providers.add(r1);
9654 }
9655 }
9656 } else {
9657 ComponentName componentName = name != null
9658 ? ComponentName.unflattenFromString(name) : null;
9659 int objectId = 0;
9660 if (componentName == null) {
9661 // Not a '/' separated full component name; maybe an object ID?
9662 try {
9663 objectId = Integer.parseInt(name, 16);
9664 name = null;
9665 componentName = null;
9666 } catch (RuntimeException e) {
9667 }
9668 }
9669
9670 synchronized (this) {
9671 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
9672 if (componentName != null) {
9673 if (r1.name.equals(componentName)) {
9674 providers.add(r1);
9675 }
9676 } else if (name != null) {
9677 if (r1.name.flattenToString().contains(name)) {
9678 providers.add(r1);
9679 }
9680 } else if (System.identityHashCode(r1) == objectId) {
9681 providers.add(r1);
9682 }
9683 }
9684 }
9685 }
9686
9687 if (providers.size() <= 0) {
9688 return false;
9689 }
9690
9691 boolean needSep = false;
9692 for (int i=0; i<providers.size(); i++) {
9693 if (needSep) {
9694 pw.println();
9695 }
9696 needSep = true;
9697 dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
9698 }
9699 return true;
9700 }
9701
9702 /**
9703 * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
9704 * there is a thread associated with the provider.
9705 */
9706 private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
9707 final ContentProviderRecord r, String[] args, boolean dumpAll) {
9708 String innerPrefix = prefix + " ";
9709 synchronized (this) {
9710 pw.print(prefix); pw.print("PROVIDER ");
9711 pw.print(r);
9712 pw.print(" pid=");
9713 if (r.proc != null) pw.println(r.proc.pid);
9714 else pw.println("(not running)");
9715 if (dumpAll) {
9716 r.dump(pw, innerPrefix);
9717 }
9718 }
9719 if (r.proc != null && r.proc.thread != null) {
9720 pw.println(" Client:");
9721 pw.flush();
9722 try {
9723 TransferPipe tp = new TransferPipe();
9724 try {
9725 r.proc.thread.dumpProvider(
9726 tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
9727 tp.setBufferPrefix(" ");
9728 // Short timeout, since blocking here can
9729 // deadlock with the application.
9730 tp.go(fd, 2000);
9731 } finally {
9732 tp.kill();
9733 }
9734 } catch (IOException ex) {
9735 pw.println(" Failure while dumping the provider: " + ex);
9736 } catch (RemoteException ex) {
9737 pw.println(" Got a RemoteException while dumping the service");
9738 }
9739 }
9740 }
9741
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009742 static class ItemMatcher {
9743 ArrayList<ComponentName> components;
9744 ArrayList<String> strings;
9745 ArrayList<Integer> objects;
9746 boolean all;
9747
9748 ItemMatcher() {
9749 all = true;
9750 }
9751
9752 void build(String name) {
9753 ComponentName componentName = ComponentName.unflattenFromString(name);
9754 if (componentName != null) {
9755 if (components == null) {
9756 components = new ArrayList<ComponentName>();
9757 }
9758 components.add(componentName);
9759 all = false;
9760 } else {
9761 int objectId = 0;
9762 // Not a '/' separated full component name; maybe an object ID?
9763 try {
9764 objectId = Integer.parseInt(name, 16);
9765 if (objects == null) {
9766 objects = new ArrayList<Integer>();
9767 }
9768 objects.add(objectId);
9769 all = false;
9770 } catch (RuntimeException e) {
9771 // Not an integer; just do string match.
9772 if (strings == null) {
9773 strings = new ArrayList<String>();
9774 }
9775 strings.add(name);
9776 all = false;
9777 }
9778 }
9779 }
9780
9781 int build(String[] args, int opti) {
9782 for (; opti<args.length; opti++) {
9783 String name = args[opti];
9784 if ("--".equals(name)) {
9785 return opti+1;
9786 }
9787 build(name);
9788 }
9789 return opti;
9790 }
9791
9792 boolean match(Object object, ComponentName comp) {
9793 if (all) {
9794 return true;
9795 }
9796 if (components != null) {
9797 for (int i=0; i<components.size(); i++) {
9798 if (components.get(i).equals(comp)) {
9799 return true;
9800 }
9801 }
9802 }
9803 if (objects != null) {
9804 for (int i=0; i<objects.size(); i++) {
9805 if (System.identityHashCode(object) == objects.get(i)) {
9806 return true;
9807 }
9808 }
9809 }
9810 if (strings != null) {
9811 String flat = comp.flattenToString();
9812 for (int i=0; i<strings.size(); i++) {
9813 if (flat.contains(strings.get(i))) {
9814 return true;
9815 }
9816 }
9817 }
9818 return false;
9819 }
9820 }
9821
Dianne Hackborn625ac272010-09-17 18:29:22 -07009822 /**
9823 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009824 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009825 * - the cmd arg isn't the flattened component name of an existing activity:
9826 * dump all activity whose component contains the cmd as a substring
9827 * - A hex number of the ActivityRecord object instance.
9828 */
9829 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9830 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009831 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009832
9833 if ("all".equals(name)) {
9834 synchronized (this) {
9835 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009836 activities.add(r1);
9837 }
9838 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009839 } else if ("top".equals(name)) {
9840 synchronized (this) {
9841 final int N = mMainStack.mHistory.size();
9842 if (N > 0) {
9843 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9844 }
9845 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009846 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009847 ItemMatcher matcher = new ItemMatcher();
9848 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009849
9850 synchronized (this) {
9851 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009852 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009853 activities.add(r1);
9854 }
9855 }
9856 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009857 }
9858
9859 if (activities.size() <= 0) {
9860 return false;
9861 }
9862
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009863 String[] newArgs = new String[args.length - opti];
9864 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9865
Dianne Hackborn30d71892010-12-11 10:37:55 -08009866 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009867 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009868 for (int i=activities.size()-1; i>=0; i--) {
9869 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009870 if (needSep) {
9871 pw.println();
9872 }
9873 needSep = true;
9874 synchronized (this) {
9875 if (lastTask != r.task) {
9876 lastTask = r.task;
9877 pw.print("TASK "); pw.print(lastTask.affinity);
9878 pw.print(" id="); pw.println(lastTask.taskId);
9879 if (dumpAll) {
9880 lastTask.dump(pw, " ");
9881 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009882 }
9883 }
9884 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009885 }
9886 return true;
9887 }
9888
9889 /**
9890 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9891 * there is a thread associated with the activity.
9892 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009893 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009894 final ActivityRecord r, String[] args, boolean dumpAll) {
9895 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009896 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009897 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9898 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9899 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009900 if (r.app != null) pw.println(r.app.pid);
9901 else pw.println("(not running)");
9902 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009903 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009904 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009905 }
9906 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009907 // flush anything that is already in the PrintWriter since the thread is going
9908 // to write to the file descriptor directly
9909 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009910 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009911 TransferPipe tp = new TransferPipe();
9912 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009913 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9914 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009915 tp.go(fd);
9916 } finally {
9917 tp.kill();
9918 }
9919 } catch (IOException e) {
9920 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009921 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009922 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009923 }
9924 }
9925 }
9926
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009927 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009928 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009929 boolean needSep = false;
9930
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009931 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009932 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009934 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009935 Iterator it = mRegisteredReceivers.values().iterator();
9936 while (it.hasNext()) {
9937 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009938 if (dumpPackage != null && (r.app == null ||
9939 !dumpPackage.equals(r.app.info.packageName))) {
9940 continue;
9941 }
9942 if (!printed) {
9943 pw.println(" Registered Receivers:");
9944 needSep = true;
9945 printed = true;
9946 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009947 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 r.dump(pw, " ");
9949 }
9950 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009951
9952 if (mReceiverResolver.dump(pw, needSep ?
9953 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9954 " ", dumpPackage, false)) {
9955 needSep = true;
9956 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009957 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009958
9959 for (BroadcastQueue q : mBroadcastQueues) {
9960 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009962
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009963 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009964
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009965 if (mStickyBroadcasts != null && dumpPackage == null) {
9966 if (needSep) {
9967 pw.println();
9968 }
9969 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009970 pw.println(" Sticky broadcasts:");
9971 StringBuilder sb = new StringBuilder(128);
9972 for (Map.Entry<String, ArrayList<Intent>> ent
9973 : mStickyBroadcasts.entrySet()) {
9974 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009975 if (dumpAll) {
9976 pw.println(":");
9977 ArrayList<Intent> intents = ent.getValue();
9978 final int N = intents.size();
9979 for (int i=0; i<N; i++) {
9980 sb.setLength(0);
9981 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009982 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009983 pw.println(sb.toString());
9984 Bundle bundle = intents.get(i).getExtras();
9985 if (bundle != null) {
9986 pw.print(" ");
9987 pw.println(bundle.toString());
9988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009989 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009990 } else {
9991 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 }
9993 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009994 needSep = true;
9995 }
9996
9997 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009998 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009999 for (BroadcastQueue queue : mBroadcastQueues) {
10000 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
10001 + queue.mBroadcastsScheduled);
10002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 pw.println(" mHandler:");
10004 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010005 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010006 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010007
10008 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 }
10010
Marco Nelissen18cb2872011-11-15 11:19:53 -080010011 /**
10012 * Prints a list of ServiceRecords (dumpsys activity services)
10013 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010014 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010015 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010016 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010017
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010018 ItemMatcher matcher = new ItemMatcher();
10019 matcher.build(args, opti);
10020
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010021 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
Amith Yamasani742a6712011-05-04 14:49:28 -070010022 try {
10023 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
10024 for (UserInfo user : users) {
10025 if (mServiceMap.getAllServices(user.id).size() > 0) {
10026 boolean printed = false;
10027 long nowReal = SystemClock.elapsedRealtime();
10028 Iterator<ServiceRecord> it = mServiceMap.getAllServices(
10029 user.id).iterator();
10030 needSep = false;
10031 while (it.hasNext()) {
10032 ServiceRecord r = it.next();
10033 if (!matcher.match(r, r.name)) {
10034 continue;
10035 }
10036 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10037 continue;
10038 }
10039 if (!printed) {
10040 pw.println(" Active services:");
10041 printed = true;
10042 }
10043 if (needSep) {
10044 pw.println();
10045 }
10046 pw.print(" * ");
10047 pw.println(r);
10048 if (dumpAll) {
10049 r.dump(pw, " ");
10050 needSep = true;
10051 } else {
10052 pw.print(" app=");
10053 pw.println(r.app);
10054 pw.print(" created=");
10055 TimeUtils.formatDuration(r.createTime, nowReal, pw);
10056 pw.print(" started=");
10057 pw.print(r.startRequested);
10058 pw.print(" connections=");
10059 pw.println(r.connections.size());
10060 if (r.connections.size() > 0) {
10061 pw.println(" Connections:");
10062 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
10063 for (int i = 0; i < clist.size(); i++) {
10064 ConnectionRecord conn = clist.get(i);
10065 pw.print(" ");
10066 pw.print(conn.binding.intent.intent.getIntent()
10067 .toShortString(false, false, false));
10068 pw.print(" -> ");
10069 ProcessRecord proc = conn.binding.client;
10070 pw.println(proc != null ? proc.toShortString() : "null");
10071 }
10072 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -080010073 }
10074 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010075 if (dumpClient && r.app != null && r.app.thread != null) {
10076 pw.println(" Client:");
10077 pw.flush();
10078 try {
10079 TransferPipe tp = new TransferPipe();
10080 try {
10081 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
10082 r, args);
10083 tp.setBufferPrefix(" ");
10084 // Short timeout, since blocking here can
10085 // deadlock with the application.
10086 tp.go(fd, 2000);
10087 } finally {
10088 tp.kill();
10089 }
10090 } catch (IOException e) {
10091 pw.println(" Failure while dumping the service: " + e);
10092 } catch (RemoteException e) {
10093 pw.println(" Got a RemoteException while dumping the service");
10094 }
10095 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010096 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010097 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010098 needSep = printed;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010100 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010101 } catch (RemoteException re) {
10102
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010104
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010105 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010106 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010107 for (int i=0; i<mPendingServices.size(); i++) {
10108 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010109 if (!matcher.match(r, r.name)) {
10110 continue;
10111 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010112 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10113 continue;
10114 }
10115 if (!printed) {
10116 if (needSep) pw.println(" ");
10117 needSep = true;
10118 pw.println(" Pending services:");
10119 printed = true;
10120 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010121 pw.print(" * Pending "); pw.println(r);
10122 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010123 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010124 needSep = true;
10125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010127 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010128 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010129 for (int i=0; i<mRestartingServices.size(); i++) {
10130 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010131 if (!matcher.match(r, r.name)) {
10132 continue;
10133 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010134 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10135 continue;
10136 }
10137 if (!printed) {
10138 if (needSep) pw.println(" ");
10139 needSep = true;
10140 pw.println(" Restarting services:");
10141 printed = true;
10142 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010143 pw.print(" * Restarting "); pw.println(r);
10144 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010145 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010146 needSep = true;
10147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010148
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010149 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010150 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010151 for (int i=0; i<mStoppingServices.size(); i++) {
10152 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010153 if (!matcher.match(r, r.name)) {
10154 continue;
10155 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010156 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10157 continue;
10158 }
10159 if (!printed) {
10160 if (needSep) pw.println(" ");
10161 needSep = true;
10162 pw.println(" Stopping services:");
10163 printed = true;
10164 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010165 pw.print(" * Stopping "); pw.println(r);
10166 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010168 needSep = true;
10169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010171 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010172 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010173 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010174 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010175 = mServiceConnections.values().iterator();
10176 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010177 ArrayList<ConnectionRecord> r = it.next();
10178 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010179 ConnectionRecord cr = r.get(i);
10180 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
10181 continue;
10182 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010183 if (dumpPackage != null && (cr.binding.client == null
10184 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
10185 continue;
10186 }
10187 if (!printed) {
10188 if (needSep) pw.println(" ");
10189 needSep = true;
10190 pw.println(" Connection bindings to services:");
10191 printed = true;
10192 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010193 pw.print(" * "); pw.println(cr);
10194 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010197 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010198 }
10199 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010200
10201 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 }
10203
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010204 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010205 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010206 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010207
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010208 ItemMatcher matcher = new ItemMatcher();
10209 matcher.build(args, opti);
10210
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010211 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -070010212
10213 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010214
10215 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010216 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010217 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010218 ContentProviderRecord r = mLaunchingProviders.get(i);
10219 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
10220 continue;
10221 }
10222 if (!printed) {
10223 if (needSep) pw.println(" ");
10224 needSep = true;
10225 pw.println(" Launching content providers:");
10226 printed = true;
10227 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010228 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010229 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010230 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010231 }
10232
10233 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010234 if (needSep) pw.println();
10235 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010236 pw.println("Granted Uri Permissions:");
10237 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
10238 int uid = mGrantedUriPermissions.keyAt(i);
10239 HashMap<Uri, UriPermission> perms
10240 = mGrantedUriPermissions.valueAt(i);
10241 pw.print(" * UID "); pw.print(uid);
10242 pw.println(" holds:");
10243 for (UriPermission perm : perms.values()) {
10244 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010245 if (dumpAll) {
10246 perm.dump(pw, " ");
10247 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010248 }
10249 }
10250 needSep = true;
10251 }
10252
10253 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 }
10255
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010256 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010257 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010258 boolean needSep = false;
10259
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010260 if (mIntentSenderRecords.size() > 0) {
10261 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010262 Iterator<WeakReference<PendingIntentRecord>> it
10263 = mIntentSenderRecords.values().iterator();
10264 while (it.hasNext()) {
10265 WeakReference<PendingIntentRecord> ref = it.next();
10266 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010267 if (dumpPackage != null && (rec == null
10268 || !dumpPackage.equals(rec.key.packageName))) {
10269 continue;
10270 }
10271 if (!printed) {
10272 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
10273 printed = true;
10274 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010275 needSep = true;
10276 if (rec != null) {
10277 pw.print(" * "); pw.println(rec);
10278 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010280 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010281 } else {
10282 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010283 }
10284 }
10285 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010286
10287 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 }
10289
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010290 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010291 String prefix, String label, boolean complete, boolean brief, boolean client,
10292 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010294 boolean needNL = false;
10295 final String innerPrefix = prefix + " ";
10296 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010298 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010299 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
10300 continue;
10301 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -070010302 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010303 if (needNL) {
10304 pw.println(" ");
10305 needNL = false;
10306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 if (lastTask != r.task) {
10308 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010309 pw.print(prefix);
10310 pw.print(full ? "* " : " ");
10311 pw.println(lastTask);
10312 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010313 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010314 } else if (complete) {
10315 // Complete + brief == give a summary. Isn't that obvious?!?
10316 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010317 pw.print(prefix); pw.print(" ");
10318 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010319 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010321 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010322 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
10323 pw.print(" #"); pw.print(i); pw.print(": ");
10324 pw.println(r);
10325 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010326 r.dump(pw, innerPrefix);
10327 } else if (complete) {
10328 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010329 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010330 if (r.app != null) {
10331 pw.print(innerPrefix); pw.println(r.app);
10332 }
10333 }
10334 if (client && r.app != null && r.app.thread != null) {
10335 // flush anything that is already in the PrintWriter since the thread is going
10336 // to write to the file descriptor directly
10337 pw.flush();
10338 try {
10339 TransferPipe tp = new TransferPipe();
10340 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -080010341 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10342 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010343 // Short timeout, since blocking here can
10344 // deadlock with the application.
10345 tp.go(fd, 2000);
10346 } finally {
10347 tp.kill();
10348 }
10349 } catch (IOException e) {
10350 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10351 } catch (RemoteException e) {
10352 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10353 }
10354 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010356 }
10357 }
10358
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010359 private static String buildOomTag(String prefix, String space, int val, int base) {
10360 if (val == base) {
10361 if (space == null) return prefix;
10362 return prefix + " ";
10363 }
10364 return prefix + "+" + Integer.toString(val-base);
10365 }
10366
10367 private static final int dumpProcessList(PrintWriter pw,
10368 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010369 String prefix, String normalLabel, String persistentLabel,
10370 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010371 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010372 final int N = list.size()-1;
10373 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010374 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010375 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10376 continue;
10377 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010378 pw.println(String.format("%s%s #%2d: %s",
10379 prefix, (r.persistent ? persistentLabel : normalLabel),
10380 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010381 if (r.persistent) {
10382 numPers++;
10383 }
10384 }
10385 return numPers;
10386 }
10387
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010388 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -070010389 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -070010390 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010391 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010392
Dianne Hackborn905577f2011-09-07 18:31:28 -070010393 ArrayList<Pair<ProcessRecord, Integer>> list
10394 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10395 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010396 ProcessRecord r = origList.get(i);
10397 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10398 continue;
10399 }
Dianne Hackborn905577f2011-09-07 18:31:28 -070010400 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10401 }
10402
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010403 if (list.size() <= 0) {
10404 return false;
10405 }
10406
Dianne Hackborn905577f2011-09-07 18:31:28 -070010407 Comparator<Pair<ProcessRecord, Integer>> comparator
10408 = new Comparator<Pair<ProcessRecord, Integer>>() {
10409 @Override
10410 public int compare(Pair<ProcessRecord, Integer> object1,
10411 Pair<ProcessRecord, Integer> object2) {
10412 if (object1.first.setAdj != object2.first.setAdj) {
10413 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10414 }
10415 if (object1.second.intValue() != object2.second.intValue()) {
10416 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10417 }
10418 return 0;
10419 }
10420 };
10421
10422 Collections.sort(list, comparator);
10423
Dianne Hackborn287952c2010-09-22 22:34:31 -070010424 final long curRealtime = SystemClock.elapsedRealtime();
10425 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10426 final long curUptime = SystemClock.uptimeMillis();
10427 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10428
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010429 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070010430 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010431 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010432 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070010433 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010434 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10435 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010436 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10437 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010438 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10439 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010440 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10441 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010442 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010443 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010444 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10445 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10446 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10447 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10448 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10449 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10450 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10451 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010452 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10453 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010454 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10455 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010456 } else {
10457 oomAdj = Integer.toString(r.setAdj);
10458 }
10459 String schedGroup;
10460 switch (r.setSchedGroup) {
10461 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10462 schedGroup = "B";
10463 break;
10464 case Process.THREAD_GROUP_DEFAULT:
10465 schedGroup = "F";
10466 break;
10467 default:
10468 schedGroup = Integer.toString(r.setSchedGroup);
10469 break;
10470 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010471 String foreground;
10472 if (r.foregroundActivities) {
10473 foreground = "A";
10474 } else if (r.foregroundServices) {
10475 foreground = "S";
10476 } else {
10477 foreground = " ";
10478 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010479 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -070010480 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010481 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10482 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -070010483 if (r.adjSource != null || r.adjTarget != null) {
10484 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010485 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070010486 if (r.adjTarget instanceof ComponentName) {
10487 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10488 } else if (r.adjTarget != null) {
10489 pw.print(r.adjTarget.toString());
10490 } else {
10491 pw.print("{null}");
10492 }
10493 pw.print("<=");
10494 if (r.adjSource instanceof ProcessRecord) {
10495 pw.print("Proc{");
10496 pw.print(((ProcessRecord)r.adjSource).toShortString());
10497 pw.println("}");
10498 } else if (r.adjSource != null) {
10499 pw.println(r.adjSource.toString());
10500 } else {
10501 pw.println("{null}");
10502 }
10503 }
10504 if (inclDetails) {
10505 pw.print(prefix);
10506 pw.print(" ");
10507 pw.print("oom: max="); pw.print(r.maxAdj);
10508 pw.print(" hidden="); pw.print(r.hiddenAdj);
10509 pw.print(" curRaw="); pw.print(r.curRawAdj);
10510 pw.print(" setRaw="); pw.print(r.setRawAdj);
10511 pw.print(" cur="); pw.print(r.curAdj);
10512 pw.print(" set="); pw.println(r.setAdj);
10513 pw.print(prefix);
10514 pw.print(" ");
10515 pw.print("keeping="); pw.print(r.keeping);
10516 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010517 pw.print(" empty="); pw.print(r.empty);
10518 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010519
10520 if (!r.keeping) {
10521 if (r.lastWakeTime != 0) {
10522 long wtime;
10523 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10524 synchronized (stats) {
10525 wtime = stats.getProcessWakeTime(r.info.uid,
10526 r.pid, curRealtime);
10527 }
10528 long timeUsed = wtime - r.lastWakeTime;
10529 pw.print(prefix);
10530 pw.print(" ");
10531 pw.print("keep awake over ");
10532 TimeUtils.formatDuration(realtimeSince, pw);
10533 pw.print(" used ");
10534 TimeUtils.formatDuration(timeUsed, pw);
10535 pw.print(" (");
10536 pw.print((timeUsed*100)/realtimeSince);
10537 pw.println("%)");
10538 }
10539 if (r.lastCpuTime != 0) {
10540 long timeUsed = r.curCpuTime - r.lastCpuTime;
10541 pw.print(prefix);
10542 pw.print(" ");
10543 pw.print("run cpu over ");
10544 TimeUtils.formatDuration(uptimeSince, pw);
10545 pw.print(" used ");
10546 TimeUtils.formatDuration(timeUsed, pw);
10547 pw.print(" (");
10548 pw.print((timeUsed*100)/uptimeSince);
10549 pw.println("%)");
10550 }
10551 }
10552 }
10553 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010554 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010555 }
10556
Dianne Hackbornb437e092011-08-05 17:50:29 -070010557 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010558 ArrayList<ProcessRecord> procs;
10559 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010560 if (args != null && args.length > start
10561 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010562 procs = new ArrayList<ProcessRecord>();
10563 int pid = -1;
10564 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010565 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010566 } catch (NumberFormatException e) {
10567
10568 }
10569 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10570 ProcessRecord proc = mLruProcesses.get(i);
10571 if (proc.pid == pid) {
10572 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010573 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010574 procs.add(proc);
10575 }
10576 }
10577 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010578 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010579 return null;
10580 }
10581 } else {
10582 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10583 }
10584 }
10585 return procs;
10586 }
10587
10588 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10589 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010590 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010591 if (procs == null) {
10592 return;
10593 }
10594
10595 long uptime = SystemClock.uptimeMillis();
10596 long realtime = SystemClock.elapsedRealtime();
10597 pw.println("Applications Graphics Acceleration Info:");
10598 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10599
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010600 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10601 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010602 if (r.thread != null) {
10603 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10604 pw.flush();
10605 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010606 TransferPipe tp = new TransferPipe();
10607 try {
10608 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10609 tp.go(fd);
10610 } finally {
10611 tp.kill();
10612 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010613 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010614 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010615 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -070010616 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010617 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010618 pw.flush();
10619 }
10620 }
10621 }
Chet Haase9c1e23b2011-03-24 10:51:31 -070010622 }
10623
Jeff Brown6754ba22011-12-14 20:20:01 -080010624 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10625 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10626 if (procs == null) {
10627 return;
10628 }
10629
10630 pw.println("Applications Database Info:");
10631
10632 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10633 ProcessRecord r = procs.get(i);
10634 if (r.thread != null) {
10635 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10636 pw.flush();
10637 try {
10638 TransferPipe tp = new TransferPipe();
10639 try {
10640 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10641 tp.go(fd);
10642 } finally {
10643 tp.kill();
10644 }
10645 } catch (IOException e) {
10646 pw.println("Failure while dumping the app: " + r);
10647 pw.flush();
10648 } catch (RemoteException e) {
10649 pw.println("Got a RemoteException while dumping the app " + r);
10650 pw.flush();
10651 }
10652 }
10653 }
10654 }
10655
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010656 final static class MemItem {
10657 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010658 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010659 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010660 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010661 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010662
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010663 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010664 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010665 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010666 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010667 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010668 }
10669 }
10670
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010671 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010672 boolean sort) {
10673 if (sort) {
10674 Collections.sort(items, new Comparator<MemItem>() {
10675 @Override
10676 public int compare(MemItem lhs, MemItem rhs) {
10677 if (lhs.pss < rhs.pss) {
10678 return 1;
10679 } else if (lhs.pss > rhs.pss) {
10680 return -1;
10681 }
10682 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010683 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010684 });
10685 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010686
10687 for (int i=0; i<items.size(); i++) {
10688 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010689 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010690 if (mi.subitems != null) {
10691 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10692 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010693 }
10694 }
10695
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010696 // These are in KB.
10697 static final long[] DUMP_MEM_BUCKETS = new long[] {
10698 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10699 120*1024, 160*1024, 200*1024,
10700 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10701 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10702 };
10703
Dianne Hackborn672342c2011-11-29 11:29:02 -080010704 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10705 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010706 int start = label.lastIndexOf('.');
10707 if (start >= 0) start++;
10708 else start = 0;
10709 int end = label.length();
10710 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10711 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10712 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10713 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010714 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010715 out.append(label, start, end);
10716 return;
10717 }
10718 }
10719 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010720 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010721 out.append(label, start, end);
10722 }
10723
10724 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10725 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10726 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10727 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10728 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10729 };
10730 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10731 "System", "Persistent", "Foreground",
10732 "Visible", "Perceptible", "Heavy Weight",
10733 "Backup", "A Services", "Home", "Previous",
10734 "B Services", "Background"
10735 };
10736
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010737 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010738 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010739 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010740 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010741 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010742
10743 int opti = 0;
10744 while (opti < args.length) {
10745 String opt = args[opti];
10746 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10747 break;
10748 }
10749 opti++;
10750 if ("-a".equals(opt)) {
10751 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010752 } else if ("--oom".equals(opt)) {
10753 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010754 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010755 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010756 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010757 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010758 pw.println("If [process] is specified it can be the name or ");
10759 pw.println("pid of a specific process to dump.");
10760 return;
10761 } else {
10762 pw.println("Unknown argument: " + opt + "; use -h for help");
10763 }
10764 }
10765
10766 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010767 if (procs == null) {
10768 return;
10769 }
10770
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010771 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772 long uptime = SystemClock.uptimeMillis();
10773 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010774
10775 if (procs.size() == 1 || isCheckinRequest) {
10776 dumpAll = true;
10777 }
10778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 if (isCheckinRequest) {
10780 // short checkin version
10781 pw.println(uptime + "," + realtime);
10782 pw.flush();
10783 } else {
10784 pw.println("Applications Memory Usage (kB):");
10785 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10786 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010787
Dianne Hackbornb437e092011-08-05 17:50:29 -070010788 String[] innerArgs = new String[args.length-opti];
10789 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10790
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010791 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10792 long nativePss=0, dalvikPss=0, otherPss=0;
10793 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10794
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010795 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10796 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10797 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010798
10799 long totalPss = 0;
10800
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010801 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10802 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010803 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010804 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10806 pw.flush();
10807 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010808 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010809 if (dumpAll) {
10810 try {
10811 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10812 } catch (RemoteException e) {
10813 if (!isCheckinRequest) {
10814 pw.println("Got RemoteException!");
10815 pw.flush();
10816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010818 } else {
10819 mi = new Debug.MemoryInfo();
10820 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010821 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010822
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010823 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010824 long myTotalPss = mi.getTotalPss();
10825 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010826 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010827 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010828 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010829
10830 nativePss += mi.nativePss;
10831 dalvikPss += mi.dalvikPss;
10832 otherPss += mi.otherPss;
10833 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10834 long mem = mi.getOtherPss(j);
10835 miscPss[j] += mem;
10836 otherPss -= mem;
10837 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010838
10839 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010840 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10841 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010842 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010843 if (oomProcs[oomIndex] == null) {
10844 oomProcs[oomIndex] = new ArrayList<MemItem>();
10845 }
10846 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010847 break;
10848 }
10849 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 }
10852 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010853
10854 if (!isCheckinRequest && procs.size() > 1) {
10855 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10856
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010857 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10858 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10859 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010860 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010861 String label = Debug.MemoryInfo.getOtherLabel(j);
10862 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010863 }
10864
Dianne Hackbornb437e092011-08-05 17:50:29 -070010865 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10866 for (int j=0; j<oomPss.length; j++) {
10867 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010868 String label = DUMP_MEM_OOM_LABEL[j];
10869 MemItem item = new MemItem(label, label, oomPss[j],
10870 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010871 item.subitems = oomProcs[j];
10872 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010873 }
10874 }
10875
Dianne Hackborn672342c2011-11-29 11:29:02 -080010876 if (outTag != null || outStack != null) {
10877 if (outTag != null) {
10878 appendMemBucket(outTag, totalPss, "total", false);
10879 }
10880 if (outStack != null) {
10881 appendMemBucket(outStack, totalPss, "total", true);
10882 }
10883 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010884 for (int i=0; i<oomMems.size(); i++) {
10885 MemItem miCat = oomMems.get(i);
10886 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10887 continue;
10888 }
10889 if (miCat.id < ProcessList.SERVICE_ADJ
10890 || miCat.id == ProcessList.HOME_APP_ADJ
10891 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010892 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10893 outTag.append(" / ");
10894 }
10895 if (outStack != null) {
10896 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10897 if (firstLine) {
10898 outStack.append(":");
10899 firstLine = false;
10900 }
10901 outStack.append("\n\t at ");
10902 } else {
10903 outStack.append("$");
10904 }
10905 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010906 for (int j=0; j<miCat.subitems.size(); j++) {
10907 MemItem mi = miCat.subitems.get(j);
10908 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010909 if (outTag != null) {
10910 outTag.append(" ");
10911 }
10912 if (outStack != null) {
10913 outStack.append("$");
10914 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010915 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010916 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10917 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10918 }
10919 if (outStack != null) {
10920 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10921 }
10922 }
10923 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10924 outStack.append("(");
10925 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10926 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10927 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10928 outStack.append(":");
10929 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10930 }
10931 }
10932 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010933 }
10934 }
10935 }
10936 }
10937
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010938 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010939 pw.println();
10940 pw.println("Total PSS by process:");
10941 dumpMemItems(pw, " ", procMems, true);
10942 pw.println();
10943 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010944 pw.println("Total PSS by OOM adjustment:");
10945 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010946 if (!oomOnly) {
10947 PrintWriter out = categoryPw != null ? categoryPw : pw;
10948 out.println();
10949 out.println("Total PSS by category:");
10950 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010951 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010952 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010953 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 }
10956
10957 /**
10958 * Searches array of arguments for the specified string
10959 * @param args array of argument strings
10960 * @param value value to search for
10961 * @return true if the value is contained in the array
10962 */
10963 private static boolean scanArgs(String[] args, String value) {
10964 if (args != null) {
10965 for (String arg : args) {
10966 if (value.equals(arg)) {
10967 return true;
10968 }
10969 }
10970 }
10971 return false;
10972 }
10973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 private final void killServicesLocked(ProcessRecord app,
10975 boolean allowRestart) {
10976 // Report disconnected services.
10977 if (false) {
10978 // XXX we are letting the client link to the service for
10979 // death notifications.
10980 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010981 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010982 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010983 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010984 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010985 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010986 = r.connections.values().iterator();
10987 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010988 ArrayList<ConnectionRecord> cl = jt.next();
10989 for (int i=0; i<cl.size(); i++) {
10990 ConnectionRecord c = cl.get(i);
10991 if (c.binding.client != app) {
10992 try {
10993 //c.conn.connected(r.className, null);
10994 } catch (Exception e) {
10995 // todo: this should be asynchronous!
10996 Slog.w(TAG, "Exception thrown disconnected servce "
10997 + r.shortName
10998 + " from app " + app.processName, e);
10999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011000 }
11001 }
11002 }
11003 }
11004 }
11005 }
11006 }
11007
11008 // Clean up any connections this application has to other services.
11009 if (app.connections.size() > 0) {
11010 Iterator<ConnectionRecord> it = app.connections.iterator();
11011 while (it.hasNext()) {
11012 ConnectionRecord r = it.next();
11013 removeConnectionLocked(r, app, null);
11014 }
11015 }
11016 app.connections.clear();
11017
11018 if (app.services.size() != 0) {
11019 // Any services running in the application need to be placed
11020 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070011021 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011022 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011023 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 synchronized (sr.stats.getBatteryStats()) {
11025 sr.stats.stopLaunchedLocked();
11026 }
11027 sr.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011028 sr.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011029 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011030 if (mStoppingServices.remove(sr)) {
11031 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
11032 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011033
11034 boolean hasClients = sr.bindings.size() > 0;
11035 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011036 Iterator<IntentBindRecord> bindings
11037 = sr.bindings.values().iterator();
11038 while (bindings.hasNext()) {
11039 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011040 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011041 + ": shouldUnbind=" + b.hasBound);
11042 b.binder = null;
11043 b.requested = b.received = b.hasBound = false;
11044 }
11045 }
11046
Dianne Hackborn070783f2010-12-29 16:46:28 -080011047 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
11048 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011049 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011051 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011052 sr.crashCount, sr.shortName, app.pid);
11053 bringDownServiceLocked(sr, true);
11054 } else if (!allowRestart) {
11055 bringDownServiceLocked(sr, true);
11056 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011057 boolean canceled = scheduleServiceRestartLocked(sr, true);
11058
11059 // Should the service remain running? Note that in the
11060 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011061 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011062 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
11063 if (sr.pendingStarts.size() == 0) {
11064 sr.startRequested = false;
11065 if (!hasClients) {
11066 // Whoops, no reason to restart!
11067 bringDownServiceLocked(sr, true);
11068 }
11069 }
11070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011071 }
11072 }
11073
11074 if (!allowRestart) {
11075 app.services.clear();
11076 }
11077 }
11078
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011079 // Make sure we have no more records on the stopping list.
11080 int i = mStoppingServices.size();
11081 while (i > 0) {
11082 i--;
11083 ServiceRecord sr = mStoppingServices.get(i);
11084 if (sr.app == app) {
11085 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011086 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011087 }
11088 }
11089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011090 app.executingServices.clear();
11091 }
11092
11093 private final void removeDyingProviderLocked(ProcessRecord proc,
11094 ContentProviderRecord cpr) {
11095 synchronized (cpr) {
11096 cpr.launchingApp = null;
11097 cpr.notifyAll();
11098 }
11099
Amith Yamasani742a6712011-05-04 14:49:28 -070011100 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011101 String names[] = cpr.info.authority.split(";");
11102 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011103 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011104 }
11105
11106 Iterator<ProcessRecord> cit = cpr.clients.iterator();
11107 while (cit.hasNext()) {
11108 ProcessRecord capp = cit.next();
11109 if (!capp.persistent && capp.thread != null
11110 && capp.pid != 0
11111 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011112 Slog.i(TAG, "Kill " + capp.processName
11113 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011114 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070011115 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011116 capp.processName, capp.setAdj, "dying provider "
11117 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011118 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 }
11120 }
11121
11122 mLaunchingProviders.remove(cpr);
11123 }
11124
11125 /**
11126 * Main code for cleaning up a process when it has gone away. This is
11127 * called both as a result of the process dying, or directly when stopping
11128 * a process when running in single process mode.
11129 */
11130 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011131 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011133 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011134 }
11135
Dianne Hackborn36124872009-10-08 16:22:03 -070011136 mProcessesToGc.remove(app);
11137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011138 // Dismiss any open dialogs.
11139 if (app.crashDialog != null) {
11140 app.crashDialog.dismiss();
11141 app.crashDialog = null;
11142 }
11143 if (app.anrDialog != null) {
11144 app.anrDialog.dismiss();
11145 app.anrDialog = null;
11146 }
11147 if (app.waitDialog != null) {
11148 app.waitDialog.dismiss();
11149 app.waitDialog = null;
11150 }
11151
11152 app.crashing = false;
11153 app.notResponding = false;
11154
11155 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070011156 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011157 app.thread = null;
11158 app.forcingToForeground = null;
11159 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011160 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070011161 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011162 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011163
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011164 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165
11166 boolean restart = false;
11167
11168 int NL = mLaunchingProviders.size();
11169
11170 // Remove published content providers.
11171 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011172 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011173 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011174 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011176 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011177
11178 // See if someone is waiting for this provider... in which
11179 // case we don't remove it, but just let it restart.
11180 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011181 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 for (; i<NL; i++) {
11183 if (mLaunchingProviders.get(i) == cpr) {
11184 restart = true;
11185 break;
11186 }
11187 }
11188 } else {
11189 i = NL;
11190 }
11191
11192 if (i >= NL) {
11193 removeDyingProviderLocked(app, cpr);
11194 NL = mLaunchingProviders.size();
11195 }
11196 }
11197 app.pubProviders.clear();
11198 }
11199
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011200 // Take care of any launching providers waiting for this process.
11201 if (checkAppInLaunchingProvidersLocked(app, false)) {
11202 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011203 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011205 // Unregister from connected content providers.
11206 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070011207 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011208 while (it.hasNext()) {
11209 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
11210 cpr.clients.remove(app);
11211 }
11212 app.conProviders.clear();
11213 }
11214
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011215 // At this point there may be remaining entries in mLaunchingProviders
11216 // where we were the only one waiting, so they are no longer of use.
11217 // Look for these and clean up if found.
11218 // XXX Commented out for now. Trying to figure out a way to reproduce
11219 // the actual situation to identify what is actually going on.
11220 if (false) {
11221 for (int i=0; i<NL; i++) {
11222 ContentProviderRecord cpr = (ContentProviderRecord)
11223 mLaunchingProviders.get(i);
11224 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
11225 synchronized (cpr) {
11226 cpr.launchingApp = null;
11227 cpr.notifyAll();
11228 }
11229 }
11230 }
11231 }
11232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011233 skipCurrentReceiverLocked(app);
11234
11235 // Unregister any receivers.
11236 if (app.receivers.size() > 0) {
11237 Iterator<ReceiverList> it = app.receivers.iterator();
11238 while (it.hasNext()) {
11239 removeReceiverLocked(it.next());
11240 }
11241 app.receivers.clear();
11242 }
11243
Christopher Tate181fafa2009-05-14 11:12:14 -070011244 // If the app is undergoing backup, tell the backup manager about it
11245 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011246 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070011247 try {
11248 IBackupManager bm = IBackupManager.Stub.asInterface(
11249 ServiceManager.getService(Context.BACKUP_SERVICE));
11250 bm.agentDisconnected(app.info.packageName);
11251 } catch (RemoteException e) {
11252 // can't happen; backup manager is local
11253 }
11254 }
11255
Jeff Sharkey287bd832011-05-28 19:36:26 -070011256 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011258 // If the caller is restarting this app, then leave it in its
11259 // current lists and let the caller take care of it.
11260 if (restarting) {
11261 return;
11262 }
11263
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011264 if (!app.persistent || app.isolated) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011265 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011266 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011267 mProcessNames.remove(app.processName, app.uid);
11268 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070011269 if (mHeavyWeightProcess == app) {
11270 mHeavyWeightProcess = null;
11271 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
11272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011273 } else if (!app.removed) {
11274 // This app is persistent, so we need to keep its record around.
11275 // If it is not already on the pending app list, add it there
11276 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011277 if (mPersistentStartingProcesses.indexOf(app) < 0) {
11278 mPersistentStartingProcesses.add(app);
11279 restart = true;
11280 }
11281 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011282 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
11283 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011284 mProcessesOnHold.remove(app);
11285
The Android Open Source Project4df24232009-03-05 14:34:35 -080011286 if (app == mHomeProcess) {
11287 mHomeProcess = null;
11288 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070011289 if (app == mPreviousProcess) {
11290 mPreviousProcess = null;
11291 }
11292
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011293 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011294 // We have components that still need to be running in the
11295 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011296 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011297 startProcessLocked(app, "restart", app.processName);
11298 } else if (app.pid > 0 && app.pid != MY_PID) {
11299 // Goodbye!
11300 synchronized (mPidsSelfLocked) {
11301 mPidsSelfLocked.remove(app.pid);
11302 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
11303 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070011304 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011305 }
11306 }
11307
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011308 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
11309 // Look through the content providers we are waiting to have launched,
11310 // and if any run in this process then either schedule a restart of
11311 // the process or kill the client waiting for it if this process has
11312 // gone bad.
11313 int NL = mLaunchingProviders.size();
11314 boolean restart = false;
11315 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011316 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011317 if (cpr.launchingApp == app) {
11318 if (!alwaysBad && !app.bad) {
11319 restart = true;
11320 } else {
11321 removeDyingProviderLocked(app, cpr);
11322 NL = mLaunchingProviders.size();
11323 }
11324 }
11325 }
11326 return restart;
11327 }
11328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011329 // =========================================================
11330 // SERVICES
11331 // =========================================================
11332
11333 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
11334 ActivityManager.RunningServiceInfo info =
11335 new ActivityManager.RunningServiceInfo();
11336 info.service = r.name;
11337 if (r.app != null) {
11338 info.pid = r.app.pid;
11339 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011340 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011341 info.process = r.processName;
11342 info.foreground = r.isForeground;
11343 info.activeSince = r.createTime;
11344 info.started = r.startRequested;
11345 info.clientCount = r.connections.size();
11346 info.crashCount = r.crashCount;
11347 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011348 if (r.isForeground) {
11349 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
11350 }
11351 if (r.startRequested) {
11352 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
11353 }
Dan Egnor42471dd2010-01-07 17:25:22 -080011354 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011355 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
11356 }
11357 if (r.app != null && r.app.persistent) {
11358 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
11359 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011360
11361 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
11362 for (int i=0; i<connl.size(); i++) {
11363 ConnectionRecord conn = connl.get(i);
11364 if (conn.clientLabel != 0) {
11365 info.clientPackage = conn.binding.client.info.packageName;
11366 info.clientLabel = conn.clientLabel;
11367 return info;
11368 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011369 }
11370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 return info;
11372 }
11373
11374 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11375 int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011376 enforceNotIsolatedCaller("getServices");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011377 synchronized (this) {
11378 ArrayList<ActivityManager.RunningServiceInfo> res
11379 = new ArrayList<ActivityManager.RunningServiceInfo>();
11380
Amith Yamasani742a6712011-05-04 14:49:28 -070011381 int userId = UserId.getUserId(Binder.getCallingUid());
11382 if (mServiceMap.getAllServices(userId).size() > 0) {
11383 Iterator<ServiceRecord> it
11384 = mServiceMap.getAllServices(userId).iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011385 while (it.hasNext() && res.size() < maxNum) {
11386 res.add(makeRunningServiceInfoLocked(it.next()));
11387 }
11388 }
11389
11390 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11391 ServiceRecord r = mRestartingServices.get(i);
11392 ActivityManager.RunningServiceInfo info =
11393 makeRunningServiceInfoLocked(r);
11394 info.restarting = r.nextRestartTime;
11395 res.add(info);
11396 }
11397
11398 return res;
11399 }
11400 }
11401
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011402 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011403 enforceNotIsolatedCaller("getRunningServiceControlPanel");
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011404 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011405 int userId = UserId.getUserId(Binder.getCallingUid());
11406 ServiceRecord r = mServiceMap.getServiceByName(name, userId);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011407 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011408 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11409 for (int i=0; i<conn.size(); i++) {
11410 if (conn.get(i).clientIntent != null) {
11411 return conn.get(i).clientIntent;
11412 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011413 }
11414 }
11415 }
11416 }
11417 return null;
11418 }
11419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011420 private final ServiceRecord findServiceLocked(ComponentName name,
11421 IBinder token) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011422 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011423 return r == token ? r : null;
11424 }
11425
11426 private final class ServiceLookupResult {
11427 final ServiceRecord record;
11428 final String permission;
11429
11430 ServiceLookupResult(ServiceRecord _record, String _permission) {
11431 record = _record;
11432 permission = _permission;
11433 }
11434 };
11435
11436 private ServiceLookupResult findServiceLocked(Intent service,
11437 String resolvedType) {
11438 ServiceRecord r = null;
11439 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011440 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011441 }
11442 if (r == null) {
11443 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani742a6712011-05-04 14:49:28 -070011444 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011445 }
11446
11447 if (r == null) {
11448 try {
11449 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011450 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451 service, resolvedType, 0);
11452 ServiceInfo sInfo =
11453 rInfo != null ? rInfo.serviceInfo : null;
11454 if (sInfo == null) {
11455 return null;
11456 }
11457
11458 ComponentName name = new ComponentName(
11459 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011460 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011461 } catch (RemoteException ex) {
11462 // pm is in same process, this will never happen.
11463 }
11464 }
11465 if (r != null) {
11466 int callingPid = Binder.getCallingPid();
11467 int callingUid = Binder.getCallingUid();
11468 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011469 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011470 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011471 if (!r.exported) {
11472 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11473 + " from pid=" + callingPid
11474 + ", uid=" + callingUid
11475 + " that is not exported from uid " + r.appInfo.uid);
11476 return new ServiceLookupResult(null, "not exported from uid "
11477 + r.appInfo.uid);
11478 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011479 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011480 + " from pid=" + callingPid
11481 + ", uid=" + callingUid
11482 + " requires " + r.permission);
11483 return new ServiceLookupResult(null, r.permission);
11484 }
11485 return new ServiceLookupResult(r, null);
11486 }
11487 return null;
11488 }
11489
11490 private class ServiceRestarter implements Runnable {
11491 private ServiceRecord mService;
11492
11493 void setService(ServiceRecord service) {
11494 mService = service;
11495 }
11496
11497 public void run() {
11498 synchronized(ActivityManagerService.this) {
11499 performServiceRestartLocked(mService);
11500 }
11501 }
11502 }
11503
11504 private ServiceLookupResult retrieveServiceLocked(Intent service,
11505 String resolvedType, int callingPid, int callingUid) {
11506 ServiceRecord r = null;
Amith Yamasani742a6712011-05-04 14:49:28 -070011507 if (DEBUG_SERVICE)
11508 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
11509 + " origCallingUid=" + callingUid);
11510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011511 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011512 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011513 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011514 if (r == null) {
11515 Intent.FilterComparison filter = new Intent.FilterComparison(service);
11516 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
11517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011518 if (r == null) {
11519 try {
11520 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011521 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011522 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011523 ServiceInfo sInfo =
11524 rInfo != null ? rInfo.serviceInfo : null;
11525 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011526 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011527 ": not found");
11528 return null;
11529 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011530 if (Binder.getOrigCallingUser() > 0) {
11531 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo,
11532 Binder.getOrigCallingUser());
11533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011534 ComponentName name = new ComponentName(
11535 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011536 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011537 if (r == null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011538 Intent.FilterComparison filter = new Intent.FilterComparison(
11539 service.cloneFilter());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011540 ServiceRestarter res = new ServiceRestarter();
11541 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11542 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11543 synchronized (stats) {
11544 ss = stats.getServiceStatsLocked(
11545 sInfo.applicationInfo.uid, sInfo.packageName,
11546 sInfo.name);
11547 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080011548 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011549 res.setService(r);
Amith Yamasani742a6712011-05-04 14:49:28 -070011550 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11551 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011552
11553 // Make sure this component isn't in the pending list.
11554 int N = mPendingServices.size();
11555 for (int i=0; i<N; i++) {
11556 ServiceRecord pr = mPendingServices.get(i);
11557 if (pr.name.equals(name)) {
11558 mPendingServices.remove(i);
11559 i--;
11560 N--;
11561 }
11562 }
11563 }
11564 } catch (RemoteException ex) {
11565 // pm is in same process, this will never happen.
11566 }
11567 }
11568 if (r != null) {
11569 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011570 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011571 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011572 if (!r.exported) {
11573 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11574 + " from pid=" + callingPid
11575 + ", uid=" + callingUid
11576 + " that is not exported from uid " + r.appInfo.uid);
11577 return new ServiceLookupResult(null, "not exported from uid "
11578 + r.appInfo.uid);
11579 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011580 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011581 + " from pid=" + callingPid
11582 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583 + " requires " + r.permission);
11584 return new ServiceLookupResult(null, r.permission);
11585 }
11586 return new ServiceLookupResult(r, null);
11587 }
11588 return null;
11589 }
11590
Dianne Hackborn287952c2010-09-22 22:34:31 -070011591 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11592 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11593 + why + " of " + r + " in app " + r.app);
11594 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11595 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011596 long now = SystemClock.uptimeMillis();
11597 if (r.executeNesting == 0 && r.app != null) {
11598 if (r.app.executingServices.size() == 0) {
11599 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11600 msg.obj = r.app;
11601 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11602 }
11603 r.app.executingServices.add(r);
11604 }
11605 r.executeNesting++;
11606 r.executingStart = now;
11607 }
11608
11609 private final void sendServiceArgsLocked(ServiceRecord r,
11610 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011611 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011612 if (N == 0) {
11613 return;
11614 }
11615
Dianne Hackborn39792d22010-08-19 18:01:52 -070011616 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011617 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011618 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011619 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11620 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011621 if (si.intent == null && N > 1) {
11622 // If somehow we got a dummy null intent in the middle,
11623 // then skip it. DO NOT skip a null intent when it is
11624 // the only one in the list -- this is to support the
11625 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011626 continue;
11627 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070011628 si.deliveredTime = SystemClock.uptimeMillis();
11629 r.deliveredStarts.add(si);
11630 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011631 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011632 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070011633 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070011634 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070011635 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011636 if (!oomAdjusted) {
11637 oomAdjusted = true;
11638 updateOomAdjLocked(r.app);
11639 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011640 int flags = 0;
11641 if (si.deliveryCount > 0) {
11642 flags |= Service.START_FLAG_RETRY;
11643 }
11644 if (si.doneExecutingCount > 0) {
11645 flags |= Service.START_FLAG_REDELIVERY;
11646 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011647 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011648 } catch (RemoteException e) {
11649 // Remote process gone... we'll let the normal cleanup take
11650 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011651 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011652 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011653 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011654 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 break;
11656 }
11657 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011658 }
11659
11660 private final boolean requestServiceBindingLocked(ServiceRecord r,
11661 IntentBindRecord i, boolean rebind) {
11662 if (r.app == null || r.app.thread == null) {
11663 // If service is not currently running, can't yet bind.
11664 return false;
11665 }
11666 if ((!i.requested || rebind) && i.apps.size() > 0) {
11667 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011668 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11670 if (!rebind) {
11671 i.requested = true;
11672 }
11673 i.hasBound = true;
11674 i.doRebind = false;
11675 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011676 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 return false;
11678 }
11679 }
11680 return true;
11681 }
11682
11683 private final void requestServiceBindingsLocked(ServiceRecord r) {
11684 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11685 while (bindings.hasNext()) {
11686 IntentBindRecord i = bindings.next();
11687 if (!requestServiceBindingLocked(r, i, false)) {
11688 break;
11689 }
11690 }
11691 }
11692
11693 private final void realStartServiceLocked(ServiceRecord r,
11694 ProcessRecord app) throws RemoteException {
11695 if (app.thread == null) {
11696 throw new RemoteException();
11697 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011698 if (DEBUG_MU)
11699 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011700 + ", ProcessRecord.uid = " + app.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011701 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070011702 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703
11704 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011705 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011706 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011707
11708 boolean created = false;
11709 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011710 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070011711 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011712 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011713 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011714 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011715 synchronized (r.stats.getBatteryStats()) {
11716 r.stats.startLaunchedLocked();
11717 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011718 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011719 app.thread.scheduleCreateService(r, r.serviceInfo,
11720 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011721 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011722 created = true;
11723 } finally {
11724 if (!created) {
11725 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011726 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011727 }
11728 }
11729
11730 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011731
11732 // If the service is in the started state, and there are no
11733 // pending arguments, then fake up one so its onStartCommand() will
11734 // be called.
11735 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011736 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11737 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011738 }
11739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011740 sendServiceArgsLocked(r, true);
11741 }
11742
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011743 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11744 boolean allowCancel) {
11745 boolean canceled = false;
11746
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011747 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011748 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070011749 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011750
Dianne Hackborn070783f2010-12-29 16:46:28 -080011751 if ((r.serviceInfo.applicationInfo.flags
11752 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11753 minDuration /= 4;
11754 }
11755
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011756 // Any delivered but not yet finished starts should be put back
11757 // on the pending list.
11758 final int N = r.deliveredStarts.size();
11759 if (N > 0) {
11760 for (int i=N-1; i>=0; i--) {
11761 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070011762 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011763 if (si.intent == null) {
11764 // We'll generate this again if needed.
11765 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11766 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11767 r.pendingStarts.add(0, si);
11768 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11769 dur *= 2;
11770 if (minDuration < dur) minDuration = dur;
11771 if (resetTime < dur) resetTime = dur;
11772 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011773 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011774 + r.name);
11775 canceled = true;
11776 }
11777 }
11778 r.deliveredStarts.clear();
11779 }
11780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011781 r.totalRestartCount++;
11782 if (r.restartDelay == 0) {
11783 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011784 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011785 } else {
11786 // If it has been a "reasonably long time" since the service
11787 // was started, then reset our restart duration back to
11788 // the beginning, so we don't infinitely increase the duration
11789 // on a service that just occasionally gets killed (which is
11790 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011791 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011792 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011793 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011794 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080011795 if ((r.serviceInfo.applicationInfo.flags
11796 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11797 // Services in peristent processes will restart much more
11798 // quickly, since they are pretty important. (Think SystemUI).
11799 r.restartDelay += minDuration/2;
11800 } else {
11801 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11802 if (r.restartDelay < minDuration) {
11803 r.restartDelay = minDuration;
11804 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011806 }
11807 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011808
11809 r.nextRestartTime = now + r.restartDelay;
11810
11811 // Make sure that we don't end up restarting a bunch of services
11812 // all at the same time.
11813 boolean repeat;
11814 do {
11815 repeat = false;
11816 for (int i=mRestartingServices.size()-1; i>=0; i--) {
11817 ServiceRecord r2 = mRestartingServices.get(i);
11818 if (r2 != r && r.nextRestartTime
11819 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11820 && r.nextRestartTime
11821 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11822 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11823 r.restartDelay = r.nextRestartTime - now;
11824 repeat = true;
11825 break;
11826 }
11827 }
11828 } while (repeat);
11829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011830 if (!mRestartingServices.contains(r)) {
11831 mRestartingServices.add(r);
11832 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011833
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011834 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011836 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011837 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011839 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011840 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080011841 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011842 r.shortName, r.restartDelay);
11843
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011844 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011845 }
11846
11847 final void performServiceRestartLocked(ServiceRecord r) {
11848 if (!mRestartingServices.contains(r)) {
11849 return;
11850 }
11851 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11852 }
11853
11854 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11855 if (r.restartDelay == 0) {
11856 return false;
11857 }
11858 r.resetRestartCounter();
11859 mRestartingServices.remove(r);
11860 mHandler.removeCallbacks(r.restarter);
11861 return true;
11862 }
11863
11864 private final boolean bringUpServiceLocked(ServiceRecord r,
11865 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011866 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 //r.dump(" ");
11868
Dianne Hackborn36124872009-10-08 16:22:03 -070011869 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011870 sendServiceArgsLocked(r, false);
11871 return true;
11872 }
11873
11874 if (!whileRestarting && r.restartDelay > 0) {
11875 // If waiting for a restart, then do nothing.
11876 return true;
11877 }
11878
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011879 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011880
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011881 // We are now bringing the service up, so no longer in the
11882 // restarting state.
11883 mRestartingServices.remove(r);
11884
Dianne Hackborne7f97212011-02-24 14:40:20 -080011885 // Service is now being launched, its package can't be stopped.
11886 try {
11887 AppGlobals.getPackageManager().setPackageStoppedState(
11888 r.packageName, false);
11889 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011890 } catch (IllegalArgumentException e) {
11891 Slog.w(TAG, "Failed trying to unstop package "
11892 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011893 }
11894
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011895 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011896 final String appName = r.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011897 ProcessRecord app;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011898
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011899 if (!isolated) {
11900 app = getProcessRecordLocked(appName, r.appInfo.uid);
11901 if (DEBUG_MU)
11902 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11903 if (app != null && app.thread != null) {
11904 try {
11905 app.addPackage(r.appInfo.packageName);
11906 realStartServiceLocked(r, app);
11907 return true;
11908 } catch (RemoteException e) {
11909 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11910 }
11911
11912 // If a dead object exception was thrown -- fall through to
11913 // restart the application.
11914 }
11915 } else {
11916 // If this service runs in an isolated process, then each time
11917 // we call startProcessLocked() we will get a new isolated
11918 // process, starting another process if we are currently waiting
11919 // for a previous process to come up. To deal with this, we store
11920 // in the service any current isolated process it is running in or
11921 // waiting to have come up.
11922 app = r.isolatedProc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011923 }
11924
Dianne Hackborn36124872009-10-08 16:22:03 -070011925 // Not running -- get it started, and enqueue this service record
11926 // to be executed when the app comes up.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011927 if (app == null) {
11928 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11929 "service", r.name, false, isolated)) == null) {
11930 Slog.w(TAG, "Unable to launch app "
11931 + r.appInfo.packageName + "/"
11932 + r.appInfo.uid + " for service "
11933 + r.intent.getIntent() + ": process is bad");
11934 bringDownServiceLocked(r, true);
11935 return false;
11936 }
11937 if (isolated) {
11938 r.isolatedProc = app;
11939 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011940 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011943 mPendingServices.add(r);
11944 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011946 return true;
11947 }
11948
11949 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011950 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011951 //r.dump(" ");
11952
11953 // Does it still need to run?
11954 if (!force && r.startRequested) {
11955 return;
11956 }
11957 if (r.connections.size() > 0) {
11958 if (!force) {
11959 // XXX should probably keep a count of the number of auto-create
11960 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011961 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011962 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011963 ArrayList<ConnectionRecord> cr = it.next();
11964 for (int i=0; i<cr.size(); i++) {
11965 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11966 return;
11967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011968 }
11969 }
11970 }
11971
11972 // Report to all of the connections that the service is no longer
11973 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011974 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011975 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011976 ArrayList<ConnectionRecord> c = it.next();
11977 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011978 ConnectionRecord cr = c.get(i);
11979 // There is still a connection to the service that is
11980 // being brought down. Mark it as dead.
11981 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011982 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011983 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011984 } catch (Exception e) {
11985 Slog.w(TAG, "Failure disconnecting service " + r.name +
11986 " to connection " + c.get(i).conn.asBinder() +
11987 " (in " + c.get(i).binding.client.processName + ")", e);
11988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 }
11990 }
11991 }
11992
11993 // Tell the service that it has been unbound.
11994 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11995 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11996 while (it.hasNext()) {
11997 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011998 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011999 + ": hasBound=" + ibr.hasBound);
12000 if (r.app != null && r.app.thread != null && ibr.hasBound) {
12001 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012002 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012003 updateOomAdjLocked(r.app);
12004 ibr.hasBound = false;
12005 r.app.thread.scheduleUnbindService(r,
12006 ibr.intent.getIntent());
12007 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012008 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 + r.shortName, e);
12010 serviceDoneExecutingLocked(r, true);
12011 }
12012 }
12013 }
12014 }
12015
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012016 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012017 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012018 System.identityHashCode(r), r.shortName,
12019 (r.app != null) ? r.app.pid : -1);
12020
Amith Yamasani742a6712011-05-04 14:49:28 -070012021 mServiceMap.removeServiceByName(r.name, r.userId);
12022 mServiceMap.removeServiceByIntent(r.intent, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 r.totalRestartCount = 0;
12024 unscheduleServiceRestartLocked(r);
12025
12026 // Also make sure it is not on the pending list.
12027 int N = mPendingServices.size();
12028 for (int i=0; i<N; i++) {
12029 if (mPendingServices.get(i) == r) {
12030 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012031 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012032 i--;
12033 N--;
12034 }
12035 }
12036
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012037 r.cancelNotification();
12038 r.isForeground = false;
12039 r.foregroundId = 0;
12040 r.foregroundNoti = null;
12041
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012042 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070012043 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012044 r.pendingStarts.clear();
12045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012046 if (r.app != null) {
12047 synchronized (r.stats.getBatteryStats()) {
12048 r.stats.stopLaunchedLocked();
12049 }
12050 r.app.services.remove(r);
12051 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012052 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012053 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012054 mStoppingServices.add(r);
12055 updateOomAdjLocked(r.app);
12056 r.app.thread.scheduleStopService(r);
12057 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012058 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012059 + r.shortName, e);
12060 serviceDoneExecutingLocked(r, true);
12061 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012062 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012063 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012064 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012065 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012066 }
12067 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012068 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012069 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012070 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080012071
12072 if (r.bindings.size() > 0) {
12073 r.bindings.clear();
12074 }
12075
12076 if (r.restarter instanceof ServiceRestarter) {
12077 ((ServiceRestarter)r.restarter).setService(null);
12078 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012079 }
12080
12081 ComponentName startServiceLocked(IApplicationThread caller,
12082 Intent service, String resolvedType,
12083 int callingPid, int callingUid) {
12084 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012085 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012086 + " type=" + resolvedType + " args=" + service.getExtras());
12087
12088 if (caller != null) {
12089 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12090 if (callerApp == null) {
12091 throw new SecurityException(
12092 "Unable to find app for caller " + caller
12093 + " (pid=" + Binder.getCallingPid()
12094 + ") when starting service " + service);
12095 }
12096 }
12097
12098 ServiceLookupResult res =
12099 retrieveServiceLocked(service, resolvedType,
12100 callingPid, callingUid);
12101 if (res == null) {
12102 return null;
12103 }
12104 if (res.record == null) {
12105 return new ComponentName("!", res.permission != null
12106 ? res.permission : "private to package");
12107 }
12108 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070012109 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
12110 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012111 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012112 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012113 }
12114 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012115 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012116 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070012117 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118 r.lastActivity = SystemClock.uptimeMillis();
12119 synchronized (r.stats.getBatteryStats()) {
12120 r.stats.startRunningLocked();
12121 }
12122 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
12123 return new ComponentName("!", "Service process is bad");
12124 }
12125 return r.name;
12126 }
12127 }
12128
12129 public ComponentName startService(IApplicationThread caller, Intent service,
12130 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012131 enforceNotIsolatedCaller("startService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 // Refuse possible leaked file descriptors
12133 if (service != null && service.hasFileDescriptors() == true) {
12134 throw new IllegalArgumentException("File descriptors passed in Intent");
12135 }
12136
Amith Yamasani742a6712011-05-04 14:49:28 -070012137 if (DEBUG_SERVICE)
12138 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 synchronized(this) {
12140 final int callingPid = Binder.getCallingPid();
12141 final int callingUid = Binder.getCallingUid();
12142 final long origId = Binder.clearCallingIdentity();
12143 ComponentName res = startServiceLocked(caller, service,
12144 resolvedType, callingPid, callingUid);
12145 Binder.restoreCallingIdentity(origId);
12146 return res;
12147 }
12148 }
12149
12150 ComponentName startServiceInPackage(int uid,
12151 Intent service, String resolvedType) {
12152 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070012153 if (DEBUG_SERVICE)
12154 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012155 final long origId = Binder.clearCallingIdentity();
12156 ComponentName res = startServiceLocked(null, service,
12157 resolvedType, -1, uid);
12158 Binder.restoreCallingIdentity(origId);
12159 return res;
12160 }
12161 }
12162
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012163 private void stopServiceLocked(ServiceRecord service) {
12164 synchronized (service.stats.getBatteryStats()) {
12165 service.stats.stopRunningLocked();
12166 }
12167 service.startRequested = false;
12168 service.callStart = false;
12169 bringDownServiceLocked(service, false);
12170 }
12171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012172 public int stopService(IApplicationThread caller, Intent service,
12173 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012174 enforceNotIsolatedCaller("stopService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012175 // Refuse possible leaked file descriptors
12176 if (service != null && service.hasFileDescriptors() == true) {
12177 throw new IllegalArgumentException("File descriptors passed in Intent");
12178 }
12179
12180 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012181 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012182 + " type=" + resolvedType);
12183
12184 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12185 if (caller != null && callerApp == null) {
12186 throw new SecurityException(
12187 "Unable to find app for caller " + caller
12188 + " (pid=" + Binder.getCallingPid()
12189 + ") when stopping service " + service);
12190 }
12191
12192 // If this service is active, make sure it is stopped.
12193 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12194 if (r != null) {
12195 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012197 try {
12198 stopServiceLocked(r.record);
12199 } finally {
12200 Binder.restoreCallingIdentity(origId);
12201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 return 1;
12203 }
12204 return -1;
12205 }
12206 }
12207
12208 return 0;
12209 }
12210
12211 public IBinder peekService(Intent service, String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012212 enforceNotIsolatedCaller("peekService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012213 // Refuse possible leaked file descriptors
12214 if (service != null && service.hasFileDescriptors() == true) {
12215 throw new IllegalArgumentException("File descriptors passed in Intent");
12216 }
12217
12218 IBinder ret = null;
12219
12220 synchronized(this) {
12221 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12222
12223 if (r != null) {
12224 // r.record is null if findServiceLocked() failed the caller permission check
12225 if (r.record == null) {
12226 throw new SecurityException(
12227 "Permission Denial: Accessing service " + r.record.name
12228 + " from pid=" + Binder.getCallingPid()
12229 + ", uid=" + Binder.getCallingUid()
12230 + " requires " + r.permission);
12231 }
12232 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
12233 if (ib != null) {
12234 ret = ib.binder;
12235 }
12236 }
12237 }
12238
12239 return ret;
12240 }
12241
12242 public boolean stopServiceToken(ComponentName className, IBinder token,
12243 int startId) {
12244 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012245 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 + " " + token + " startId=" + startId);
12247 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012248 if (r != null) {
12249 if (startId >= 0) {
12250 // Asked to only stop if done with all work. Note that
12251 // to avoid leaks, we will take this as dropping all
12252 // start items up to and including this one.
12253 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12254 if (si != null) {
12255 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070012256 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
12257 cur.removeUriPermissionsLocked();
12258 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012259 break;
12260 }
12261 }
12262 }
12263
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012264 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012265 return false;
12266 }
12267
12268 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012269 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012270 + " is last, but have " + r.deliveredStarts.size()
12271 + " remaining args");
12272 }
12273 }
12274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275 synchronized (r.stats.getBatteryStats()) {
12276 r.stats.stopRunningLocked();
12277 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012278 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012279 }
12280 final long origId = Binder.clearCallingIdentity();
12281 bringDownServiceLocked(r, false);
12282 Binder.restoreCallingIdentity(origId);
12283 return true;
12284 }
12285 }
12286 return false;
12287 }
12288
12289 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012290 int id, Notification notification, boolean removeNotification) {
12291 final long origId = Binder.clearCallingIdentity();
12292 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012293 synchronized(this) {
12294 ServiceRecord r = findServiceLocked(className, token);
12295 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012296 if (id != 0) {
12297 if (notification == null) {
12298 throw new IllegalArgumentException("null notification");
12299 }
12300 if (r.foregroundId != id) {
12301 r.cancelNotification();
12302 r.foregroundId = id;
12303 }
12304 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
12305 r.foregroundNoti = notification;
12306 r.isForeground = true;
12307 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012308 if (r.app != null) {
12309 updateServiceForegroundLocked(r.app, true);
12310 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012311 } else {
12312 if (r.isForeground) {
12313 r.isForeground = false;
12314 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070012315 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012316 updateServiceForegroundLocked(r.app, true);
12317 }
12318 }
12319 if (removeNotification) {
12320 r.cancelNotification();
12321 r.foregroundId = 0;
12322 r.foregroundNoti = null;
12323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012324 }
12325 }
12326 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012327 } finally {
12328 Binder.restoreCallingIdentity(origId);
12329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012330 }
12331
12332 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
12333 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070012334 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335 if (sr.isForeground) {
12336 anyForeground = true;
12337 break;
12338 }
12339 }
12340 if (anyForeground != proc.foregroundServices) {
12341 proc.foregroundServices = anyForeground;
12342 if (oomAdj) {
12343 updateOomAdjLocked();
12344 }
12345 }
12346 }
12347
12348 public int bindService(IApplicationThread caller, IBinder token,
12349 Intent service, String resolvedType,
12350 IServiceConnection connection, int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012351 enforceNotIsolatedCaller("bindService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012352 // Refuse possible leaked file descriptors
12353 if (service != null && service.hasFileDescriptors() == true) {
12354 throw new IllegalArgumentException("File descriptors passed in Intent");
12355 }
12356
12357 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012358 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 + " type=" + resolvedType + " conn=" + connection.asBinder()
12360 + " flags=0x" + Integer.toHexString(flags));
Amith Yamasani742a6712011-05-04 14:49:28 -070012361 if (DEBUG_MU)
12362 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12363 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12365 if (callerApp == null) {
12366 throw new SecurityException(
12367 "Unable to find app for caller " + caller
12368 + " (pid=" + Binder.getCallingPid()
12369 + ") when binding service " + service);
12370 }
12371
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012372 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012373 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012374 activity = mMainStack.isInStackLocked(token);
12375 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012376 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012377 return 0;
12378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012379 }
12380
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012381 int clientLabel = 0;
12382 PendingIntent clientIntent = null;
12383
12384 if (callerApp.info.uid == Process.SYSTEM_UID) {
12385 // Hacky kind of thing -- allow system stuff to tell us
12386 // what they are, so we can report this elsewhere for
12387 // others to know why certain services are running.
12388 try {
12389 clientIntent = (PendingIntent)service.getParcelableExtra(
12390 Intent.EXTRA_CLIENT_INTENT);
12391 } catch (RuntimeException e) {
12392 }
12393 if (clientIntent != null) {
12394 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12395 if (clientLabel != 0) {
12396 // There are no useful extras in the intent, trash them.
12397 // System code calling with this stuff just needs to know
12398 // this will happen.
12399 service = service.cloneFilter();
12400 }
12401 }
12402 }
12403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012404 ServiceLookupResult res =
12405 retrieveServiceLocked(service, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -070012406 Binder.getCallingPid(), Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012407 if (res == null) {
12408 return 0;
12409 }
12410 if (res.record == null) {
12411 return -1;
12412 }
12413 ServiceRecord s = res.record;
12414
12415 final long origId = Binder.clearCallingIdentity();
12416
12417 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012418 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012419 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012420 }
12421
12422 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12423 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012424 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012425
12426 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012427 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12428 if (clist == null) {
12429 clist = new ArrayList<ConnectionRecord>();
12430 s.connections.put(binder, clist);
12431 }
12432 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012433 b.connections.add(c);
12434 if (activity != null) {
12435 if (activity.connections == null) {
12436 activity.connections = new HashSet<ConnectionRecord>();
12437 }
12438 activity.connections.add(c);
12439 }
12440 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012441 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12442 b.client.hasAboveClient = true;
12443 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012444 clist = mServiceConnections.get(binder);
12445 if (clist == null) {
12446 clist = new ArrayList<ConnectionRecord>();
12447 mServiceConnections.put(binder, clist);
12448 }
12449 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012450
12451 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12452 s.lastActivity = SystemClock.uptimeMillis();
12453 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12454 return 0;
12455 }
12456 }
12457
12458 if (s.app != null) {
12459 // This could have made the service more important.
12460 updateOomAdjLocked(s.app);
12461 }
12462
Joe Onorato8a9b2202010-02-26 18:56:32 -080012463 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 + ": received=" + b.intent.received
12465 + " apps=" + b.intent.apps.size()
12466 + " doRebind=" + b.intent.doRebind);
12467
12468 if (s.app != null && b.intent.received) {
12469 // Service is already running, so we can immediately
12470 // publish the connection.
12471 try {
12472 c.conn.connected(s.name, b.intent.binder);
12473 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012474 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012475 + " to connection " + c.conn.asBinder()
12476 + " (in " + c.binding.client.processName + ")", e);
12477 }
12478
12479 // If this is the first app connected back to this binding,
12480 // and the service had previously asked to be told when
12481 // rebound, then do so.
12482 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12483 requestServiceBindingLocked(s, b.intent, true);
12484 }
12485 } else if (!b.intent.requested) {
12486 requestServiceBindingLocked(s, b.intent, false);
12487 }
12488
12489 Binder.restoreCallingIdentity(origId);
12490 }
12491
12492 return 1;
12493 }
12494
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012495 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012496 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012497 IBinder binder = c.conn.asBinder();
12498 AppBindRecord b = c.binding;
12499 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012500 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12501 if (clist != null) {
12502 clist.remove(c);
12503 if (clist.size() == 0) {
12504 s.connections.remove(binder);
12505 }
12506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 b.connections.remove(c);
12508 if (c.activity != null && c.activity != skipAct) {
12509 if (c.activity.connections != null) {
12510 c.activity.connections.remove(c);
12511 }
12512 }
12513 if (b.client != skipApp) {
12514 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012515 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12516 b.client.updateHasAboveClientLocked();
12517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012518 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012519 clist = mServiceConnections.get(binder);
12520 if (clist != null) {
12521 clist.remove(c);
12522 if (clist.size() == 0) {
12523 mServiceConnections.remove(binder);
12524 }
12525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012526
12527 if (b.connections.size() == 0) {
12528 b.intent.apps.remove(b.client);
12529 }
12530
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012531 if (!c.serviceDead) {
12532 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12533 + ": shouldUnbind=" + b.intent.hasBound);
12534 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12535 && b.intent.hasBound) {
12536 try {
12537 bumpServiceExecutingLocked(s, "unbind");
12538 updateOomAdjLocked(s.app);
12539 b.intent.hasBound = false;
12540 // Assume the client doesn't want to know about a rebind;
12541 // we will deal with that later if it asks for one.
12542 b.intent.doRebind = false;
12543 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12544 } catch (Exception e) {
12545 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12546 serviceDoneExecutingLocked(s, true);
12547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012549
12550 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12551 bringDownServiceLocked(s, false);
12552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012553 }
12554 }
12555
12556 public boolean unbindService(IServiceConnection connection) {
12557 synchronized (this) {
12558 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012559 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012560 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12561 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012562 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012563 + connection.asBinder());
12564 return false;
12565 }
12566
12567 final long origId = Binder.clearCallingIdentity();
12568
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012569 while (clist.size() > 0) {
12570 ConnectionRecord r = clist.get(0);
12571 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012572
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012573 if (r.binding.service.app != null) {
12574 // This could have made the service less important.
12575 updateOomAdjLocked(r.binding.service.app);
12576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012577 }
12578
12579 Binder.restoreCallingIdentity(origId);
12580 }
12581
12582 return true;
12583 }
12584
12585 public void publishService(IBinder token, Intent intent, IBinder service) {
12586 // Refuse possible leaked file descriptors
12587 if (intent != null && intent.hasFileDescriptors() == true) {
12588 throw new IllegalArgumentException("File descriptors passed in Intent");
12589 }
12590
12591 synchronized(this) {
12592 if (!(token instanceof ServiceRecord)) {
12593 throw new IllegalArgumentException("Invalid service token");
12594 }
12595 ServiceRecord r = (ServiceRecord)token;
12596
12597 final long origId = Binder.clearCallingIdentity();
12598
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012599 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012600 + " " + intent + ": " + service);
12601 if (r != null) {
12602 Intent.FilterComparison filter
12603 = new Intent.FilterComparison(intent);
12604 IntentBindRecord b = r.bindings.get(filter);
12605 if (b != null && !b.received) {
12606 b.binder = service;
12607 b.requested = true;
12608 b.received = true;
12609 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012610 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012611 = r.connections.values().iterator();
12612 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012613 ArrayList<ConnectionRecord> clist = it.next();
12614 for (int i=0; i<clist.size(); i++) {
12615 ConnectionRecord c = clist.get(i);
12616 if (!filter.equals(c.binding.intent.intent)) {
12617 if (DEBUG_SERVICE) Slog.v(
12618 TAG, "Not publishing to: " + c);
12619 if (DEBUG_SERVICE) Slog.v(
12620 TAG, "Bound intent: " + c.binding.intent.intent);
12621 if (DEBUG_SERVICE) Slog.v(
12622 TAG, "Published intent: " + intent);
12623 continue;
12624 }
12625 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12626 try {
12627 c.conn.connected(r.name, service);
12628 } catch (Exception e) {
12629 Slog.w(TAG, "Failure sending service " + r.name +
12630 " to connection " + c.conn.asBinder() +
12631 " (in " + c.binding.client.processName + ")", e);
12632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012633 }
12634 }
12635 }
12636 }
12637
12638 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12639
12640 Binder.restoreCallingIdentity(origId);
12641 }
12642 }
12643 }
12644
12645 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12646 // Refuse possible leaked file descriptors
12647 if (intent != null && intent.hasFileDescriptors() == true) {
12648 throw new IllegalArgumentException("File descriptors passed in Intent");
12649 }
12650
12651 synchronized(this) {
12652 if (!(token instanceof ServiceRecord)) {
12653 throw new IllegalArgumentException("Invalid service token");
12654 }
12655 ServiceRecord r = (ServiceRecord)token;
12656
12657 final long origId = Binder.clearCallingIdentity();
12658
12659 if (r != null) {
12660 Intent.FilterComparison filter
12661 = new Intent.FilterComparison(intent);
12662 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012663 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012664 + " at " + b + ": apps="
12665 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020012666
12667 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012668 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020012669 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012670 // Applications have already bound since the last
12671 // unbind, so just rebind right here.
12672 requestServiceBindingLocked(r, b, true);
12673 } else {
12674 // Note to tell the service the next time there is
12675 // a new client.
12676 b.doRebind = true;
12677 }
12678 }
12679
Per Edelberg78f9fff2010-08-30 20:01:35 +020012680 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012681
12682 Binder.restoreCallingIdentity(origId);
12683 }
12684 }
12685 }
12686
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012687 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012688 synchronized(this) {
12689 if (!(token instanceof ServiceRecord)) {
12690 throw new IllegalArgumentException("Invalid service token");
12691 }
12692 ServiceRecord r = (ServiceRecord)token;
12693 boolean inStopping = mStoppingServices.contains(token);
12694 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012695 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012696 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 + " with incorrect token: given " + token
12698 + ", expected " + r);
12699 return;
12700 }
12701
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012702 if (type == 1) {
12703 // This is a call from a service start... take care of
12704 // book-keeping.
12705 r.callStart = true;
12706 switch (res) {
12707 case Service.START_STICKY_COMPATIBILITY:
12708 case Service.START_STICKY: {
12709 // We are done with the associated start arguments.
12710 r.findDeliveredStart(startId, true);
12711 // Don't stop if killed.
12712 r.stopIfKilled = false;
12713 break;
12714 }
12715 case Service.START_NOT_STICKY: {
12716 // We are done with the associated start arguments.
12717 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012718 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012719 // There is no more work, and this service
12720 // doesn't want to hang around if killed.
12721 r.stopIfKilled = true;
12722 }
12723 break;
12724 }
12725 case Service.START_REDELIVER_INTENT: {
12726 // We'll keep this item until they explicitly
12727 // call stop for it, but keep track of the fact
12728 // that it was delivered.
12729 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12730 if (si != null) {
12731 si.deliveryCount = 0;
12732 si.doneExecutingCount++;
12733 // Don't stop if killed.
12734 r.stopIfKilled = true;
12735 }
12736 break;
12737 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012738 case Service.START_TASK_REMOVED_COMPLETE: {
12739 // Special processing for onTaskRemoved(). Don't
12740 // impact normal onStartCommand() processing.
12741 r.findDeliveredStart(startId, true);
12742 break;
12743 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012744 default:
12745 throw new IllegalArgumentException(
12746 "Unknown service start result: " + res);
12747 }
12748 if (res == Service.START_STICKY_COMPATIBILITY) {
12749 r.callStart = false;
12750 }
12751 }
Amith Yamasani742a6712011-05-04 14:49:28 -070012752 if (DEBUG_MU)
12753 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12754 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012755 final long origId = Binder.clearCallingIdentity();
12756 serviceDoneExecutingLocked(r, inStopping);
12757 Binder.restoreCallingIdentity(origId);
12758 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012759 Slog.w(TAG, "Done executing unknown service from pid "
12760 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012761 }
12762 }
12763 }
12764
12765 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012766 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12767 + ": nesting=" + r.executeNesting
12768 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012769 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012770 r.executeNesting--;
12771 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012772 if (DEBUG_SERVICE) Slog.v(TAG,
12773 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012774 r.app.executingServices.remove(r);
12775 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012776 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12777 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12779 }
12780 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012781 if (DEBUG_SERVICE) Slog.v(TAG,
12782 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012783 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020012784 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012785 }
12786 updateOomAdjLocked(r.app);
12787 }
12788 }
12789
12790 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012791 String anrMessage = null;
12792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012793 synchronized(this) {
12794 if (proc.executingServices.size() == 0 || proc.thread == null) {
12795 return;
12796 }
12797 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12798 Iterator<ServiceRecord> it = proc.executingServices.iterator();
12799 ServiceRecord timeout = null;
12800 long nextTime = 0;
12801 while (it.hasNext()) {
12802 ServiceRecord sr = it.next();
12803 if (sr.executingStart < maxTime) {
12804 timeout = sr;
12805 break;
12806 }
12807 if (sr.executingStart > nextTime) {
12808 nextTime = sr.executingStart;
12809 }
12810 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012811 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012812 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012813 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012814 } else {
12815 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12816 msg.obj = proc;
12817 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12818 }
12819 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012820
12821 if (anrMessage != null) {
12822 appNotResponding(proc, null, null, anrMessage);
12823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012824 }
12825
12826 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070012827 // BACKUP AND RESTORE
12828 // =========================================================
12829
12830 // Cause the target app to be launched if necessary and its backup agent
12831 // instantiated. The backup agent will invoke backupAgentCreated() on the
12832 // activity manager to announce its creation.
12833 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012834 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012835 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12836
12837 synchronized(this) {
12838 // !!! TODO: currently no check here that we're already bound
12839 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12840 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12841 synchronized (stats) {
12842 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12843 }
12844
Dianne Hackborne7f97212011-02-24 14:40:20 -080012845 // Backup agent is now in use, its package can't be stopped.
12846 try {
12847 AppGlobals.getPackageManager().setPackageStoppedState(
12848 app.packageName, false);
12849 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012850 } catch (IllegalArgumentException e) {
12851 Slog.w(TAG, "Failed trying to unstop package "
12852 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012853 }
12854
Christopher Tate181fafa2009-05-14 11:12:14 -070012855 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070012856 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12857 ? new ComponentName(app.packageName, app.backupAgentName)
12858 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070012859 // startProcessLocked() returns existing proc's record if it's already running
12860 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080012861 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070012862 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012863 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070012864 return false;
12865 }
12866
12867 r.app = proc;
12868 mBackupTarget = r;
12869 mBackupAppName = app.packageName;
12870
Christopher Tate6fa95972009-06-05 18:43:55 -070012871 // Try not to kill the process during backup
12872 updateOomAdjLocked(proc);
12873
Christopher Tate181fafa2009-05-14 11:12:14 -070012874 // If the process is already attached, schedule the creation of the backup agent now.
12875 // If it is not yet live, this will be done when it attaches to the framework.
12876 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012877 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070012878 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012879 proc.thread.scheduleCreateBackupAgent(app,
12880 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012881 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070012882 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070012883 }
12884 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012885 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070012886 }
12887 // Invariants: at this point, the target app process exists and the application
12888 // is either already running or in the process of coming up. mBackupTarget and
12889 // mBackupAppName describe the app, so that when it binds back to the AM we
12890 // know that it's scheduled for a backup-agent operation.
12891 }
12892
12893 return true;
12894 }
12895
12896 // A backup agent has just come up
12897 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012898 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070012899 + " = " + agent);
12900
12901 synchronized(this) {
12902 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012903 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070012904 return;
12905 }
Dianne Hackborn06740692010-09-22 22:46:21 -070012906 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012907
Dianne Hackborn06740692010-09-22 22:46:21 -070012908 long oldIdent = Binder.clearCallingIdentity();
12909 try {
12910 IBackupManager bm = IBackupManager.Stub.asInterface(
12911 ServiceManager.getService(Context.BACKUP_SERVICE));
12912 bm.agentConnected(agentPackageName, agent);
12913 } catch (RemoteException e) {
12914 // can't happen; the backup manager service is local
12915 } catch (Exception e) {
12916 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12917 e.printStackTrace();
12918 } finally {
12919 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070012920 }
12921 }
12922
12923 // done with this agent
12924 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012925 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070012926 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012927 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070012928 return;
12929 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012930
12931 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070012932 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012933 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070012934 return;
12935 }
12936
Christopher Tate181fafa2009-05-14 11:12:14 -070012937 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012938 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070012939 return;
12940 }
12941
Christopher Tate6fa95972009-06-05 18:43:55 -070012942 ProcessRecord proc = mBackupTarget.app;
12943 mBackupTarget = null;
12944 mBackupAppName = null;
12945
12946 // Not backing this app up any more; reset its OOM adjustment
12947 updateOomAdjLocked(proc);
12948
Christopher Tatec7b31e32009-06-10 15:49:30 -070012949 // If the app crashed during backup, 'thread' will be null here
12950 if (proc.thread != null) {
12951 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012952 proc.thread.scheduleDestroyBackupAgent(appInfo,
12953 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070012954 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012955 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070012956 e.printStackTrace();
12957 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012958 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012959 }
12960 }
12961 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012962 // BROADCASTS
12963 // =========================================================
12964
Josh Bartel7f208742010-02-25 11:01:44 -060012965 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966 List cur) {
12967 final ContentResolver resolver = mContext.getContentResolver();
12968 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12969 if (list == null) {
12970 return cur;
12971 }
12972 int N = list.size();
12973 for (int i=0; i<N; i++) {
12974 Intent intent = list.get(i);
12975 if (filter.match(resolver, intent, true, TAG) >= 0) {
12976 if (cur == null) {
12977 cur = new ArrayList<Intent>();
12978 }
12979 cur.add(intent);
12980 }
12981 }
12982 return cur;
12983 }
12984
Christopher Tatef46723b2012-01-26 14:19:24 -080012985 boolean isPendingBroadcastProcessLocked(int pid) {
12986 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12987 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012989
Christopher Tatef46723b2012-01-26 14:19:24 -080012990 void skipPendingBroadcastLocked(int pid) {
12991 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12992 for (BroadcastQueue queue : mBroadcastQueues) {
12993 queue.skipPendingBroadcastLocked(pid);
12994 }
12995 }
12996
12997 // The app just attached; send any pending broadcasts that it should receive
12998 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12999 boolean didSomething = false;
13000 for (BroadcastQueue queue : mBroadcastQueues) {
13001 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013002 }
Christopher Tatef46723b2012-01-26 14:19:24 -080013003 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 }
13005
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013006 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007 IIntentReceiver receiver, IntentFilter filter, String permission) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013008 enforceNotIsolatedCaller("registerReceiver");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013009 synchronized(this) {
13010 ProcessRecord callerApp = null;
13011 if (caller != null) {
13012 callerApp = getRecordForAppLocked(caller);
13013 if (callerApp == null) {
13014 throw new SecurityException(
13015 "Unable to find app for caller " + caller
13016 + " (pid=" + Binder.getCallingPid()
13017 + ") when registering receiver " + receiver);
13018 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013019 if (callerApp.info.uid != Process.SYSTEM_UID &&
13020 !callerApp.pkgList.contains(callerPackage)) {
13021 throw new SecurityException("Given caller package " + callerPackage
13022 + " is not running in process " + callerApp);
13023 }
13024 } else {
13025 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013026 }
13027
13028 List allSticky = null;
13029
13030 // Look for any matching sticky broadcasts...
13031 Iterator actions = filter.actionsIterator();
13032 if (actions != null) {
13033 while (actions.hasNext()) {
13034 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060013035 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013036 }
13037 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060013038 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013039 }
13040
13041 // The first sticky in the list is returned directly back to
13042 // the client.
13043 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13044
Joe Onorato8a9b2202010-02-26 18:56:32 -080013045 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013046 + ": " + sticky);
13047
13048 if (receiver == null) {
13049 return sticky;
13050 }
13051
13052 ReceiverList rl
13053 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13054 if (rl == null) {
13055 rl = new ReceiverList(this, callerApp,
13056 Binder.getCallingPid(),
13057 Binder.getCallingUid(), receiver);
13058 if (rl.app != null) {
13059 rl.app.receivers.add(rl);
13060 } else {
13061 try {
13062 receiver.asBinder().linkToDeath(rl, 0);
13063 } catch (RemoteException e) {
13064 return sticky;
13065 }
13066 rl.linkedToDeath = true;
13067 }
13068 mRegisteredReceivers.put(receiver.asBinder(), rl);
13069 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013070 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013071 rl.add(bf);
13072 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013073 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013074 }
13075 mReceiverResolver.addFilter(bf);
13076
13077 // Enqueue broadcasts for all existing stickies that match
13078 // this filter.
13079 if (allSticky != null) {
13080 ArrayList receivers = new ArrayList();
13081 receivers.add(bf);
13082
13083 int N = allSticky.size();
13084 for (int i=0; i<N; i++) {
13085 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080013086 BroadcastQueue queue = broadcastQueueForIntent(intent);
13087 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013088 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013089 false, true, true);
Christopher Tatef46723b2012-01-26 14:19:24 -080013090 queue.enqueueParallelBroadcastLocked(r);
13091 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013092 }
13093 }
13094
13095 return sticky;
13096 }
13097 }
13098
13099 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013100 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013101
Christopher Tatef46723b2012-01-26 14:19:24 -080013102 final long origId = Binder.clearCallingIdentity();
13103 try {
13104 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013105
Christopher Tatef46723b2012-01-26 14:19:24 -080013106 synchronized(this) {
13107 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013108 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080013109 if (rl != null) {
13110 if (rl.curBroadcast != null) {
13111 BroadcastRecord r = rl.curBroadcast;
13112 final boolean doNext = finishReceiverLocked(
13113 receiver.asBinder(), r.resultCode, r.resultData,
13114 r.resultExtras, r.resultAbort, true);
13115 if (doNext) {
13116 doTrim = true;
13117 r.queue.processNextBroadcast(false);
13118 }
13119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013120
Christopher Tatef46723b2012-01-26 14:19:24 -080013121 if (rl.app != null) {
13122 rl.app.receivers.remove(rl);
13123 }
13124 removeReceiverLocked(rl);
13125 if (rl.linkedToDeath) {
13126 rl.linkedToDeath = false;
13127 rl.receiver.asBinder().unlinkToDeath(rl, 0);
13128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013129 }
13130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013131
Christopher Tatef46723b2012-01-26 14:19:24 -080013132 // If we actually concluded any broadcasts, we might now be able
13133 // to trim the recipients' apps from our working set
13134 if (doTrim) {
13135 trimApplications();
13136 return;
13137 }
13138
13139 } finally {
13140 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013141 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013142 }
13143
13144 void removeReceiverLocked(ReceiverList rl) {
13145 mRegisteredReceivers.remove(rl.receiver.asBinder());
13146 int N = rl.size();
13147 for (int i=0; i<N; i++) {
13148 mReceiverResolver.removeFilter(rl.get(i));
13149 }
13150 }
13151
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013152 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
13153 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13154 ProcessRecord r = mLruProcesses.get(i);
13155 if (r.thread != null) {
13156 try {
13157 r.thread.dispatchPackageBroadcast(cmd, packages);
13158 } catch (RemoteException ex) {
13159 }
13160 }
13161 }
13162 }
13163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013164 private final int broadcastIntentLocked(ProcessRecord callerApp,
13165 String callerPackage, Intent intent, String resolvedType,
13166 IIntentReceiver resultTo, int resultCode, String resultData,
13167 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013168 boolean ordered, boolean sticky, int callingPid, int callingUid,
13169 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013170 intent = new Intent(intent);
13171
Dianne Hackborne7f97212011-02-24 14:40:20 -080013172 // By default broadcasts do not go to stopped apps.
13173 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13174
Joe Onorato8a9b2202010-02-26 18:56:32 -080013175 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013176 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13177 + " ordered=" + ordered);
13178 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013179 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013180 }
13181
13182 // Handle special intents: if this broadcast is from the package
13183 // manager about a package being removed, we need to remove all of
13184 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013185 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013186 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013187 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13188 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013189 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013190 || uidRemoved) {
13191 if (checkComponentPermission(
13192 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013193 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013194 == PackageManager.PERMISSION_GRANTED) {
13195 if (uidRemoved) {
13196 final Bundle intentExtras = intent.getExtras();
13197 final int uid = intentExtras != null
13198 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13199 if (uid >= 0) {
13200 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13201 synchronized (bs) {
13202 bs.removeUidStatsLocked(uid);
13203 }
13204 }
13205 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013206 // If resources are unvailble just force stop all
13207 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013208 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013209 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13210 if (list != null && (list.length > 0)) {
13211 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070013212 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013213 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013214 sendPackageBroadcastLocked(
13215 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013216 }
13217 } else {
13218 Uri data = intent.getData();
13219 String ssp;
13220 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13221 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13222 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070013223 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070013224 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013225 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013226 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13227 new String[] {ssp});
13228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013229 }
13230 }
13231 }
13232 } else {
13233 String msg = "Permission Denial: " + intent.getAction()
13234 + " broadcast from " + callerPackage + " (pid=" + callingPid
13235 + ", uid=" + callingUid + ")"
13236 + " requires "
13237 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013238 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013239 throw new SecurityException(msg);
13240 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013241
13242 // Special case for adding a package: by default turn on compatibility
13243 // mode.
13244 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070013245 Uri data = intent.getData();
13246 String ssp;
13247 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13248 mCompatModePackages.handlePackageAddedLocked(ssp,
13249 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013251 }
13252
13253 /*
13254 * If this is the time zone changed action, queue up a message that will reset the timezone
13255 * of all currently running processes. This message will get queued up before the broadcast
13256 * happens.
13257 */
13258 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13259 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13260 }
13261
Robert Greenwalt03595d02010-11-02 14:08:23 -070013262 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13263 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
13264 }
13265
Robert Greenwalt434203a2010-10-11 16:00:27 -070013266 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13267 ProxyProperties proxy = intent.getParcelableExtra("proxy");
13268 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
13269 }
13270
Dianne Hackborn854060af2009-07-09 18:14:31 -070013271 /*
13272 * Prevent non-system code (defined here to be non-persistent
13273 * processes) from sending protected broadcasts.
13274 */
13275 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
13276 || callingUid == Process.SHELL_UID || callingUid == 0) {
13277 // Always okay.
13278 } else if (callerApp == null || !callerApp.persistent) {
13279 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013280 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070013281 intent.getAction())) {
13282 String msg = "Permission Denial: not allowed to send broadcast "
13283 + intent.getAction() + " from pid="
13284 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013285 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013286 throw new SecurityException(msg);
13287 }
13288 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013289 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013290 return BROADCAST_SUCCESS;
13291 }
13292 }
13293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013294 // Add to the sticky list if requested.
13295 if (sticky) {
13296 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13297 callingPid, callingUid)
13298 != PackageManager.PERMISSION_GRANTED) {
13299 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13300 + callingPid + ", uid=" + callingUid
13301 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013302 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013303 throw new SecurityException(msg);
13304 }
13305 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013306 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013307 + " and enforce permission " + requiredPermission);
13308 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13309 }
13310 if (intent.getComponent() != null) {
13311 throw new SecurityException(
13312 "Sticky broadcasts can't target a specific component");
13313 }
13314 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13315 if (list == null) {
13316 list = new ArrayList<Intent>();
13317 mStickyBroadcasts.put(intent.getAction(), list);
13318 }
13319 int N = list.size();
13320 int i;
13321 for (i=0; i<N; i++) {
13322 if (intent.filterEquals(list.get(i))) {
13323 // This sticky already exists, replace it.
13324 list.set(i, new Intent(intent));
13325 break;
13326 }
13327 }
13328 if (i >= N) {
13329 list.add(new Intent(intent));
13330 }
13331 }
13332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013333 // Figure out who all will receive this broadcast.
13334 List receivers = null;
13335 List<BroadcastFilter> registeredReceivers = null;
13336 try {
13337 if (intent.getComponent() != null) {
13338 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013339 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070013340 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 if (ai != null) {
13342 receivers = new ArrayList();
13343 ResolveInfo ri = new ResolveInfo();
Amith Yamasani742a6712011-05-04 14:49:28 -070013344 ri.activityInfo = getActivityInfoForUser(ai, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013345 receivers.add(ri);
13346 }
13347 } else {
Amith Yamasani742a6712011-05-04 14:49:28 -070013348 // TODO: Apply userId
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013349 // Need to resolve the intent to interested receivers...
13350 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13351 == 0) {
13352 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013353 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013354 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013355 }
Mihai Preda074edef2009-05-18 17:13:31 +020013356 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013357 }
13358 } catch (RemoteException ex) {
13359 // pm is in same process, this will never happen.
13360 }
13361
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013362 final boolean replacePending =
13363 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13364
Joe Onorato8a9b2202010-02-26 18:56:32 -080013365 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013366 + " replacePending=" + replacePending);
13367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013368 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13369 if (!ordered && NR > 0) {
13370 // If we are not serializing this broadcast, then send the
13371 // registered receivers separately so they don't wait for the
13372 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080013373 final BroadcastQueue queue = broadcastQueueForIntent(intent);
13374 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013375 callerPackage, callingPid, callingUid, requiredPermission,
13376 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013377 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013378 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080013379 TAG, "Enqueueing parallel broadcast " + r);
13380 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013381 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013382 queue.enqueueParallelBroadcastLocked(r);
13383 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013385 registeredReceivers = null;
13386 NR = 0;
13387 }
13388
13389 // Merge into one list.
13390 int ir = 0;
13391 if (receivers != null) {
13392 // A special case for PACKAGE_ADDED: do not allow the package
13393 // being added to see this broadcast. This prevents them from
13394 // using this as a back door to get run as soon as they are
13395 // installed. Maybe in the future we want to have a special install
13396 // broadcast or such for apps, but we'd like to deliberately make
13397 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013398 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013399 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13400 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13401 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013402 Uri data = intent.getData();
13403 if (data != null) {
13404 String pkgName = data.getSchemeSpecificPart();
13405 if (pkgName != null) {
13406 skipPackages = new String[] { pkgName };
13407 }
13408 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013409 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013410 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070013411 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013412 if (skipPackages != null && (skipPackages.length > 0)) {
13413 for (String skipPackage : skipPackages) {
13414 if (skipPackage != null) {
13415 int NT = receivers.size();
13416 for (int it=0; it<NT; it++) {
13417 ResolveInfo curt = (ResolveInfo)receivers.get(it);
13418 if (curt.activityInfo.packageName.equals(skipPackage)) {
13419 receivers.remove(it);
13420 it--;
13421 NT--;
13422 }
13423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013424 }
13425 }
13426 }
13427
13428 int NT = receivers != null ? receivers.size() : 0;
13429 int it = 0;
13430 ResolveInfo curt = null;
13431 BroadcastFilter curr = null;
13432 while (it < NT && ir < NR) {
13433 if (curt == null) {
13434 curt = (ResolveInfo)receivers.get(it);
13435 }
13436 if (curr == null) {
13437 curr = registeredReceivers.get(ir);
13438 }
13439 if (curr.getPriority() >= curt.priority) {
13440 // Insert this broadcast record into the final list.
13441 receivers.add(it, curr);
13442 ir++;
13443 curr = null;
13444 it++;
13445 NT++;
13446 } else {
13447 // Skip to the next ResolveInfo in the final list.
13448 it++;
13449 curt = null;
13450 }
13451 }
13452 }
13453 while (ir < NR) {
13454 if (receivers == null) {
13455 receivers = new ArrayList();
13456 }
13457 receivers.add(registeredReceivers.get(ir));
13458 ir++;
13459 }
13460
13461 if ((receivers != null && receivers.size() > 0)
13462 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013463 BroadcastQueue queue = broadcastQueueForIntent(intent);
13464 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013465 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013466 receivers, resultTo, resultCode, resultData, map, ordered,
13467 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013468 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013469 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080013470 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013471 if (DEBUG_BROADCAST) {
13472 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013473 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013474 }
Christopher Tatef46723b2012-01-26 14:19:24 -080013475 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013476 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013477 queue.enqueueOrderedBroadcastLocked(r);
13478 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013480 }
13481
13482 return BROADCAST_SUCCESS;
13483 }
13484
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013485 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013486 // Refuse possible leaked file descriptors
13487 if (intent != null && intent.hasFileDescriptors() == true) {
13488 throw new IllegalArgumentException("File descriptors passed in Intent");
13489 }
13490
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013491 int flags = intent.getFlags();
13492
13493 if (!mProcessesReady) {
13494 // if the caller really truly claims to know what they're doing, go
13495 // ahead and allow the broadcast without launching any receivers
13496 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13497 intent = new Intent(intent);
13498 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13499 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13500 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13501 + " before boot completion");
13502 throw new IllegalStateException("Cannot broadcast before boot completed");
13503 }
13504 }
13505
13506 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13507 throw new IllegalArgumentException(
13508 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13509 }
13510
13511 return intent;
13512 }
13513
13514 public final int broadcastIntent(IApplicationThread caller,
13515 Intent intent, String resolvedType, IIntentReceiver resultTo,
13516 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013517 String requiredPermission, boolean serialized, boolean sticky, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013518 enforceNotIsolatedCaller("broadcastIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013519 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013520 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013522 final ProcessRecord callerApp = getRecordForAppLocked(caller);
13523 final int callingPid = Binder.getCallingPid();
13524 final int callingUid = Binder.getCallingUid();
13525 final long origId = Binder.clearCallingIdentity();
13526 int res = broadcastIntentLocked(callerApp,
13527 callerApp != null ? callerApp.info.packageName : null,
13528 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070013529 resultCode, resultData, map, requiredPermission, serialized, sticky,
13530 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 Binder.restoreCallingIdentity(origId);
13532 return res;
13533 }
13534 }
13535
13536 int broadcastIntentInPackage(String packageName, int uid,
13537 Intent intent, String resolvedType, IIntentReceiver resultTo,
13538 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013539 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013540 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013541 intent = verifyBroadcastLocked(intent);
13542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013543 final long origId = Binder.clearCallingIdentity();
13544 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13545 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013546 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013547 Binder.restoreCallingIdentity(origId);
13548 return res;
13549 }
13550 }
13551
Amith Yamasani742a6712011-05-04 14:49:28 -070013552 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13553 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013554 // Refuse possible leaked file descriptors
13555 if (intent != null && intent.hasFileDescriptors() == true) {
13556 throw new IllegalArgumentException("File descriptors passed in Intent");
13557 }
13558
13559 synchronized(this) {
13560 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13561 != PackageManager.PERMISSION_GRANTED) {
13562 String msg = "Permission Denial: unbroadcastIntent() from pid="
13563 + Binder.getCallingPid()
13564 + ", uid=" + Binder.getCallingUid()
13565 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013566 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013567 throw new SecurityException(msg);
13568 }
13569 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13570 if (list != null) {
13571 int N = list.size();
13572 int i;
13573 for (i=0; i<N; i++) {
13574 if (intent.filterEquals(list.get(i))) {
13575 list.remove(i);
13576 break;
13577 }
13578 }
13579 }
13580 }
13581 }
13582
13583 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13584 String resultData, Bundle resultExtras, boolean resultAbort,
13585 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013586 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13587 if (r == null) {
13588 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013589 return false;
13590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013591
Christopher Tatef46723b2012-01-26 14:19:24 -080013592 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13593 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013594 }
13595
13596 public void finishReceiver(IBinder who, int resultCode, String resultData,
13597 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013598 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013599
13600 // Refuse possible leaked file descriptors
13601 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13602 throw new IllegalArgumentException("File descriptors passed in Bundle");
13603 }
13604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013605 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080013606 try {
13607 boolean doNext = false;
13608 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013609
Christopher Tatef46723b2012-01-26 14:19:24 -080013610 synchronized(this) {
13611 r = broadcastRecordForReceiverLocked(who);
13612 if (r != null) {
13613 doNext = r.queue.finishReceiverLocked(r, resultCode,
13614 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013616 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013617
Christopher Tatef46723b2012-01-26 14:19:24 -080013618 if (doNext) {
13619 r.queue.processNextBroadcast(false);
13620 }
13621 trimApplications();
13622 } finally {
13623 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070013624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013625 }
13626
13627 private final void processCurBroadcastLocked(BroadcastRecord r,
13628 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013629 if (DEBUG_BROADCAST) Slog.v(TAG,
13630 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013631 if (app.thread == null) {
13632 throw new RemoteException();
13633 }
13634 r.receiver = app.thread.asBinder();
13635 r.curApp = app;
13636 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013637 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013638
13639 // Tell the application to launch this receiver.
13640 r.intent.setComponent(r.curComponent);
13641
13642 boolean started = false;
13643 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013644 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013645 "Delivering to component " + r.curComponent
13646 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070013647 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013648 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040013649 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013650 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013651 if (DEBUG_BROADCAST) Slog.v(TAG,
13652 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013653 started = true;
13654 } finally {
13655 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013656 if (DEBUG_BROADCAST) Slog.v(TAG,
13657 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013658 r.receiver = null;
13659 r.curApp = null;
13660 app.curReceiver = null;
13661 }
13662 }
13663
13664 }
13665
Jeff Brown4d94a762010-09-23 11:33:28 -070013666 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013667 Intent intent, int resultCode, String data, Bundle extras,
13668 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070013669 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013670 if (app != null && app.thread != null) {
13671 // If we have an app thread, do the call through that so it is
13672 // correctly ordered with other one-way calls.
13673 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013674 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013675 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013676 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013677 }
13678 }
13679
Jeff Brown4d94a762010-09-23 11:33:28 -070013680 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013681 BroadcastFilter filter, boolean ordered) {
13682 boolean skip = false;
13683 if (filter.requiredPermission != null) {
13684 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013685 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013686 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013687 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013688 + r.intent.toString()
13689 + " from " + r.callerPackage + " (pid="
13690 + r.callingPid + ", uid=" + r.callingUid + ")"
13691 + " requires " + filter.requiredPermission
13692 + " due to registered receiver " + filter);
13693 skip = true;
13694 }
13695 }
13696 if (r.requiredPermission != null) {
13697 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013698 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013699 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013700 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013701 + r.intent.toString()
13702 + " to " + filter.receiverList.app
13703 + " (pid=" + filter.receiverList.pid
13704 + ", uid=" + filter.receiverList.uid + ")"
13705 + " requires " + r.requiredPermission
13706 + " due to sender " + r.callerPackage
13707 + " (uid " + r.callingUid + ")");
13708 skip = true;
13709 }
13710 }
13711
13712 if (!skip) {
13713 // If this is not being sent as an ordered broadcast, then we
13714 // don't want to touch the fields that keep track of the current
13715 // state of ordered broadcasts.
13716 if (ordered) {
13717 r.receiver = filter.receiverList.receiver.asBinder();
13718 r.curFilter = filter;
13719 filter.receiverList.curBroadcast = r;
13720 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013721 if (filter.receiverList.app != null) {
13722 // Bump hosting application to no longer be in background
13723 // scheduling class. Note that we can't do that if there
13724 // isn't an app... but we can only be in that case for
13725 // things that directly call the IActivityManager API, which
13726 // are already core system stuff so don't matter for this.
13727 r.curApp = filter.receiverList.app;
13728 filter.receiverList.app.curReceiver = r;
13729 updateOomAdjLocked();
13730 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013731 }
13732 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013733 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013734 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013735 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013736 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013737 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013738 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013739 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013740 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013741 if (ordered) {
13742 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
13743 }
13744 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013745 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013746 if (ordered) {
13747 r.receiver = null;
13748 r.curFilter = null;
13749 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013750 if (filter.receiverList.app != null) {
13751 filter.receiverList.app.curReceiver = null;
13752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013753 }
13754 }
13755 }
13756 }
13757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013758 // =========================================================
13759 // INSTRUMENTATION
13760 // =========================================================
13761
13762 public boolean startInstrumentation(ComponentName className,
13763 String profileFile, int flags, Bundle arguments,
13764 IInstrumentationWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013765 enforceNotIsolatedCaller("startInstrumentation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013766 // Refuse possible leaked file descriptors
13767 if (arguments != null && arguments.hasFileDescriptors()) {
13768 throw new IllegalArgumentException("File descriptors passed in Bundle");
13769 }
13770
13771 synchronized(this) {
13772 InstrumentationInfo ii = null;
13773 ApplicationInfo ai = null;
13774 try {
13775 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013776 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013777 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013778 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013779 } catch (PackageManager.NameNotFoundException e) {
13780 }
13781 if (ii == null) {
13782 reportStartInstrumentationFailure(watcher, className,
13783 "Unable to find instrumentation info for: " + className);
13784 return false;
13785 }
13786 if (ai == null) {
13787 reportStartInstrumentationFailure(watcher, className,
13788 "Unable to find instrumentation target package: " + ii.targetPackage);
13789 return false;
13790 }
13791
13792 int match = mContext.getPackageManager().checkSignatures(
13793 ii.targetPackage, ii.packageName);
13794 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13795 String msg = "Permission Denial: starting instrumentation "
13796 + className + " from pid="
13797 + Binder.getCallingPid()
13798 + ", uid=" + Binder.getCallingPid()
13799 + " not allowed because package " + ii.packageName
13800 + " does not have a signature matching the target "
13801 + ii.targetPackage;
13802 reportStartInstrumentationFailure(watcher, className, msg);
13803 throw new SecurityException(msg);
13804 }
13805
13806 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013807 // Instrumentation can kill and relaunch even persistent processes
13808 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013809 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013810 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013811 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013812 app.instrumentationProfileFile = profileFile;
13813 app.instrumentationArguments = arguments;
13814 app.instrumentationWatcher = watcher;
13815 app.instrumentationResultClass = className;
13816 Binder.restoreCallingIdentity(origId);
13817 }
13818
13819 return true;
13820 }
13821
13822 /**
13823 * Report errors that occur while attempting to start Instrumentation. Always writes the
13824 * error to the logs, but if somebody is watching, send the report there too. This enables
13825 * the "am" command to report errors with more information.
13826 *
13827 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13828 * @param cn The component name of the instrumentation.
13829 * @param report The error report.
13830 */
13831 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13832 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013833 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013834 try {
13835 if (watcher != null) {
13836 Bundle results = new Bundle();
13837 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13838 results.putString("Error", report);
13839 watcher.instrumentationStatus(cn, -1, results);
13840 }
13841 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013842 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013843 }
13844 }
13845
13846 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13847 if (app.instrumentationWatcher != null) {
13848 try {
13849 // NOTE: IInstrumentationWatcher *must* be oneway here
13850 app.instrumentationWatcher.instrumentationFinished(
13851 app.instrumentationClass,
13852 resultCode,
13853 results);
13854 } catch (RemoteException e) {
13855 }
13856 }
13857 app.instrumentationWatcher = null;
13858 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013859 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013860 app.instrumentationProfileFile = null;
13861 app.instrumentationArguments = null;
13862
Christopher Tate3dacd842011-08-19 14:56:15 -070013863 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013864 }
13865
13866 public void finishInstrumentation(IApplicationThread target,
13867 int resultCode, Bundle results) {
13868 // Refuse possible leaked file descriptors
13869 if (results != null && results.hasFileDescriptors()) {
13870 throw new IllegalArgumentException("File descriptors passed in Intent");
13871 }
13872
13873 synchronized(this) {
13874 ProcessRecord app = getRecordForAppLocked(target);
13875 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013876 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013877 return;
13878 }
13879 final long origId = Binder.clearCallingIdentity();
13880 finishInstrumentationLocked(app, resultCode, results);
13881 Binder.restoreCallingIdentity(origId);
13882 }
13883 }
13884
13885 // =========================================================
13886 // CONFIGURATION
13887 // =========================================================
13888
13889 public ConfigurationInfo getDeviceConfigurationInfo() {
13890 ConfigurationInfo config = new ConfigurationInfo();
13891 synchronized (this) {
13892 config.reqTouchScreen = mConfiguration.touchscreen;
13893 config.reqKeyboardType = mConfiguration.keyboard;
13894 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013895 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13896 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013897 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13898 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013899 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13900 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013901 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13902 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013903 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013904 }
13905 return config;
13906 }
13907
13908 public Configuration getConfiguration() {
13909 Configuration ci;
13910 synchronized(this) {
13911 ci = new Configuration(mConfiguration);
13912 }
13913 return ci;
13914 }
13915
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013916 public void updatePersistentConfiguration(Configuration values) {
13917 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13918 "updateConfiguration()");
13919 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13920 "updateConfiguration()");
13921 if (values == null) {
13922 throw new NullPointerException("Configuration must not be null");
13923 }
13924
13925 synchronized(this) {
13926 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013927 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013928 Binder.restoreCallingIdentity(origId);
13929 }
13930 }
13931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013932 public void updateConfiguration(Configuration values) {
13933 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13934 "updateConfiguration()");
13935
13936 synchronized(this) {
13937 if (values == null && mWindowManager != null) {
13938 // sentinel: fetch the current configuration from the window manager
13939 values = mWindowManager.computeNewConfiguration();
13940 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013941
13942 if (mWindowManager != null) {
13943 mProcessList.applyDisplaySize(mWindowManager);
13944 }
13945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013946 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013947 if (values != null) {
13948 Settings.System.clearConfiguration(values);
13949 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013950 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013951 Binder.restoreCallingIdentity(origId);
13952 }
13953 }
13954
13955 /**
13956 * Do either or both things: (1) change the current configuration, and (2)
13957 * make sure the given activity is running with the (now) current
13958 * configuration. Returns true if the activity has been left running, or
13959 * false if <var>starting</var> is being destroyed to match the new
13960 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013961 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013962 */
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013963 boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013964 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013965 int changes = 0;
13966
13967 boolean kept = true;
13968
13969 if (values != null) {
13970 Configuration newConfig = new Configuration(mConfiguration);
13971 changes = newConfig.updateFrom(values);
13972 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013973 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013974 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013975 }
13976
Doug Zongker2bec3d42009-12-04 12:52:44 -080013977 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013978
Dianne Hackborn813075a62011-11-14 17:45:19 -080013979 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013980 saveLocaleLocked(values.locale,
13981 !values.locale.equals(mConfiguration.locale),
13982 values.userSetLocale);
13983 }
13984
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013985 mConfigurationSeq++;
13986 if (mConfigurationSeq <= 0) {
13987 mConfigurationSeq = 1;
13988 }
13989 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013990 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013991 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013992
13993 final Configuration configCopy = new Configuration(mConfiguration);
13994
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013995 AttributeCache ac = AttributeCache.instance();
13996 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013997 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013999
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070014000 // Make sure all resources in our process are updated
14001 // right now, so that anyone who is going to retrieve
14002 // resource values after we return will be sure to get
14003 // the new ones. This is especially important during
14004 // boot, where the first config change needs to guarantee
14005 // all resources have that config before following boot
14006 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080014007 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070014008
Dianne Hackborn31ca8542011-07-19 14:58:28 -070014009 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080014010 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080014011 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080014012 mHandler.sendMessage(msg);
14013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014014
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014015 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14016 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014017 try {
14018 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014019 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070014020 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080014021 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014022 }
14023 } catch (Exception e) {
14024 }
14025 }
14026 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080014027 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14028 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014029 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070014030 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080014031 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14032 broadcastIntentLocked(null, null,
14033 new Intent(Intent.ACTION_LOCALE_CHANGED),
14034 null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070014035 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080014036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014037 }
14038 }
14039
14040 if (changes != 0 && starting == null) {
14041 // If the configuration changed, and the caller is not already
14042 // in the process of starting an activity, then find the top
14043 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014044 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014045 }
14046
14047 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014048 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080014049 // And we need to make sure at this point that all other activities
14050 // are made visible with the correct configuration.
14051 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014052 }
14053
Dianne Hackborne36d6e22010-02-17 19:46:25 -080014054 if (values != null && mWindowManager != null) {
14055 mWindowManager.setNewConfiguration(mConfiguration);
14056 }
14057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014058 return kept;
14059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014060
14061 /**
14062 * Save the locale. You must be inside a synchronized (this) block.
14063 */
14064 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14065 if(isDiff) {
14066 SystemProperties.set("user.language", l.getLanguage());
14067 SystemProperties.set("user.region", l.getCountry());
14068 }
14069
14070 if(isPersist) {
14071 SystemProperties.set("persist.sys.language", l.getLanguage());
14072 SystemProperties.set("persist.sys.country", l.getCountry());
14073 SystemProperties.set("persist.sys.localevar", l.getVariant());
14074 }
14075 }
14076
14077 // =========================================================
14078 // LIFETIME MANAGEMENT
14079 // =========================================================
14080
Christopher Tatef46723b2012-01-26 14:19:24 -080014081 // Returns which broadcast queue the app is the current [or imminent] receiver
14082 // on, or 'null' if the app is not an active broadcast recipient.
14083 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14084 BroadcastRecord r = app.curReceiver;
14085 if (r != null) {
14086 return r.queue;
14087 }
14088
14089 // It's not the current receiver, but it might be starting up to become one
14090 synchronized (this) {
14091 for (BroadcastQueue queue : mBroadcastQueues) {
14092 r = queue.mPendingBroadcast;
14093 if (r != null && r.curApp == app) {
14094 // found it; report which queue it's in
14095 return queue;
14096 }
14097 }
14098 }
14099
14100 return null;
14101 }
14102
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014103 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014104 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014105 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014106 // This adjustment has already been computed. If we are calling
14107 // from the top, we may have already computed our adjustment with
14108 // an earlier hidden adjustment that isn't really for us... if
14109 // so, use the new hidden adjustment.
14110 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014111 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014112 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014113 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014114 }
14115
14116 if (app.thread == null) {
14117 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014118 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014119 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014120 }
14121
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014122 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14123 app.adjSource = null;
14124 app.adjTarget = null;
14125 app.empty = false;
14126 app.hidden = false;
14127
14128 final int activitiesSize = app.activities.size();
14129
Dianne Hackborn7d608422011-08-07 16:24:18 -070014130 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014131 // The max adjustment doesn't allow this app to be anything
14132 // below foreground, so it is not worth doing work for it.
14133 app.adjType = "fixed";
14134 app.adjSeq = mAdjSeq;
14135 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014136 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014137 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014138 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014139 // System process can do UI, and when they do we want to have
14140 // them trim their memory after the user leaves the UI. To
14141 // facilitate this, here we need to determine whether or not it
14142 // is currently showing UI.
14143 app.systemNoUi = true;
14144 if (app == TOP_APP) {
14145 app.systemNoUi = false;
14146 } else if (activitiesSize > 0) {
14147 for (int j = 0; j < activitiesSize; j++) {
14148 final ActivityRecord r = app.activities.get(j);
14149 if (r.visible) {
14150 app.systemNoUi = false;
14151 break;
14152 }
14153 }
14154 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014155 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014156 }
14157
14158 final boolean hadForegroundActivities = app.foregroundActivities;
14159
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014160 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014161 app.keeping = false;
14162 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014163
The Android Open Source Project4df24232009-03-05 14:34:35 -080014164 // Determine the importance of the process, starting with most
14165 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014166 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014167 int schedGroup;
Christopher Tatef46723b2012-01-26 14:19:24 -080014168 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014169 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014170 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014171 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014172 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014173 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014174 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014175 } else if (app.instrumentationClass != null) {
14176 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014177 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014178 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014179 app.adjType = "instrumentation";
Christopher Tatef46723b2012-01-26 14:19:24 -080014180 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014181 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080014182 // counts as being in the foreground for OOM killer purposes.
14183 // It's placed in a sched group based on the nature of the
14184 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014185 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080014186 schedGroup = (queue == mFgBroadcastQueue)
14187 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014188 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014189 } else if (app.executingServices.size() > 0) {
14190 // An app that is currently executing a service callback also
14191 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014192 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014193 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014194 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014195 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014196 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014197 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014198 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014199 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014200 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014201 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014202 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014203 // A very not-needed process. If this is lower in the lru list,
14204 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014205 adj = hiddenAdj;
14206 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014207 app.hidden = true;
14208 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014209 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014210 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014211
14212 // Examine all activities if not already foreground.
14213 if (!app.foregroundActivities && activitiesSize > 0) {
14214 for (int j = 0; j < activitiesSize; j++) {
14215 final ActivityRecord r = app.activities.get(j);
14216 if (r.visible) {
14217 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014218 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14219 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014220 app.adjType = "visible";
14221 }
14222 schedGroup = Process.THREAD_GROUP_DEFAULT;
14223 app.hidden = false;
14224 app.foregroundActivities = true;
14225 break;
14226 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
14227 || r.state == ActivityState.STOPPING) {
14228 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014229 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14230 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014231 app.adjType = "stopping";
14232 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080014233 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014234 app.foregroundActivities = true;
14235 }
14236 }
14237 }
14238
Dianne Hackborn7d608422011-08-07 16:24:18 -070014239 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014240 if (app.foregroundServices) {
14241 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014242 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014243 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014244 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014245 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014246 } else if (app.forcingToForeground != null) {
14247 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014248 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014249 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014250 app.adjType = "force-foreground";
14251 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014252 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014253 }
14254 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014255
Dianne Hackborn7d608422011-08-07 16:24:18 -070014256 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014257 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014258 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014259 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014260 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014261 app.adjType = "heavy";
14262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014263
Dianne Hackborn7d608422011-08-07 16:24:18 -070014264 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014265 // This process is hosting what we currently consider to be the
14266 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014267 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014268 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014269 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014270 app.adjType = "home";
14271 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014272
Dianne Hackbornf35fe232011-11-01 19:25:20 -070014273 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
14274 && app.activities.size() > 0) {
14275 // This was the previous process that showed UI to the user.
14276 // We want to try to keep it around more aggressively, to give
14277 // a good experience around switching between two apps.
14278 adj = ProcessList.PREVIOUS_APP_ADJ;
14279 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14280 app.hidden = false;
14281 app.adjType = "previous";
14282 }
14283
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014284 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14285 + " reason=" + app.adjType);
14286
The Android Open Source Project4df24232009-03-05 14:34:35 -080014287 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014288 // there are applications dependent on our services or providers, but
14289 // this gives us a baseline and makes sure we don't get into an
14290 // infinite recursion.
14291 app.adjSeq = mAdjSeq;
14292 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014293
Christopher Tate6fa95972009-06-05 18:43:55 -070014294 if (mBackupTarget != null && app == mBackupTarget.app) {
14295 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070014296 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014297 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014298 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014299 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014300 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070014301 }
14302 }
14303
Dianne Hackborn7d608422011-08-07 16:24:18 -070014304 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014305 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014306 final long now = SystemClock.uptimeMillis();
14307 // This process is more important if the top activity is
14308 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070014309 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014310 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014311 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014312 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014313 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014314 // If this process has shown some UI, let it immediately
14315 // go to the LRU list because it may be pretty heavy with
14316 // UI stuff. We'll tag it with a label just to help
14317 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014318 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014319 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014320 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014321 } else {
14322 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14323 // This service has seen some activity within
14324 // recent memory, so we will keep its process ahead
14325 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014326 if (adj > ProcessList.SERVICE_ADJ) {
14327 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014328 app.adjType = "started-services";
14329 app.hidden = false;
14330 }
14331 }
14332 // If we have let the service slide into the background
14333 // state, still have some text describing what it is doing
14334 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014335 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014336 app.adjType = "started-bg-services";
14337 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014338 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014339 // Don't kill this process because it is doing work; it
14340 // has said it is doing work.
14341 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014342 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014343 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014344 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014345 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014346 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014347 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014348 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014349 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014350 // XXX should compute this based on the max of
14351 // all connected clients.
14352 ConnectionRecord cr = clist.get(i);
14353 if (cr.binding.client == app) {
14354 // Binding to ourself is not interesting.
14355 continue;
14356 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014357 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014358 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014359 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014360 int myHiddenAdj = hiddenAdj;
14361 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014362 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014363 myHiddenAdj = client.hiddenAdj;
14364 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014365 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014366 }
14367 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014368 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014369 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014370 String adjType = null;
14371 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14372 // Not doing bind OOM management, so treat
14373 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014374 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014375 // If this process has shown some UI, let it immediately
14376 // go to the LRU list because it may be pretty heavy with
14377 // UI stuff. We'll tag it with a label just to help
14378 // debug and understand what is going on.
14379 if (adj > clientAdj) {
14380 adjType = "bound-bg-ui-services";
14381 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014382 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014383 clientAdj = adj;
14384 } else {
14385 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14386 // This service has not seen activity within
14387 // recent memory, so allow it to drop to the
14388 // LRU list if there is no other reason to keep
14389 // it around. We'll also tag it with a label just
14390 // to help debug and undertand what is going on.
14391 if (adj > clientAdj) {
14392 adjType = "bound-bg-services";
14393 }
14394 clientAdj = adj;
14395 }
14396 }
14397 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014398 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014399 // If this process has recently shown UI, and
14400 // the process that is binding to it is less
14401 // important than being visible, then we don't
14402 // care about the binding as much as we care
14403 // about letting this process get into the LRU
14404 // list to be killed and restarted if needed for
14405 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014406 if (app.hasShownUi && app != mHomeProcess
14407 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014408 adjType = "bound-bg-ui-services";
14409 } else {
14410 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14411 |Context.BIND_IMPORTANT)) != 0) {
14412 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014413 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14414 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14415 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14416 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14417 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014418 adj = clientAdj;
14419 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014420 app.pendingUiClean = true;
14421 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14422 adj = ProcessList.VISIBLE_APP_ADJ;
14423 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014424 }
14425 if (!client.hidden) {
14426 app.hidden = false;
14427 }
14428 if (client.keeping) {
14429 app.keeping = true;
14430 }
14431 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014432 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014433 }
14434 if (adjType != null) {
14435 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014436 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14437 .REASON_SERVICE_IN_USE;
14438 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014439 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014440 app.adjTarget = s.name;
14441 }
14442 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14443 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14444 schedGroup = Process.THREAD_GROUP_DEFAULT;
14445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014446 }
14447 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014448 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14449 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014450 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014451 (a.visible || a.state == ActivityState.RESUMED
14452 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014453 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014454 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14455 schedGroup = Process.THREAD_GROUP_DEFAULT;
14456 }
14457 app.hidden = false;
14458 app.adjType = "service";
14459 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14460 .REASON_SERVICE_IN_USE;
14461 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014462 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014463 app.adjTarget = s.name;
14464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014466 }
14467 }
14468 }
14469 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014470
Dianne Hackborn287952c2010-09-22 22:34:31 -070014471 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014472 // would like to avoid killing it unless it would prevent the current
14473 // application from running. By default we put the process in
14474 // with the rest of the background processes; as we scan through
14475 // its services we may bump it up from there.
14476 if (adj > hiddenAdj) {
14477 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014478 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014479 app.adjType = "bg-services";
14480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014481 }
14482
Dianne Hackborn7d608422011-08-07 16:24:18 -070014483 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014484 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014485 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014486 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014487 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014488 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014489 if (cpr.clients.size() != 0) {
14490 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014491 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014492 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070014493 if (client == app) {
14494 // Being our own client is not interesting.
14495 continue;
14496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014497 int myHiddenAdj = hiddenAdj;
14498 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014499 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014500 myHiddenAdj = client.hiddenAdj;
14501 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014502 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014503 }
14504 }
14505 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014506 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014507 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014508 if (app.hasShownUi && app != mHomeProcess
14509 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014510 app.adjType = "bg-ui-provider";
14511 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014512 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14513 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014514 app.adjType = "provider";
14515 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014516 if (!client.hidden) {
14517 app.hidden = false;
14518 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014519 if (client.keeping) {
14520 app.keeping = true;
14521 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070014522 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14523 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014524 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014525 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014526 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014527 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014528 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14529 schedGroup = Process.THREAD_GROUP_DEFAULT;
14530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014531 }
14532 }
14533 // If the provider has external (non-framework) process
14534 // dependencies, ensure that its adjustment is at least
14535 // FOREGROUND_APP_ADJ.
14536 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014537 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14538 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014539 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014540 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014541 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014542 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014543 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014544 }
14545 }
14546 }
14547 }
14548
14549 app.curRawAdj = adj;
14550
Joe Onorato8a9b2202010-02-26 18:56:32 -080014551 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014552 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14553 if (adj > app.maxAdj) {
14554 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014555 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014556 schedGroup = Process.THREAD_GROUP_DEFAULT;
14557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014558 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014559 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014560 app.keeping = true;
14561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014562
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014563 if (app.hasAboveClient) {
14564 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14565 // then we need to drop its adjustment to be lower than the service's
14566 // in order to honor the request. We want to drop it by one adjustment
14567 // level... but there is special meaning applied to various levels so
14568 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014569 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014570 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014571 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14572 adj = ProcessList.VISIBLE_APP_ADJ;
14573 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14574 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14575 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14576 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014577 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014578 adj++;
14579 }
14580 }
14581
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014582 if (adj == ProcessList.SERVICE_ADJ) {
14583 if (doingAll) {
14584 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14585 mNewNumServiceProcs++;
14586 }
14587 if (app.serviceb) {
14588 adj = ProcessList.SERVICE_B_ADJ;
14589 }
14590 } else {
14591 app.serviceb = false;
14592 }
14593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014594 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014595 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014596
14597 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014598 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14599 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014600 }
14601
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014602 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014603 }
14604
14605 /**
14606 * Ask a given process to GC right now.
14607 */
14608 final void performAppGcLocked(ProcessRecord app) {
14609 try {
14610 app.lastRequestedGc = SystemClock.uptimeMillis();
14611 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014612 if (app.reportLowMemory) {
14613 app.reportLowMemory = false;
14614 app.thread.scheduleLowMemory();
14615 } else {
14616 app.thread.processInBackground();
14617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014618 }
14619 } catch (Exception e) {
14620 // whatever.
14621 }
14622 }
14623
14624 /**
14625 * Returns true if things are idle enough to perform GCs.
14626 */
Josh Bartel7f208742010-02-25 11:01:44 -060014627 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080014628 boolean processingBroadcasts = false;
14629 for (BroadcastQueue q : mBroadcastQueues) {
14630 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14631 processingBroadcasts = true;
14632 }
14633 }
14634 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014635 && (mSleeping || (mMainStack.mResumedActivity != null &&
14636 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014637 }
14638
14639 /**
14640 * Perform GCs on all processes that are waiting for it, but only
14641 * if things are idle.
14642 */
14643 final void performAppGcsLocked() {
14644 final int N = mProcessesToGc.size();
14645 if (N <= 0) {
14646 return;
14647 }
Josh Bartel7f208742010-02-25 11:01:44 -060014648 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014649 while (mProcessesToGc.size() > 0) {
14650 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014651 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014652 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14653 <= SystemClock.uptimeMillis()) {
14654 // To avoid spamming the system, we will GC processes one
14655 // at a time, waiting a few seconds between each.
14656 performAppGcLocked(proc);
14657 scheduleAppGcsLocked();
14658 return;
14659 } else {
14660 // It hasn't been long enough since we last GCed this
14661 // process... put it in the list to wait for its time.
14662 addProcessToGcListLocked(proc);
14663 break;
14664 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014665 }
14666 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014667
14668 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014669 }
14670 }
14671
14672 /**
14673 * If all looks good, perform GCs on all processes waiting for them.
14674 */
14675 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014676 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014677 performAppGcsLocked();
14678 return;
14679 }
14680 // Still not idle, wait some more.
14681 scheduleAppGcsLocked();
14682 }
14683
14684 /**
14685 * Schedule the execution of all pending app GCs.
14686 */
14687 final void scheduleAppGcsLocked() {
14688 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014689
14690 if (mProcessesToGc.size() > 0) {
14691 // Schedule a GC for the time to the next process.
14692 ProcessRecord proc = mProcessesToGc.get(0);
14693 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14694
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014695 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014696 long now = SystemClock.uptimeMillis();
14697 if (when < (now+GC_TIMEOUT)) {
14698 when = now + GC_TIMEOUT;
14699 }
14700 mHandler.sendMessageAtTime(msg, when);
14701 }
14702 }
14703
14704 /**
14705 * Add a process to the array of processes waiting to be GCed. Keeps the
14706 * list in sorted order by the last GC time. The process can't already be
14707 * on the list.
14708 */
14709 final void addProcessToGcListLocked(ProcessRecord proc) {
14710 boolean added = false;
14711 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14712 if (mProcessesToGc.get(i).lastRequestedGc <
14713 proc.lastRequestedGc) {
14714 added = true;
14715 mProcessesToGc.add(i+1, proc);
14716 break;
14717 }
14718 }
14719 if (!added) {
14720 mProcessesToGc.add(0, proc);
14721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014722 }
14723
14724 /**
14725 * Set up to ask a process to GC itself. This will either do it
14726 * immediately, or put it on the list of processes to gc the next
14727 * time things are idle.
14728 */
14729 final void scheduleAppGcLocked(ProcessRecord app) {
14730 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014731 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014732 return;
14733 }
14734 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014735 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014736 scheduleAppGcsLocked();
14737 }
14738 }
14739
Dianne Hackborn287952c2010-09-22 22:34:31 -070014740 final void checkExcessivePowerUsageLocked(boolean doKills) {
14741 updateCpuStatsNow();
14742
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014743 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014744 boolean doWakeKills = doKills;
14745 boolean doCpuKills = doKills;
14746 if (mLastPowerCheckRealtime == 0) {
14747 doWakeKills = false;
14748 }
14749 if (mLastPowerCheckUptime == 0) {
14750 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014751 }
14752 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014753 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014754 }
14755 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014756 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14757 final long curUptime = SystemClock.uptimeMillis();
14758 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14759 mLastPowerCheckRealtime = curRealtime;
14760 mLastPowerCheckUptime = curUptime;
14761 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14762 doWakeKills = false;
14763 }
14764 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14765 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014766 }
14767 int i = mLruProcesses.size();
14768 while (i > 0) {
14769 i--;
14770 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014771 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014772 long wtime;
14773 synchronized (stats) {
14774 wtime = stats.getProcessWakeTime(app.info.uid,
14775 app.pid, curRealtime);
14776 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014777 long wtimeUsed = wtime - app.lastWakeTime;
14778 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14779 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014780 StringBuilder sb = new StringBuilder(128);
14781 sb.append("Wake for ");
14782 app.toShortString(sb);
14783 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014784 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014785 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014786 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014787 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014788 sb.append((wtimeUsed*100)/realtimeSince);
14789 sb.append("%)");
14790 Slog.i(TAG, sb.toString());
14791 sb.setLength(0);
14792 sb.append("CPU for ");
14793 app.toShortString(sb);
14794 sb.append(": over ");
14795 TimeUtils.formatDuration(uptimeSince, sb);
14796 sb.append(" used ");
14797 TimeUtils.formatDuration(cputimeUsed, sb);
14798 sb.append(" (");
14799 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014800 sb.append("%)");
14801 Slog.i(TAG, sb.toString());
14802 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014803 // If a process has held a wake lock for more
14804 // than 50% of the time during this period,
14805 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014806 if (doWakeKills && realtimeSince > 0
14807 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14808 synchronized (stats) {
14809 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14810 realtimeSince, wtimeUsed);
14811 }
14812 Slog.w(TAG, "Excessive wake lock in " + app.processName
14813 + " (pid " + app.pid + "): held " + wtimeUsed
14814 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014815 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14816 app.processName, app.setAdj, "excessive wake lock");
14817 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014818 } else if (doCpuKills && uptimeSince > 0
14819 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14820 synchronized (stats) {
14821 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14822 uptimeSince, cputimeUsed);
14823 }
14824 Slog.w(TAG, "Excessive CPU in " + app.processName
14825 + " (pid " + app.pid + "): used " + cputimeUsed
14826 + " during " + uptimeSince);
14827 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14828 app.processName, app.setAdj, "excessive cpu");
14829 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014830 } else {
14831 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014832 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014833 }
14834 }
14835 }
14836 }
14837
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014838 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014839 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014840 app.hiddenAdj = hiddenAdj;
14841
14842 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014843 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014844 }
14845
Dianne Hackborn287952c2010-09-22 22:34:31 -070014846 final boolean wasKeeping = app.keeping;
14847
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014848 boolean success = true;
14849
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014850 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014851
Jeff Brown10e89712011-07-08 18:52:57 -070014852 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014853 if (false) {
14854 // Removing for now. Forcing GCs is not so useful anymore
14855 // with Dalvik, and the new memory level hint facility is
14856 // better for what we need to do these days.
14857 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14858 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14859 // If this app is transitioning from foreground to
14860 // non-foreground, have it do a gc.
14861 scheduleAppGcLocked(app);
14862 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14863 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14864 // Likewise do a gc when an app is moving in to the
14865 // background (such as a service stopping).
14866 scheduleAppGcLocked(app);
14867 }
Jeff Brown10e89712011-07-08 18:52:57 -070014868 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014869
Jeff Brown10e89712011-07-08 18:52:57 -070014870 if (wasKeeping && !app.keeping) {
14871 // This app is no longer something we want to keep. Note
14872 // its current wake lock time to later know to kill it if
14873 // it is not behaving well.
14874 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14875 synchronized (stats) {
14876 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14877 app.pid, SystemClock.elapsedRealtime());
14878 }
14879 app.lastCpuTime = app.curCpuTime;
14880 }
14881
14882 app.setRawAdj = app.curRawAdj;
14883 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014884
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014885 if (app.curAdj != app.setAdj) {
14886 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014887 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014888 TAG, "Set " + app.pid + " " + app.processName +
14889 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014890 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014891 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014892 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014893 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014894 }
14895 }
14896 if (app.setSchedGroup != app.curSchedGroup) {
14897 app.setSchedGroup = app.curSchedGroup;
14898 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14899 "Setting process group of " + app.processName
14900 + " to " + app.curSchedGroup);
14901 if (app.waitingToKill != null &&
14902 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14903 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14904 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14905 app.processName, app.setAdj, app.waitingToKill);
14906 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014907 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014908 } else {
14909 if (true) {
14910 long oldId = Binder.clearCallingIdentity();
14911 try {
14912 Process.setProcessGroup(app.pid, app.curSchedGroup);
14913 } catch (Exception e) {
14914 Slog.w(TAG, "Failed setting process group of " + app.pid
14915 + " to " + app.curSchedGroup);
14916 e.printStackTrace();
14917 } finally {
14918 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014919 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014920 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014921 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014922 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014923 app.thread.setSchedulingGroup(app.curSchedGroup);
14924 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014925 }
14926 }
14927 }
14928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014929 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014930 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014931 }
14932
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014933 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014934 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014935 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborncbb722e2012-02-07 18:33:49 -080014936 for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) {
14937 ActivityRecord r = mMainStack.mPausingActivities.get(i);
14938 if (r.app != null) {
14939 resumedActivity = r;
14940 break;
14941 }
14942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014943 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014944 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014945 }
14946 }
14947 return resumedActivity;
14948 }
14949
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014950 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014951 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014952 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14953 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014954 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14955 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014956
14957 mAdjSeq++;
14958
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014959 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014960 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14961 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014962 if (nowHidden != wasHidden) {
14963 // Changed to/from hidden state, so apps after it in the LRU
14964 // list may also be changed.
14965 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014966 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014967 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014968 }
14969
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014970 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014971 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014972 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14973
14974 if (false) {
14975 RuntimeException e = new RuntimeException();
14976 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014977 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014978 }
14979
14980 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014981 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014982
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014983 // Let's determine how many processes we have running vs.
14984 // how many slots we have for background processes; we may want
14985 // to put multiple processes in a slot of there are enough of
14986 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014987 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014988 int factor = (mLruProcesses.size()-4)/numSlots;
14989 if (factor < 1) factor = 1;
14990 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014991 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014992
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014993 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014994 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014995 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014996 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014997 while (i > 0) {
14998 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014999 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080015000 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070015001 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
15002 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015003 && app.curAdj == curHiddenAdj) {
15004 step++;
15005 if (step >= factor) {
15006 step = 0;
15007 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015008 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015009 }
15010 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070015011 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015012 numHidden++;
15013 if (numHidden > mProcessLimit) {
15014 Slog.i(TAG, "No longer want " + app.processName
15015 + " (pid " + app.pid + "): hidden #" + numHidden);
15016 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
15017 app.processName, app.setAdj, "too many background");
15018 app.killedBackground = true;
15019 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070015020 }
15021 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080015022 if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
15023 // If this is an isolated process, and there are no
15024 // services running in it, then the process is no longer
15025 // needed. We agressively kill these because we can by
15026 // definition not re-use the same process again, and it is
15027 // good to avoid having whatever code was running in them
15028 // left sitting around after no longer needed.
15029 Slog.i(TAG, "Isolated process " + app.processName
15030 + " (pid " + app.pid + ") no longer needed");
15031 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
15032 app.processName, app.setAdj, "isolated not needed");
15033 app.killedBackground = true;
15034 Process.killProcessQuiet(app.pid);
15035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015036 }
15037 }
15038
Dianne Hackborne02c88a2011-10-28 13:58:15 -070015039 mNumServiceProcs = mNewNumServiceProcs;
15040
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015041 // Now determine the memory trimming level of background processes.
15042 // Unfortunately we need to start at the back of the list to do this
15043 // properly. We only do this if the number of background apps we
15044 // are managing to keep around is less than half the maximum we desire;
15045 // if we are keeping a good number around, we'll let them use whatever
15046 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070015047 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015048 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080015049 factor = numHidden/3;
15050 int minFactor = 2;
15051 if (mHomeProcess != null) minFactor++;
15052 if (mPreviousProcess != null) minFactor++;
15053 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015054 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015055 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015056 for (i=0; i<N; i++) {
15057 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080015058 if (app.curAdj >= ProcessList.HOME_APP_ADJ
15059 && app.curAdj != ProcessList.SERVICE_B_ADJ
15060 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015061 if (app.trimMemoryLevel < curLevel && app.thread != null) {
15062 try {
15063 app.thread.scheduleTrimMemory(curLevel);
15064 } catch (RemoteException e) {
15065 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080015066 if (false) {
15067 // For now we won't do this; our memory trimming seems
15068 // to be good enough at this point that destroying
15069 // activities causes more harm than good.
15070 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15071 && app != mHomeProcess && app != mPreviousProcess) {
15072 // For these apps we will also finish their activities
15073 // to help them free memory.
15074 mMainStack.destroyActivitiesLocked(app, false, "trim");
15075 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015076 }
15077 }
15078 app.trimMemoryLevel = curLevel;
15079 step++;
15080 if (step >= factor) {
15081 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015082 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15083 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015084 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015085 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15086 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015087 break;
15088 }
15089 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070015090 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015091 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015092 && app.thread != null) {
15093 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015094 app.thread.scheduleTrimMemory(
15095 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015096 } catch (RemoteException e) {
15097 }
15098 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015099 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070015100 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015101 && app.pendingUiClean) {
15102 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15103 && app.thread != null) {
15104 try {
15105 app.thread.scheduleTrimMemory(
15106 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15107 } catch (RemoteException e) {
15108 }
15109 }
15110 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15111 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015112 } else {
15113 app.trimMemoryLevel = 0;
15114 }
15115 }
15116 } else {
15117 final int N = mLruProcesses.size();
15118 for (i=0; i<N; i++) {
15119 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070015120 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015121 && app.pendingUiClean) {
15122 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15123 && app.thread != null) {
15124 try {
15125 app.thread.scheduleTrimMemory(
15126 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15127 } catch (RemoteException e) {
15128 }
15129 }
15130 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15131 app.pendingUiClean = false;
15132 } else {
15133 app.trimMemoryLevel = 0;
15134 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015135 }
15136 }
15137
15138 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070015139 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015141 }
15142
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070015143 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015144 synchronized (this) {
15145 int i;
15146
15147 // First remove any unused application processes whose package
15148 // has been removed.
15149 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15150 final ProcessRecord app = mRemovedProcesses.get(i);
15151 if (app.activities.size() == 0
15152 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080015153 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015154 TAG, "Exiting empty application process "
15155 + app.processName + " ("
15156 + (app.thread != null ? app.thread.asBinder() : null)
15157 + ")\n");
15158 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070015159 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
15160 app.processName, app.setAdj, "empty");
15161 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015162 } else {
15163 try {
15164 app.thread.scheduleExit();
15165 } catch (Exception e) {
15166 // Ignore exceptions.
15167 }
15168 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070015169 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015170 mRemovedProcesses.remove(i);
15171
15172 if (app.persistent) {
15173 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080015174 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015175 }
15176 }
15177 }
15178 }
15179
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015180 // Now update the oom adj for all processes.
15181 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015182 }
15183 }
15184
15185 /** This method sends the specified signal to each of the persistent apps */
15186 public void signalPersistentProcesses(int sig) throws RemoteException {
15187 if (sig != Process.SIGNAL_USR1) {
15188 throw new SecurityException("Only SIGNAL_USR1 is allowed");
15189 }
15190
15191 synchronized (this) {
15192 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15193 != PackageManager.PERMISSION_GRANTED) {
15194 throw new SecurityException("Requires permission "
15195 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15196 }
15197
Dianne Hackborndd71fc82009-12-16 19:24:32 -080015198 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15199 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015200 if (r.thread != null && r.persistent) {
15201 Process.sendSignal(r.pid, sig);
15202 }
15203 }
15204 }
15205 }
15206
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015207 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15208 if (proc == null || proc == mProfileProc) {
15209 proc = mProfileProc;
15210 path = mProfileFile;
15211 profileType = mProfileType;
15212 clearProfilerLocked();
15213 }
15214 if (proc == null) {
15215 return;
15216 }
15217 try {
15218 proc.thread.profilerControl(false, path, null, profileType);
15219 } catch (RemoteException e) {
15220 throw new IllegalStateException("Process disappeared");
15221 }
15222 }
15223
15224 private void clearProfilerLocked() {
15225 if (mProfileFd != null) {
15226 try {
15227 mProfileFd.close();
15228 } catch (IOException e) {
15229 }
15230 }
15231 mProfileApp = null;
15232 mProfileProc = null;
15233 mProfileFile = null;
15234 mProfileType = 0;
15235 mAutoStopProfiler = false;
15236 }
15237
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015238 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070015239 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015240
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015241 try {
15242 synchronized (this) {
15243 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15244 // its own permission.
15245 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15246 != PackageManager.PERMISSION_GRANTED) {
15247 throw new SecurityException("Requires permission "
15248 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015249 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015250
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015251 if (start && fd == null) {
15252 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015253 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015254
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015255 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015256 if (process != null) {
15257 try {
15258 int pid = Integer.parseInt(process);
15259 synchronized (mPidsSelfLocked) {
15260 proc = mPidsSelfLocked.get(pid);
15261 }
15262 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015263 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015264
15265 if (proc == null) {
15266 HashMap<String, SparseArray<ProcessRecord>> all
15267 = mProcessNames.getMap();
15268 SparseArray<ProcessRecord> procs = all.get(process);
15269 if (procs != null && procs.size() > 0) {
15270 proc = procs.valueAt(0);
15271 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015272 }
15273 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015274
15275 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015276 throw new IllegalArgumentException("Unknown process: " + process);
15277 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015278
15279 if (start) {
15280 stopProfilerLocked(null, null, 0);
15281 setProfileApp(proc.info, proc.processName, path, fd, false);
15282 mProfileProc = proc;
15283 mProfileType = profileType;
15284 try {
15285 fd = fd.dup();
15286 } catch (IOException e) {
15287 fd = null;
15288 }
15289 proc.thread.profilerControl(start, path, fd, profileType);
15290 fd = null;
15291 mProfileFd = null;
15292 } else {
15293 stopProfilerLocked(proc, path, profileType);
15294 if (fd != null) {
15295 try {
15296 fd.close();
15297 } catch (IOException e) {
15298 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015299 }
15300 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015301
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015302 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015303 }
15304 } catch (RemoteException e) {
15305 throw new IllegalStateException("Process disappeared");
15306 } finally {
15307 if (fd != null) {
15308 try {
15309 fd.close();
15310 } catch (IOException e) {
15311 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015312 }
15313 }
15314 }
Andy McFadden824c5102010-07-09 16:26:57 -070015315
15316 public boolean dumpHeap(String process, boolean managed,
15317 String path, ParcelFileDescriptor fd) throws RemoteException {
15318
15319 try {
15320 synchronized (this) {
15321 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15322 // its own permission (same as profileControl).
15323 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15324 != PackageManager.PERMISSION_GRANTED) {
15325 throw new SecurityException("Requires permission "
15326 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15327 }
15328
15329 if (fd == null) {
15330 throw new IllegalArgumentException("null fd");
15331 }
15332
15333 ProcessRecord proc = null;
15334 try {
15335 int pid = Integer.parseInt(process);
15336 synchronized (mPidsSelfLocked) {
15337 proc = mPidsSelfLocked.get(pid);
15338 }
15339 } catch (NumberFormatException e) {
15340 }
15341
15342 if (proc == null) {
15343 HashMap<String, SparseArray<ProcessRecord>> all
15344 = mProcessNames.getMap();
15345 SparseArray<ProcessRecord> procs = all.get(process);
15346 if (procs != null && procs.size() > 0) {
15347 proc = procs.valueAt(0);
15348 }
15349 }
15350
15351 if (proc == null || proc.thread == null) {
15352 throw new IllegalArgumentException("Unknown process: " + process);
15353 }
15354
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080015355 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15356 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070015357 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15358 throw new SecurityException("Process not debuggable: " + proc);
15359 }
15360 }
15361
15362 proc.thread.dumpHeap(managed, path, fd);
15363 fd = null;
15364 return true;
15365 }
15366 } catch (RemoteException e) {
15367 throw new IllegalStateException("Process disappeared");
15368 } finally {
15369 if (fd != null) {
15370 try {
15371 fd.close();
15372 } catch (IOException e) {
15373 }
15374 }
15375 }
15376 }
15377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015378 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15379 public void monitor() {
15380 synchronized (this) { }
15381 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015382
Dianne Hackborna573f6a2012-02-09 16:12:18 -080015383 void onCoreSettingsChange(Bundle settings) {
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015384 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15385 ProcessRecord processRecord = mLruProcesses.get(i);
15386 try {
15387 if (processRecord.thread != null) {
15388 processRecord.thread.setCoreSettings(settings);
15389 }
15390 } catch (RemoteException re) {
15391 /* ignore */
15392 }
15393 }
15394 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015395
15396 // Multi-user methods
15397
Amith Yamasani742a6712011-05-04 14:49:28 -070015398 private int mCurrentUserId;
15399 private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15400
15401 public boolean switchUser(int userId) {
15402 final int callingUid = Binder.getCallingUid();
15403 if (callingUid != 0 && callingUid != Process.myUid()) {
15404 Slog.e(TAG, "Trying to switch user from unauthorized app");
15405 return false;
15406 }
15407 if (mCurrentUserId == userId)
15408 return true;
15409
15410 synchronized (this) {
15411 // Check if user is already logged in, otherwise check if user exists first before
15412 // adding to the list of logged in users.
15413 if (mLoggedInUsers.indexOfKey(userId) < 0) {
15414 if (!userExists(userId)) {
15415 return false;
15416 }
15417 mLoggedInUsers.append(userId, userId);
15418 }
15419
15420 mCurrentUserId = userId;
15421 boolean haveActivities = mMainStack.switchUser(userId);
15422 if (!haveActivities) {
15423 startHomeActivityLocked(userId);
15424 }
15425 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015426 return true;
15427 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015428
15429 private boolean userExists(int userId) {
15430 try {
15431 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
15432 for (UserInfo user : users) {
15433 if (user.id == userId) {
15434 return true;
15435 }
15436 }
15437 } catch (RemoteException re) {
15438 // Won't happen, in same process
15439 }
15440
15441 return false;
15442 }
15443
15444
15445 private int applyUserId(int uid, int userId) {
15446 return UserId.getUid(userId, uid);
15447 }
15448
15449 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015450 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070015451 ApplicationInfo newInfo = new ApplicationInfo(info);
15452 newInfo.uid = applyUserId(info.uid, userId);
15453 if (newInfo.uid >= Process.FIRST_APPLICATION_UID) {
15454 newInfo.dataDir = USER_DATA_DIR + userId + "/"
15455 + info.packageName;
15456 }
15457 return newInfo;
15458 }
15459
15460 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015461 if (aInfo == null || aInfo.applicationInfo.uid < Process.FIRST_APPLICATION_UID
Amith Yamasani742a6712011-05-04 14:49:28 -070015462 || userId < 1) {
15463 return aInfo;
15464 }
15465
15466 ActivityInfo info = new ActivityInfo(aInfo);
15467 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15468 return info;
15469 }
15470
15471 static class ServiceMap {
15472
15473 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15474 = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15475 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15476 mServicesByIntentPerUser = new SparseArray<
15477 HashMap<Intent.FilterComparison, ServiceRecord>>();
15478
15479 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15480 // TODO: Deal with global services
15481 if (DEBUG_MU)
15482 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15483 return getServices(callingUser).get(name);
15484 }
15485
15486 ServiceRecord getServiceByName(ComponentName name) {
15487 return getServiceByName(name, -1);
15488 }
15489
15490 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15491 // TODO: Deal with global services
15492 if (DEBUG_MU)
15493 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15494 return getServicesByIntent(callingUser).get(filter);
15495 }
15496
15497 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15498 return getServiceByIntent(filter, -1);
15499 }
15500
15501 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15502 // TODO: Deal with global services
15503 getServices(callingUser).put(name, value);
15504 }
15505
15506 void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15507 ServiceRecord value) {
15508 // TODO: Deal with global services
15509 getServicesByIntent(callingUser).put(filter, value);
15510 }
15511
15512 void removeServiceByName(ComponentName name, int callingUser) {
15513 // TODO: Deal with global services
15514 ServiceRecord removed = getServices(callingUser).remove(name);
15515 if (DEBUG_MU)
15516 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15517 + " removed=" + removed);
15518 }
15519
15520 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15521 // TODO: Deal with global services
15522 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15523 if (DEBUG_MU)
15524 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15525 + " removed=" + removed);
15526 }
15527
15528 Collection<ServiceRecord> getAllServices(int callingUser) {
15529 // TODO: Deal with global services
15530 return getServices(callingUser).values();
15531 }
15532
15533 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15534 HashMap map = mServicesByNamePerUser.get(callingUser);
15535 if (map == null) {
15536 map = new HashMap<ComponentName, ServiceRecord>();
15537 mServicesByNamePerUser.put(callingUser, map);
15538 }
15539 return map;
15540 }
15541
15542 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15543 int callingUser) {
15544 HashMap map = mServicesByIntentPerUser.get(callingUser);
15545 if (map == null) {
15546 map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15547 mServicesByIntentPerUser.put(callingUser, map);
15548 }
15549 return map;
15550 }
15551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015552}