blob: 0d1d6209c8afa19e8d29bf3d90dd3884b56dc715 [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) {
Mike Lockwooda8f767a2011-08-31 14:32:37 -04002873 if (mHeadless) {
2874 // Added because none of the other calls to ensureBootCompleted seem to fire
2875 // when running headless.
2876 ensureBootCompleted();
2877 return false;
2878 }
2879
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002880 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2881 && mTopAction == null) {
2882 // We are running in factory test mode, but unable to find
2883 // the factory test app, so just sit around displaying the
2884 // error message and don't try to start anything.
2885 return false;
2886 }
2887 Intent intent = new Intent(
2888 mTopAction,
2889 mTopData != null ? Uri.parse(mTopData) : null);
2890 intent.setComponent(mTopComponent);
2891 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2892 intent.addCategory(Intent.CATEGORY_HOME);
2893 }
2894 ActivityInfo aInfo =
2895 intent.resolveActivityInfo(mContext.getPackageManager(),
2896 STOCK_PM_FLAGS);
2897 if (aInfo != null) {
2898 intent.setComponent(new ComponentName(
2899 aInfo.applicationInfo.packageName, aInfo.name));
2900 // Don't do this if the home app is currently being
2901 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002902 aInfo = new ActivityInfo(aInfo);
2903 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002904 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2905 aInfo.applicationInfo.uid);
2906 if (app == null || app.instrumentationClass == null) {
2907 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002908 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002909 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002910 }
2911 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002912
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002913 return true;
2914 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002915
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002916 /**
2917 * Starts the "new version setup screen" if appropriate.
2918 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002919 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002920 // Only do this once per boot.
2921 if (mCheckedForSetup) {
2922 return;
2923 }
2924
2925 // We will show this screen if the current one is a different
2926 // version than the last one shown, and we are not running in
2927 // low-level factory test mode.
2928 final ContentResolver resolver = mContext.getContentResolver();
2929 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2930 Settings.Secure.getInt(resolver,
2931 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2932 mCheckedForSetup = true;
2933
2934 // See if we should be showing the platform update setup UI.
2935 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2936 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2937 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2938
2939 // We don't allow third party apps to replace this.
2940 ResolveInfo ri = null;
2941 for (int i=0; ris != null && i<ris.size(); i++) {
2942 if ((ris.get(i).activityInfo.applicationInfo.flags
2943 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2944 ri = ris.get(i);
2945 break;
2946 }
2947 }
2948
2949 if (ri != null) {
2950 String vers = ri.activityInfo.metaData != null
2951 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2952 : null;
2953 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2954 vers = ri.activityInfo.applicationInfo.metaData.getString(
2955 Intent.METADATA_SETUP_VERSION);
2956 }
2957 String lastVers = Settings.Secure.getString(
2958 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2959 if (vers != null && !vers.equals(lastVers)) {
2960 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2961 intent.setComponent(new ComponentName(
2962 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002963 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002964 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002965 }
2966 }
2967 }
2968 }
2969
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002970 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002971 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002972 }
2973
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002974 void enforceNotIsolatedCaller(String caller) {
2975 if (UserId.isIsolated(Binder.getCallingUid())) {
2976 throw new SecurityException("Isolated process not allowed to call " + caller);
2977 }
2978 }
2979
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002980 public int getFrontActivityScreenCompatMode() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002981 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002982 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002983 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2984 }
2985 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002986
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002987 public void setFrontActivityScreenCompatMode(int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2989 "setFrontActivityScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002990 synchronized (this) {
2991 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2992 }
2993 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002994
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002995 public int getPackageScreenCompatMode(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002996 enforceNotIsolatedCaller("getPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002997 synchronized (this) {
2998 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2999 }
3000 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003001
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07003002 public void setPackageScreenCompatMode(String packageName, int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003003 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3004 "setPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07003005 synchronized (this) {
3006 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003007 }
3008 }
3009
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003010 public boolean getPackageAskScreenCompat(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003011 enforceNotIsolatedCaller("getPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003012 synchronized (this) {
3013 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3014 }
3015 }
3016
3017 public void setPackageAskScreenCompat(String packageName, boolean ask) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003018 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3019 "setPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07003020 synchronized (this) {
3021 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3022 }
3023 }
3024
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003025 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003026 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003027
3028 final int identHash = System.identityHashCode(r);
3029 updateUsageStats(r, true);
3030
3031 int i = mWatchers.beginBroadcast();
3032 while (i > 0) {
3033 i--;
3034 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3035 if (w != null) {
3036 try {
3037 w.activityResuming(identHash);
3038 } catch (RemoteException e) {
3039 }
3040 }
3041 }
3042 mWatchers.finishBroadcast();
3043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003044
Jeff Sharkeya4620792011-05-20 15:29:23 -07003045 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
3046 int i = mProcessObservers.beginBroadcast();
3047 while (i > 0) {
3048 i--;
3049 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3050 if (observer != null) {
3051 try {
3052 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
3053 } catch (RemoteException e) {
3054 }
3055 }
3056 }
3057 mProcessObservers.finishBroadcast();
3058 }
3059
3060 private void dispatchProcessDied(int pid, int uid) {
3061 int i = mProcessObservers.beginBroadcast();
3062 while (i > 0) {
3063 i--;
3064 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3065 if (observer != null) {
3066 try {
3067 observer.onProcessDied(pid, uid);
3068 } catch (RemoteException e) {
3069 }
3070 }
3071 }
3072 mProcessObservers.finishBroadcast();
3073 }
3074
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003075 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003076 final int N = mPendingActivityLaunches.size();
3077 if (N <= 0) {
3078 return;
3079 }
3080 for (int i=0; i<N; i++) {
3081 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003082 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003083 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3084 doResume && i == (N-1));
3085 }
3086 mPendingActivityLaunches.clear();
3087 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003088
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003089 public final int startActivity(IApplicationThread caller,
3090 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3091 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003092 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3093 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003094 enforceNotIsolatedCaller("startActivity");
Amith Yamasani742a6712011-05-04 14:49:28 -07003095 int userId = 0;
3096 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
3097 // Requesting home, set the identity to the current user
3098 // HACK!
3099 userId = mCurrentUserId;
3100 } else {
3101 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
3102 // the current user's userId
3103 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
3104 userId = 0;
3105 } else {
3106 userId = Binder.getOrigCallingUser();
3107 }
3108 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003109 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -07003110 grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded,
3111 debug, profileFile, profileFd, autoStopProfiler, null, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003112 }
3113
3114 public final WaitResult startActivityAndWait(IApplicationThread caller,
3115 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3116 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003117 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3118 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003119 enforceNotIsolatedCaller("startActivityAndWait");
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003120 WaitResult res = new WaitResult();
Amith Yamasani742a6712011-05-04 14:49:28 -07003121 int userId = Binder.getOrigCallingUser();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003122 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003123 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003124 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
Amith Yamasani742a6712011-05-04 14:49:28 -07003125 res, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003126 return res;
3127 }
3128
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003129 public final int startActivityWithConfig(IApplicationThread caller,
3130 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3131 int grantedMode, IBinder resultTo,
3132 String resultWho, int requestCode, boolean onlyIfNeeded,
3133 boolean debug, Configuration config) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003134 enforceNotIsolatedCaller("startActivityWithConfig");
Amith Yamasani742a6712011-05-04 14:49:28 -07003135 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003136 grantedUriPermissions, grantedMode, resultTo, resultWho,
Amith Yamasani742a6712011-05-04 14:49:28 -07003137 requestCode, onlyIfNeeded,
3138 debug, null, null, false, null, config, Binder.getOrigCallingUser());
3139 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003140 }
3141
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003142 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003143 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003144 IBinder resultTo, String resultWho, int requestCode,
3145 int flagsMask, int flagsValues) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003146 enforceNotIsolatedCaller("startActivityIntentSender");
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003147 // Refuse possible leaked file descriptors
3148 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3149 throw new IllegalArgumentException("File descriptors passed in Intent");
3150 }
3151
3152 IIntentSender sender = intent.getTarget();
3153 if (!(sender instanceof PendingIntentRecord)) {
3154 throw new IllegalArgumentException("Bad PendingIntent object");
3155 }
3156
3157 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003158
3159 synchronized (this) {
3160 // If this is coming from the currently resumed activity, it is
3161 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003162 if (mMainStack.mResumedActivity != null
3163 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003164 Binder.getCallingUid()) {
3165 mAppSwitchesAllowedTime = 0;
3166 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003167 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003168 int ret = pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003169 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
Amith Yamasani742a6712011-05-04 14:49:28 -07003170 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003171 }
3172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 public boolean startNextMatchingActivity(IBinder callingActivity,
3174 Intent intent) {
3175 // Refuse possible leaked file descriptors
3176 if (intent != null && intent.hasFileDescriptors() == true) {
3177 throw new IllegalArgumentException("File descriptors passed in Intent");
3178 }
3179
3180 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003181 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
3182 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183 return false;
3184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003185 if (r.app == null || r.app.thread == null) {
3186 // The caller is not running... d'oh!
3187 return false;
3188 }
3189 intent = new Intent(intent);
3190 // The caller is not allowed to change the data.
3191 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3192 // And we are resetting to find the next component...
3193 intent.setComponent(null);
3194
3195 ActivityInfo aInfo = null;
3196 try {
3197 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003198 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003199 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07003200 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003201
3202 // Look for the original activity in the list...
3203 final int N = resolves != null ? resolves.size() : 0;
3204 for (int i=0; i<N; i++) {
3205 ResolveInfo rInfo = resolves.get(i);
3206 if (rInfo.activityInfo.packageName.equals(r.packageName)
3207 && rInfo.activityInfo.name.equals(r.info.name)) {
3208 // We found the current one... the next matching is
3209 // after it.
3210 i++;
3211 if (i<N) {
3212 aInfo = resolves.get(i).activityInfo;
3213 }
3214 break;
3215 }
3216 }
3217 } catch (RemoteException e) {
3218 }
3219
3220 if (aInfo == null) {
3221 // Nobody who is next!
3222 return false;
3223 }
3224
3225 intent.setComponent(new ComponentName(
3226 aInfo.applicationInfo.packageName, aInfo.name));
3227 intent.setFlags(intent.getFlags()&~(
3228 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3229 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3230 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3231 Intent.FLAG_ACTIVITY_NEW_TASK));
3232
3233 // Okay now we need to start the new activity, replacing the
3234 // currently running activity. This is a little tricky because
3235 // we want to start the new one as if the current one is finished,
3236 // but not finish the current one first so that there is no flicker.
3237 // And thus...
3238 final boolean wasFinishing = r.finishing;
3239 r.finishing = true;
3240
3241 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003242 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003243 final String resultWho = r.resultWho;
3244 final int requestCode = r.requestCode;
3245 r.resultTo = null;
3246 if (resultTo != null) {
3247 resultTo.removeResultsLocked(r, resultWho, requestCode);
3248 }
3249
3250 final long origId = Binder.clearCallingIdentity();
3251 // XXX we are not dealing with propagating grantedUriPermissions...
3252 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003253 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003254 r.resolvedType, null, 0, aInfo,
3255 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003256 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003257 Binder.restoreCallingIdentity(origId);
3258
3259 r.finishing = wasFinishing;
3260 if (res != START_SUCCESS) {
3261 return false;
3262 }
3263 return true;
3264 }
3265 }
3266
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003267 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 Intent intent, String resolvedType, IBinder resultTo,
3269 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003270
3271 // This is so super not safe, that only the system (or okay root)
3272 // can do it.
Amith Yamasani742a6712011-05-04 14:49:28 -07003273 int userId = Binder.getOrigCallingUser();
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003274 final int callingUid = Binder.getCallingUid();
3275 if (callingUid != 0 && callingUid != Process.myUid()) {
3276 throw new SecurityException(
3277 "startActivityInPackage only available to the system");
3278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279
Amith Yamasani742a6712011-05-04 14:49:28 -07003280 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003281 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
Amith Yamasani742a6712011-05-04 14:49:28 -07003282 null, null, false, null, null, userId);
3283 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003284 }
3285
3286 public final int startActivities(IApplicationThread caller,
3287 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003288 enforceNotIsolatedCaller("startActivities");
Amith Yamasani742a6712011-05-04 14:49:28 -07003289 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
3290 Binder.getOrigCallingUser());
3291 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003292 }
3293
3294 public final int startActivitiesInPackage(int uid,
3295 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
3296
3297 // This is so super not safe, that only the system (or okay root)
3298 // can do it.
3299 final int callingUid = Binder.getCallingUid();
3300 if (callingUid != 0 && callingUid != Process.myUid()) {
3301 throw new SecurityException(
3302 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003304 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
3305 UserId.getUserId(uid));
3306 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 }
3308
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003309 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08003311 // Quick case: check if the top-most recent task is the same.
3312 if (N > 0 && mRecentTasks.get(0) == task) {
3313 return;
3314 }
3315 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 for (int i=0; i<N; i++) {
3317 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07003318 if (task.userId == tr.userId
3319 && ((task.affinity != null && task.affinity.equals(tr.affinity))
3320 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 mRecentTasks.remove(i);
3322 i--;
3323 N--;
3324 if (task.intent == null) {
3325 // If the new recent task we are adding is not fully
3326 // specified, then replace it with the existing recent task.
3327 task = tr;
3328 }
3329 }
3330 }
3331 if (N >= MAX_RECENT_TASKS) {
3332 mRecentTasks.remove(N-1);
3333 }
3334 mRecentTasks.add(0, task);
3335 }
3336
3337 public void setRequestedOrientation(IBinder token,
3338 int requestedOrientation) {
3339 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003340 ActivityRecord r = mMainStack.isInStackLocked(token);
3341 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003342 return;
3343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003345 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003347 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003348 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 if (config != null) {
3350 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08003351 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003352 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 }
3354 }
3355 Binder.restoreCallingIdentity(origId);
3356 }
3357 }
3358
3359 public int getRequestedOrientation(IBinder token) {
3360 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003361 ActivityRecord r = mMainStack.isInStackLocked(token);
3362 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003363 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3364 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08003365 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 }
3367 }
3368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 /**
3370 * This is the internal entry point for handling Activity.finish().
3371 *
3372 * @param token The Binder token referencing the Activity we want to finish.
3373 * @param resultCode Result code, if any, from this Activity.
3374 * @param resultData Result data (Intent), if any, from this Activity.
3375 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11003376 * @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 -08003377 */
3378 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3379 // Refuse possible leaked file descriptors
3380 if (resultData != null && resultData.hasFileDescriptors() == true) {
3381 throw new IllegalArgumentException("File descriptors passed in Intent");
3382 }
3383
3384 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003385 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003387 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 if (next != null) {
3389 // ask watcher if this is allowed
3390 boolean resumeOK = true;
3391 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003392 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003394 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003395 }
3396
3397 if (!resumeOK) {
3398 return false;
3399 }
3400 }
3401 }
3402 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003403 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 resultData, "app-request");
3405 Binder.restoreCallingIdentity(origId);
3406 return res;
3407 }
3408 }
3409
Dianne Hackborn860755f2010-06-03 18:47:52 -07003410 public final void finishHeavyWeightApp() {
3411 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3412 != PackageManager.PERMISSION_GRANTED) {
3413 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3414 + Binder.getCallingPid()
3415 + ", uid=" + Binder.getCallingUid()
3416 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3417 Slog.w(TAG, msg);
3418 throw new SecurityException(msg);
3419 }
3420
3421 synchronized(this) {
3422 if (mHeavyWeightProcess == null) {
3423 return;
3424 }
3425
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003426 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07003427 mHeavyWeightProcess.activities);
3428 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003429 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003430 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003431 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003432 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003433 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07003434 null, "finish-heavy");
3435 }
3436 }
3437 }
3438
3439 mHeavyWeightProcess = null;
3440 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3441 }
3442 }
3443
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003444 public void crashApplication(int uid, int initialPid, String packageName,
3445 String message) {
3446 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3447 != PackageManager.PERMISSION_GRANTED) {
3448 String msg = "Permission Denial: crashApplication() from pid="
3449 + Binder.getCallingPid()
3450 + ", uid=" + Binder.getCallingUid()
3451 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3452 Slog.w(TAG, msg);
3453 throw new SecurityException(msg);
3454 }
3455
3456 synchronized(this) {
3457 ProcessRecord proc = null;
3458
3459 // Figure out which process to kill. We don't trust that initialPid
3460 // still has any relation to current pids, so must scan through the
3461 // list.
3462 synchronized (mPidsSelfLocked) {
3463 for (int i=0; i<mPidsSelfLocked.size(); i++) {
3464 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003465 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003466 continue;
3467 }
3468 if (p.pid == initialPid) {
3469 proc = p;
3470 break;
3471 }
3472 for (String str : p.pkgList) {
3473 if (str.equals(packageName)) {
3474 proc = p;
3475 }
3476 }
3477 }
3478 }
3479
3480 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07003481 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003482 + " initialPid=" + initialPid
3483 + " packageName=" + packageName);
3484 return;
3485 }
3486
3487 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07003488 if (proc.pid == Process.myPid()) {
3489 Log.w(TAG, "crashApplication: trying to crash self!");
3490 return;
3491 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003492 long ident = Binder.clearCallingIdentity();
3493 try {
3494 proc.thread.scheduleCrash(message);
3495 } catch (RemoteException e) {
3496 }
3497 Binder.restoreCallingIdentity(ident);
3498 }
3499 }
3500 }
3501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003502 public final void finishSubActivity(IBinder token, String resultWho,
3503 int requestCode) {
3504 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003505 ActivityRecord self = mMainStack.isInStackLocked(token);
3506 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 return;
3508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509
3510 final long origId = Binder.clearCallingIdentity();
3511
3512 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003513 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3514 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003515 if (r.resultTo == self && r.requestCode == requestCode) {
3516 if ((r.resultWho == null && resultWho == null) ||
3517 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003518 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 Activity.RESULT_CANCELED, null, "request-sub");
3520 }
3521 }
3522 }
3523
3524 Binder.restoreCallingIdentity(origId);
3525 }
3526 }
3527
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003528 public boolean willActivityBeVisible(IBinder token) {
3529 synchronized(this) {
3530 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003531 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3532 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08003533 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003534 return true;
3535 }
3536 if (r.fullscreen && !r.finishing) {
3537 return false;
3538 }
3539 }
3540 return true;
3541 }
3542 }
3543
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003544 public void overridePendingTransition(IBinder token, String packageName,
3545 int enterAnim, int exitAnim) {
3546 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003547 ActivityRecord self = mMainStack.isInStackLocked(token);
3548 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003549 return;
3550 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003551
3552 final long origId = Binder.clearCallingIdentity();
3553
3554 if (self.state == ActivityState.RESUMED
3555 || self.state == ActivityState.PAUSING) {
3556 mWindowManager.overridePendingAppTransition(packageName,
3557 enterAnim, exitAnim);
3558 }
3559
3560 Binder.restoreCallingIdentity(origId);
3561 }
3562 }
3563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003564 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 * Main function for removing an existing process from the activity manager
3566 * as a result of that process going away. Clears out all connections
3567 * to the process.
3568 */
3569 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003570 boolean restarting, boolean allowRestart) {
3571 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003573 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003574 }
3575
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003576 if (mProfileProc == app) {
3577 clearProfilerLocked();
3578 }
3579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 // Just in case...
Dianne Hackborncbb722e2012-02-07 18:33:49 -08003581 mMainStack.appDiedLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003582
3583 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003584 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585
3586 boolean atTop = true;
3587 boolean hasVisibleActivities = false;
3588
3589 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003590 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003591 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003592 TAG, "Removing app " + app + " from history with " + i + " entries");
3593 while (i > 0) {
3594 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003595 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003596 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3598 if (r.app == app) {
3599 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003600 if (ActivityStack.DEBUG_ADD_REMOVE) {
3601 RuntimeException here = new RuntimeException("here");
3602 here.fillInStackTrace();
3603 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
3604 + ": haveState=" + r.haveState
3605 + " stateNotNeeded=" + r.stateNotNeeded
3606 + " finishing=" + r.finishing
3607 + " state=" + r.state, here);
3608 }
3609 if (!r.finishing) {
3610 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08003611 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3612 System.identityHashCode(r),
3613 r.task.taskId, r.shortComponentName,
3614 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003615 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003616 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003617 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003618 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003619 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003621 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003623 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624
3625 } else {
3626 // We have the current state for this activity, so
3627 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003628 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 TAG, "Keeping entry, setting app to null");
3630 if (r.visible) {
3631 hasVisibleActivities = true;
3632 }
3633 r.app = null;
3634 r.nowVisible = false;
3635 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003636 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
3637 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 r.icicle = null;
3639 }
3640 }
3641
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003642 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 }
3644 atTop = false;
3645 }
3646
3647 app.activities.clear();
3648
3649 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003650 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003651 + " running instrumentation " + app.instrumentationClass);
3652 Bundle info = new Bundle();
3653 info.putString("shortMsg", "Process crashed.");
3654 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3655 }
3656
3657 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003658 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 // If there was nothing to resume, and we are not already
3660 // restarting this process, but there is a visible activity that
3661 // is hosted by the process... then make sure all visible
3662 // activities are running, taking care of restarting this
3663 // process.
3664 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003665 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 }
3667 }
3668 }
3669 }
3670
3671 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3672 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003674 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3675 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3677 return i;
3678 }
3679 }
3680 return -1;
3681 }
3682
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003683 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 IApplicationThread thread) {
3685 if (thread == null) {
3686 return null;
3687 }
3688
3689 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003690 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003691 }
3692
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003693 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 IApplicationThread thread) {
3695
3696 mProcDeaths[0]++;
3697
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003698 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3699 synchronized (stats) {
3700 stats.noteProcessDiedLocked(app.info.uid, pid);
3701 }
3702
Magnus Edlund7bb25812010-02-24 15:45:06 +01003703 // Clean up already done if the process has been re-started.
3704 if (app.pid == pid && app.thread != null &&
3705 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07003706 if (!app.killedBackground) {
3707 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3708 + ") has died.");
3709 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08003710 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003711 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 TAG, "Dying app: " + app + ", pid: " + pid
3713 + ", thread: " + thread.asBinder());
3714 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003715 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716
3717 if (doLowMem) {
3718 // If there are no longer any background processes running,
3719 // and the app that died was not running instrumentation,
3720 // then tell everyone we are now low on memory.
3721 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003722 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3723 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07003724 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 haveBg = true;
3726 break;
3727 }
3728 }
3729
3730 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003731 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003732 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003733 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3734 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07003735 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003736 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3737 // The low memory report is overriding any current
3738 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003739 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07003740 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003741 rec.lastRequestedGc = 0;
3742 } else {
3743 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003745 rec.reportLowMemory = true;
3746 rec.lastLowMemory = now;
3747 mProcessesToGc.remove(rec);
3748 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 }
3750 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003751 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003752 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 }
3754 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003755 } else if (app.pid != pid) {
3756 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003757 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003758 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08003759 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003760 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003761 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 + thread.asBinder());
3763 }
3764 }
3765
Dan Egnor42471dd2010-01-07 17:25:22 -08003766 /**
3767 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003768 * @param clearTraces causes the dump file to be erased prior to the new
3769 * traces being written, if true; when false, the new traces will be
3770 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003771 * @param firstPids of dalvik VM processes to dump stack traces for first
3772 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08003773 * @return file containing stack traces, or null if no dump file is configured
3774 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003775 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3776 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003777 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3778 if (tracesPath == null || tracesPath.length() == 0) {
3779 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003781
3782 File tracesFile = new File(tracesPath);
3783 try {
3784 File tracesDir = tracesFile.getParentFile();
3785 if (!tracesDir.exists()) tracesFile.mkdirs();
3786 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3787
Christopher Tate6ee412d2010-05-28 12:01:56 -07003788 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003789 tracesFile.createNewFile();
3790 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3791 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003792 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003793 return null;
3794 }
3795
3796 // Use a FileObserver to detect when traces finish writing.
3797 // The order of traces is considered important to maintain for legibility.
3798 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3799 public synchronized void onEvent(int event, String path) { notify(); }
3800 };
3801
3802 try {
3803 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003804
3805 // First collect all of the stacks of the most important pids.
3806 try {
3807 int num = firstPids.size();
3808 for (int i = 0; i < num; i++) {
3809 synchronized (observer) {
3810 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3811 observer.wait(200); // Wait for write-close, give up after 200msec
3812 }
3813 }
3814 } catch (InterruptedException e) {
3815 Log.wtf(TAG, e);
3816 }
3817
3818 // Next measure CPU usage.
3819 if (processStats != null) {
3820 processStats.init();
3821 System.gc();
3822 processStats.update();
3823 try {
3824 synchronized (processStats) {
3825 processStats.wait(500); // measure over 1/2 second.
3826 }
3827 } catch (InterruptedException e) {
3828 }
3829 processStats.update();
3830
3831 // We'll take the stack crawls of just the top apps using CPU.
3832 final int N = processStats.countWorkingStats();
3833 int numProcs = 0;
3834 for (int i=0; i<N && numProcs<5; i++) {
3835 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3836 if (lastPids.indexOfKey(stats.pid) >= 0) {
3837 numProcs++;
3838 try {
3839 synchronized (observer) {
3840 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3841 observer.wait(200); // Wait for write-close, give up after 200msec
3842 }
3843 } catch (InterruptedException e) {
3844 Log.wtf(TAG, e);
3845 }
3846
3847 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003848 }
3849 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003850
3851 return tracesFile;
3852
Dan Egnor42471dd2010-01-07 17:25:22 -08003853 } finally {
3854 observer.stopWatching();
3855 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003856 }
3857
Jeff Brown4d94a762010-09-23 11:33:28 -07003858 private final class AppNotResponding implements Runnable {
3859 private final ProcessRecord mApp;
3860 private final String mAnnotation;
3861
3862 public AppNotResponding(ProcessRecord app, String annotation) {
3863 mApp = app;
3864 mAnnotation = annotation;
3865 }
3866
3867 @Override
3868 public void run() {
3869 appNotResponding(mApp, null, null, mAnnotation);
3870 }
3871 }
3872
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003873 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3874 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003875 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3876 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3877
Dianne Hackborn287952c2010-09-22 22:34:31 -07003878 if (mController != null) {
3879 try {
3880 // 0 == continue, -1 = kill process immediately
3881 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3882 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3883 } catch (RemoteException e) {
3884 mController = null;
3885 }
3886 }
3887
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003888 long anrTime = SystemClock.uptimeMillis();
3889 if (MONITOR_CPU_USAGE) {
3890 updateCpuStatsNow();
3891 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003892
3893 synchronized (this) {
3894 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3895 if (mShuttingDown) {
3896 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3897 return;
3898 } else if (app.notResponding) {
3899 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3900 return;
3901 } else if (app.crashing) {
3902 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3903 return;
3904 }
3905
3906 // In case we come through here for the same app before completing
3907 // this one, mark as anring now so we will bail out.
3908 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003909
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003910 // Log the ANR to the event log.
3911 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3912 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003913
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003914 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003915 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003916
3917 int parentPid = app.pid;
3918 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003919 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003920
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003921 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003922
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003923 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3924 ProcessRecord r = mLruProcesses.get(i);
3925 if (r != null && r.thread != null) {
3926 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003927 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3928 if (r.persistent) {
3929 firstPids.add(pid);
3930 } else {
3931 lastPids.put(pid, Boolean.TRUE);
3932 }
3933 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 }
3936 }
3937
Dan Egnor42471dd2010-01-07 17:25:22 -08003938 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003939 StringBuilder info = mStringBuilder;
3940 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003941 info.append("ANR in ").append(app.processName);
3942 if (activity != null && activity.shortComponentName != null) {
3943 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003944 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003945 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003947 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003949 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003950 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952
Dianne Hackborn287952c2010-09-22 22:34:31 -07003953 final ProcessStats processStats = new ProcessStats(true);
3954
3955 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3956
Dan Egnor42471dd2010-01-07 17:25:22 -08003957 String cpuInfo = null;
3958 if (MONITOR_CPU_USAGE) {
3959 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003960 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003961 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003962 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003963 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003964 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 }
3966
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003967 info.append(processStats.printCurrentState(anrTime));
3968
Joe Onorato8a9b2202010-02-26 18:56:32 -08003969 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003970 if (tracesFile == null) {
3971 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3972 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3973 }
3974
Jeff Sharkeya353d262011-10-28 11:12:06 -07003975 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3976 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003977
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003978 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003980 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3981 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003983 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3984 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 }
3986 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003987 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 }
3989 }
3990
Dan Egnor42471dd2010-01-07 17:25:22 -08003991 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3992 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3993 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003994
3995 synchronized (this) {
3996 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003997 Slog.w(TAG, "Killing " + app + ": background ANR");
3998 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3999 app.processName, app.setAdj, "background ANR");
4000 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07004001 return;
4002 }
4003
4004 // Set the app's notResponding state, and look up the errorReportReceiver
4005 makeAppNotRespondingLocked(app,
4006 activity != null ? activity.shortComponentName : null,
4007 annotation != null ? "ANR " + annotation : "ANR",
4008 info.toString());
4009
4010 // Bring up the infamous App Not Responding dialog
4011 Message msg = Message.obtain();
4012 HashMap map = new HashMap();
4013 msg.what = SHOW_NOT_RESPONDING_MSG;
4014 msg.obj = map;
4015 map.put("app", app);
4016 if (activity != null) {
4017 map.put("activity", activity);
4018 }
4019
4020 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08004021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 }
4023
Dianne Hackborn0dad3642010-09-09 21:25:35 -07004024 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4025 if (!mLaunchWarningShown) {
4026 mLaunchWarningShown = true;
4027 mHandler.post(new Runnable() {
4028 @Override
4029 public void run() {
4030 synchronized (ActivityManagerService.this) {
4031 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4032 d.show();
4033 mHandler.postDelayed(new Runnable() {
4034 @Override
4035 public void run() {
4036 synchronized (ActivityManagerService.this) {
4037 d.dismiss();
4038 mLaunchWarningShown = false;
4039 }
4040 }
4041 }, 4000);
4042 }
4043 }
4044 });
4045 }
4046 }
4047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 public boolean clearApplicationUserData(final String packageName,
Amith Yamasani742a6712011-05-04 14:49:28 -07004049 final IPackageDataObserver observer, final int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004050 enforceNotIsolatedCaller("clearApplicationUserData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004051 int uid = Binder.getCallingUid();
4052 int pid = Binder.getCallingPid();
4053 long callingId = Binder.clearCallingIdentity();
4054 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004055 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004056 int pkgUid = -1;
4057 synchronized(this) {
4058 try {
4059 pkgUid = pm.getPackageUid(packageName);
4060 } catch (RemoteException e) {
4061 }
4062 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004063 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 return false;
4065 }
4066 if (uid == pkgUid || checkComponentPermission(
4067 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004068 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004069 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004070 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 } else {
4072 throw new SecurityException(pid+" does not have permission:"+
4073 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4074 "for process:"+packageName);
4075 }
4076 }
4077
4078 try {
4079 //clear application user data
4080 pm.clearApplicationUserData(packageName, observer);
4081 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4082 Uri.fromParts("package", packageName, null));
4083 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004084 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07004085 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 } catch (RemoteException e) {
4087 }
4088 } finally {
4089 Binder.restoreCallingIdentity(callingId);
4090 }
4091 return true;
4092 }
4093
Dianne Hackborn03abb812010-01-04 18:43:19 -08004094 public void killBackgroundProcesses(final String packageName) {
4095 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4096 != PackageManager.PERMISSION_GRANTED &&
4097 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4098 != PackageManager.PERMISSION_GRANTED) {
4099 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 + Binder.getCallingPid()
4101 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08004102 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004103 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104 throw new SecurityException(msg);
4105 }
4106
4107 long callingId = Binder.clearCallingIdentity();
4108 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004109 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 int pkgUid = -1;
4111 synchronized(this) {
4112 try {
4113 pkgUid = pm.getPackageUid(packageName);
4114 } catch (RemoteException e) {
4115 }
4116 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004117 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118 return;
4119 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004120 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004121 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4122 }
4123 } finally {
4124 Binder.restoreCallingIdentity(callingId);
4125 }
4126 }
4127
4128 public void killAllBackgroundProcesses() {
4129 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4130 != PackageManager.PERMISSION_GRANTED) {
4131 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4132 + Binder.getCallingPid()
4133 + ", uid=" + Binder.getCallingUid()
4134 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4135 Slog.w(TAG, msg);
4136 throw new SecurityException(msg);
4137 }
4138
4139 long callingId = Binder.clearCallingIdentity();
4140 try {
4141 synchronized(this) {
4142 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4143 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4144 final int NA = apps.size();
4145 for (int ia=0; ia<NA; ia++) {
4146 ProcessRecord app = apps.valueAt(ia);
4147 if (app.persistent) {
4148 // we don't kill persistent processes
4149 continue;
4150 }
4151 if (app.removed) {
4152 procs.add(app);
4153 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
4154 app.removed = true;
4155 procs.add(app);
4156 }
4157 }
4158 }
4159
4160 int N = procs.size();
4161 for (int i=0; i<N; i++) {
4162 removeProcessLocked(procs.get(i), false, true, "kill all background");
4163 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004164 }
4165 } finally {
4166 Binder.restoreCallingIdentity(callingId);
4167 }
4168 }
4169
4170 public void forceStopPackage(final String packageName) {
4171 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4172 != PackageManager.PERMISSION_GRANTED) {
4173 String msg = "Permission Denial: forceStopPackage() from pid="
4174 + Binder.getCallingPid()
4175 + ", uid=" + Binder.getCallingUid()
4176 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004177 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004178 throw new SecurityException(msg);
4179 }
Amith Yamasani742a6712011-05-04 14:49:28 -07004180 final int userId = Binder.getOrigCallingUser();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004181 long callingId = Binder.clearCallingIdentity();
4182 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004183 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004184 int pkgUid = -1;
4185 synchronized(this) {
4186 try {
4187 pkgUid = pm.getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07004188 // Convert the uid to the one for the calling user
4189 pkgUid = UserId.getUid(userId, pkgUid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004190 } catch (RemoteException e) {
4191 }
4192 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004193 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004194 return;
4195 }
4196 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004197 try {
4198 pm.setPackageStoppedState(packageName, true);
4199 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08004200 } catch (IllegalArgumentException e) {
4201 Slog.w(TAG, "Failed trying to unstop package "
4202 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004204 }
4205 } finally {
4206 Binder.restoreCallingIdentity(callingId);
4207 }
4208 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004209
4210 /*
4211 * The pkg name and uid have to be specified.
4212 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4213 */
4214 public void killApplicationWithUid(String pkg, int uid) {
4215 if (pkg == null) {
4216 return;
4217 }
4218 // Make sure the uid is valid.
4219 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004220 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004221 return;
4222 }
4223 int callerUid = Binder.getCallingUid();
4224 // Only the system server can kill an application
4225 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07004226 // Post an aysnc message to kill the application
4227 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4228 msg.arg1 = uid;
4229 msg.arg2 = 0;
4230 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07004231 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004232 } else {
4233 throw new SecurityException(callerUid + " cannot kill pkg: " +
4234 pkg);
4235 }
4236 }
4237
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004238 public void closeSystemDialogs(String reason) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004239 enforceNotIsolatedCaller("closeSystemDialogs");
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004240 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004241 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004242 if (reason != null) {
4243 intent.putExtra("reason", reason);
4244 }
4245
4246 final int uid = Binder.getCallingUid();
4247 final long origId = Binder.clearCallingIdentity();
4248 synchronized (this) {
4249 int i = mWatchers.beginBroadcast();
4250 while (i > 0) {
4251 i--;
4252 IActivityWatcher w = mWatchers.getBroadcastItem(i);
4253 if (w != null) {
4254 try {
4255 w.closingSystemDialogs(reason);
4256 } catch (RemoteException e) {
4257 }
4258 }
4259 }
4260 mWatchers.finishBroadcast();
4261
Dianne Hackbornffa42482009-09-23 22:20:11 -07004262 mWindowManager.closeSystemDialogs(reason);
4263
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004264 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
4265 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004266 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004267 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07004268 Activity.RESULT_CANCELED, null, "close-sys");
4269 }
4270 }
4271
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004272 broadcastIntentLocked(null, null, intent, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004273 null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004274 }
4275 Binder.restoreCallingIdentity(origId);
4276 }
4277
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004278 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004279 throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004280 enforceNotIsolatedCaller("getProcessMemoryInfo");
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004281 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4282 for (int i=pids.length-1; i>=0; i--) {
4283 infos[i] = new Debug.MemoryInfo();
4284 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004285 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004286 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004287 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07004288
Dianne Hackbornb437e092011-08-05 17:50:29 -07004289 public long[] getProcessPss(int[] pids) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004290 enforceNotIsolatedCaller("getProcessPss");
Dianne Hackbornb437e092011-08-05 17:50:29 -07004291 long[] pss = new long[pids.length];
4292 for (int i=pids.length-1; i>=0; i--) {
4293 pss[i] = Debug.getPss(pids[i]);
4294 }
4295 return pss;
4296 }
4297
Christopher Tate5e1ab332009-09-01 20:32:49 -07004298 public void killApplicationProcess(String processName, int uid) {
4299 if (processName == null) {
4300 return;
4301 }
4302
4303 int callerUid = Binder.getCallingUid();
4304 // Only the system server can kill an application
4305 if (callerUid == Process.SYSTEM_UID) {
4306 synchronized (this) {
4307 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07004308 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07004309 try {
4310 app.thread.scheduleSuicide();
4311 } catch (RemoteException e) {
4312 // If the other end already died, then our work here is done.
4313 }
4314 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004315 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07004316 + processName + " / " + uid);
4317 }
4318 }
4319 } else {
4320 throw new SecurityException(callerUid + " cannot kill app process: " +
4321 processName);
4322 }
4323 }
4324
Dianne Hackborn03abb812010-01-04 18:43:19 -08004325 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004326 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4328 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004329 if (!mProcessesReady) {
4330 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 intent.putExtra(Intent.EXTRA_UID, uid);
4333 broadcastIntentLocked(null, null, intent,
4334 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004335 false, false,
4336 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 }
4338
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004339 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004340 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004341 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004342 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343
Dianne Hackborn03abb812010-01-04 18:43:19 -08004344 // Remove all processes this package may have touched: all with the
4345 // same UID (except for the system or root user), and all whose name
4346 // matches the package name.
4347 final String procNamePrefix = packageName + ":";
4348 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4349 final int NA = apps.size();
4350 for (int ia=0; ia<NA; ia++) {
4351 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07004352 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07004353 // we don't kill persistent processes
4354 continue;
4355 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004356 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004357 if (doit) {
4358 procs.add(app);
4359 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004360 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
4361 || app.processName.equals(packageName)
4362 || app.processName.startsWith(procNamePrefix)) {
4363 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004364 if (!doit) {
4365 return true;
4366 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004367 app.removed = true;
4368 procs.add(app);
4369 }
4370 }
4371 }
4372 }
4373
4374 int N = procs.size();
4375 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004376 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004377 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004378 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08004379 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004380
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004381 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004382 boolean callerWillRestart, boolean purgeCache, boolean doit,
4383 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004384 int i;
4385 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 if (uid < 0) {
4388 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004389 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 } catch (RemoteException e) {
4391 }
4392 }
4393
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004394 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004395 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004396
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004397 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
4398 while (badApps.hasNext()) {
4399 SparseArray<Long> ba = badApps.next();
4400 if (ba.get(uid) != null) {
4401 badApps.remove();
4402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
4404 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004405
4406 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004407 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004409 TaskRecord lastTask = null;
4410 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004411 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004412 final boolean samePackage = r.packageName.equals(name);
4413 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07004414 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004415 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07004416 if (r.finishing) {
4417 // If this activity is just finishing, then it is not
4418 // interesting as far as something to stop.
4419 continue;
4420 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004421 return true;
4422 }
4423 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004424 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004425 if (samePackage) {
4426 if (r.app != null) {
4427 r.app.removed = true;
4428 }
4429 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004431 lastTask = r.task;
4432 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
4433 null, "force-stop")) {
4434 i--;
4435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 }
4437 }
4438
4439 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07004440 int userId = UserId.getUserId(uid);
4441 for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
Christopher Tate064d8422011-07-26 15:38:07 -07004442 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07004443 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004444 if (!doit) {
4445 return true;
4446 }
4447 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004448 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 if (service.app != null) {
4450 service.app.removed = true;
4451 }
4452 service.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004453 service.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004454 services.add(service);
4455 }
4456 }
4457
4458 N = services.size();
4459 for (i=0; i<N; i++) {
4460 bringDownServiceLocked(services.get(i), true);
4461 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07004462
4463 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4464 for (ContentProviderRecord provider : mProvidersByClass.values()) {
4465 if (provider.info.packageName.equals(name)
4466 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
4467 if (!doit) {
4468 return true;
4469 }
4470 didSomething = true;
4471 providers.add(provider);
4472 }
4473 }
4474
4475 N = providers.size();
4476 for (i=0; i<N; i++) {
4477 removeDyingProviderLocked(null, providers.get(i));
4478 }
4479
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004480 if (doit) {
4481 if (purgeCache) {
4482 AttributeCache ac = AttributeCache.instance();
4483 if (ac != null) {
4484 ac.removePackage(name);
4485 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004486 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004487 if (mBooted) {
4488 mMainStack.resumeTopActivityLocked(null);
4489 mMainStack.scheduleIdleLocked();
4490 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004491 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004492
4493 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 }
4495
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004496 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004497 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004499 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004500 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004501 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 + "/" + uid + ")");
4503
4504 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004505 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004506 if (mHeavyWeightProcess == app) {
4507 mHeavyWeightProcess = null;
4508 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 boolean needRestart = false;
4511 if (app.pid > 0 && app.pid != MY_PID) {
4512 int pid = app.pid;
4513 synchronized (mPidsSelfLocked) {
4514 mPidsSelfLocked.remove(pid);
4515 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4516 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004517 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004518 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004519 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004520 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004522 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004524 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 } else {
4526 needRestart = true;
4527 }
4528 }
4529 } else {
4530 mRemovedProcesses.add(app);
4531 }
4532
4533 return needRestart;
4534 }
4535
4536 private final void processStartTimedOutLocked(ProcessRecord app) {
4537 final int pid = app.pid;
4538 boolean gone = false;
4539 synchronized (mPidsSelfLocked) {
4540 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4541 if (knownApp != null && knownApp.thread == null) {
4542 mPidsSelfLocked.remove(pid);
4543 gone = true;
4544 }
4545 }
4546
4547 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004548 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004549 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004550 app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004551 mProcessNames.remove(app.processName, app.uid);
4552 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004553 if (mHeavyWeightProcess == app) {
4554 mHeavyWeightProcess = null;
4555 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4556 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004557 // Take care of any launching providers waiting for this process.
4558 checkAppInLaunchingProvidersLocked(app, true);
4559 // Take care of any services that are waiting for the process.
4560 for (int i=0; i<mPendingServices.size(); i++) {
4561 ServiceRecord sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004562 if ((app.uid == sr.appInfo.uid
4563 && app.processName.equals(sr.processName))
4564 || sr.isolatedProc == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004565 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004566 sr.isolatedProc = null;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004567 mPendingServices.remove(i);
4568 i--;
4569 bringDownServiceLocked(sr, true);
4570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004572 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4573 app.processName, app.setAdj, "start timeout");
4574 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07004575 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004576 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07004577 try {
4578 IBackupManager bm = IBackupManager.Stub.asInterface(
4579 ServiceManager.getService(Context.BACKUP_SERVICE));
4580 bm.agentDisconnected(app.info.packageName);
4581 } catch (RemoteException e) {
4582 // Can't happen; the backup manager is local
4583 }
4584 }
Christopher Tatef46723b2012-01-26 14:19:24 -08004585 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004586 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08004587 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004589 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004590 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004591 }
4592 }
4593
4594 private final boolean attachApplicationLocked(IApplicationThread thread,
4595 int pid) {
4596
4597 // Find the application record that is being attached... either via
4598 // the pid if we are running in multiple processes, or just pull the
4599 // next app record if we are emulating process with anonymous threads.
4600 ProcessRecord app;
4601 if (pid != MY_PID && pid >= 0) {
4602 synchronized (mPidsSelfLocked) {
4603 app = mPidsSelfLocked.get(pid);
4604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 } else {
4606 app = null;
4607 }
4608
4609 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004610 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08004612 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004614 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615 } else {
4616 try {
4617 thread.scheduleExit();
4618 } catch (Exception e) {
4619 // Ignore exceptions.
4620 }
4621 }
4622 return false;
4623 }
4624
4625 // If this application record is still attached to a previous
4626 // process, clean it up now.
4627 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004628 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 }
4630
4631 // Tell the process all about itself.
4632
Joe Onorato8a9b2202010-02-26 18:56:32 -08004633 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 TAG, "Binding process pid " + pid + " to record " + app);
4635
4636 String processName = app.processName;
4637 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004638 AppDeathRecipient adr = new AppDeathRecipient(
4639 app, pid, thread);
4640 thread.asBinder().linkToDeath(adr, 0);
4641 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 } catch (RemoteException e) {
4643 app.resetPackageList();
4644 startProcessLocked(app, "link fail", processName);
4645 return false;
4646 }
4647
Doug Zongker2bec3d42009-12-04 12:52:44 -08004648 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004649
4650 app.thread = thread;
4651 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08004652 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4653 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 app.forcingToForeground = null;
4655 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07004656 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 app.debugging = false;
4658
4659 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4660
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004661 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004662 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004663
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004664 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004665 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004666 }
4667
Joe Onorato8a9b2202010-02-26 18:56:32 -08004668 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004669 TAG, "New app record " + app
4670 + " thread=" + thread.asBinder() + " pid=" + pid);
4671 try {
4672 int testMode = IApplicationThread.DEBUG_OFF;
4673 if (mDebugApp != null && mDebugApp.equals(processName)) {
4674 testMode = mWaitForDebugger
4675 ? IApplicationThread.DEBUG_WAIT
4676 : IApplicationThread.DEBUG_ON;
4677 app.debugging = true;
4678 if (mDebugTransient) {
4679 mDebugApp = mOrigDebugApp;
4680 mWaitForDebugger = mOrigWaitForDebugger;
4681 }
4682 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004683 String profileFile = app.instrumentationProfileFile;
4684 ParcelFileDescriptor profileFd = null;
4685 boolean profileAutoStop = false;
4686 if (mProfileApp != null && mProfileApp.equals(processName)) {
4687 mProfileProc = app;
4688 profileFile = mProfileFile;
4689 profileFd = mProfileFd;
4690 profileAutoStop = mAutoStopProfiler;
4691 }
4692
Christopher Tate181fafa2009-05-14 11:12:14 -07004693 // If the app is being launched for restore or full backup, set it up specially
4694 boolean isRestrictedBackupMode = false;
4695 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4696 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004697 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004698 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4699 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004700
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004701 ensurePackageDexOpt(app.instrumentationInfo != null
4702 ? app.instrumentationInfo.packageName
4703 : app.info.packageName);
4704 if (app.instrumentationClass != null) {
4705 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004706 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004707 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004708 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004709 ApplicationInfo appInfo = app.instrumentationInfo != null
4710 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004711 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004712 if (profileFd != null) {
4713 profileFd = profileFd.dup();
4714 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004715 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004716 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004717 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004718 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004719 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004720 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004721 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004722 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 } catch (Exception e) {
4724 // todo: Yikes! What should we do? For now we will try to
4725 // start another process, but that could easily get us in
4726 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004727 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728
4729 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004730 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 startProcessLocked(app, "bind fail", processName);
4732 return false;
4733 }
4734
4735 // Remove this record from the list of starting applications.
4736 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004737 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4738 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 mProcessesOnHold.remove(app);
4740
4741 boolean badApp = false;
4742 boolean didSomething = false;
4743
4744 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004745 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004746 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004747 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 && processName.equals(hr.processName)) {
4749 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004750 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 didSomething = true;
4752 }
4753 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004754 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755 + hr.intent.getComponent().flattenToShortString(), e);
4756 badApp = true;
4757 }
4758 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004759 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 }
4761 }
4762
4763 // Find any services that should be running in this process...
4764 if (!badApp && mPendingServices.size() > 0) {
4765 ServiceRecord sr = null;
4766 try {
4767 for (int i=0; i<mPendingServices.size(); i++) {
4768 sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004769 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4770 || !processName.equals(sr.processName))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004771 continue;
4772 }
4773
4774 mPendingServices.remove(i);
4775 i--;
4776 realStartServiceLocked(sr, app);
4777 didSomething = true;
4778 }
4779 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004780 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 + sr.shortName, e);
4782 badApp = true;
4783 }
4784 }
4785
Christopher Tatef46723b2012-01-26 14:19:24 -08004786 // Check if a next-broadcast receiver is in this process...
4787 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004788 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004789 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004790 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004791 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004793 }
4794 }
4795
Christopher Tate181fafa2009-05-14 11:12:14 -07004796 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004797 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004798 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004799 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004800 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004801 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4802 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4803 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004804 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004805 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004806 e.printStackTrace();
4807 }
4808 }
4809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004810 if (badApp) {
4811 // todo: Also need to kill application to deal with all
4812 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004813 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 return false;
4815 }
4816
4817 if (!didSomething) {
4818 updateOomAdjLocked();
4819 }
4820
4821 return true;
4822 }
4823
4824 public final void attachApplication(IApplicationThread thread) {
4825 synchronized (this) {
4826 int callingPid = Binder.getCallingPid();
4827 final long origId = Binder.clearCallingIdentity();
4828 attachApplicationLocked(thread, callingPid);
4829 Binder.restoreCallingIdentity(origId);
4830 }
4831 }
4832
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004833 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004835 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4836 if (stopProfiling) {
4837 synchronized (this) {
4838 if (mProfileProc == r.app) {
4839 if (mProfileFd != null) {
4840 try {
4841 mProfileFd.close();
4842 } catch (IOException e) {
4843 }
4844 clearProfilerLocked();
4845 }
4846 }
4847 }
4848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004849 Binder.restoreCallingIdentity(origId);
4850 }
4851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004853 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004854 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004855 mWindowManager.enableScreenAfterBoot();
4856 }
4857
Dianne Hackborn661cd522011-08-22 00:26:20 -07004858 public void showBootMessage(final CharSequence msg, final boolean always) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004859 enforceNotIsolatedCaller("showBootMessage");
Dianne Hackborn661cd522011-08-22 00:26:20 -07004860 mWindowManager.showBootMessage(msg, always);
4861 }
4862
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004863 public void dismissKeyguardOnNextActivity() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004864 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004865 synchronized (this) {
4866 mMainStack.dismissKeyguardOnNextActivityLocked();
4867 }
4868 }
4869
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004870 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004871 IntentFilter pkgFilter = new IntentFilter();
4872 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4873 pkgFilter.addDataScheme("package");
4874 mContext.registerReceiver(new BroadcastReceiver() {
4875 @Override
4876 public void onReceive(Context context, Intent intent) {
4877 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4878 if (pkgs != null) {
4879 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004880 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004881 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004882 setResultCode(Activity.RESULT_OK);
4883 return;
4884 }
4885 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004886 }
4887 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004888 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004889 }, pkgFilter);
4890
4891 synchronized (this) {
4892 // Ensure that any processes we had put on hold are now started
4893 // up.
4894 final int NP = mProcessesOnHold.size();
4895 if (NP > 0) {
4896 ArrayList<ProcessRecord> procs =
4897 new ArrayList<ProcessRecord>(mProcessesOnHold);
4898 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004899 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4900 + procs.get(ip));
4901 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004902 }
4903 }
4904
4905 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004906 // Start looking for apps that are abusing wake locks.
4907 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004908 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004909 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004910 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004911 SystemProperties.set("dev.bootcomplete", "1");
Amith Yamasani742a6712011-05-04 14:49:28 -07004912 /* TODO: Send this to all users that are to be logged in on startup */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004913 broadcastIntentLocked(null, null,
4914 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4915 null, null, 0, null, null,
4916 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Amith Yamasani742a6712011-05-04 14:49:28 -07004917 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004918 }
4919 }
4920 }
4921
4922 final void ensureBootCompleted() {
4923 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004924 boolean enableScreen;
4925 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004926 booting = mBooting;
4927 mBooting = false;
Mike Lockwooda8f767a2011-08-31 14:32:37 -04004928 enableScreen = !mBooted && !mHeadless;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004929 mBooted = true;
4930 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004931
4932 if (booting) {
4933 finishBooting();
4934 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004935
4936 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004937 enableScreenAfterBoot();
4938 }
4939 }
4940
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004941 public final void activityPaused(IBinder token) {
4942 final long origId = Binder.clearCallingIdentity();
4943 mMainStack.activityPaused(token, false);
4944 Binder.restoreCallingIdentity(origId);
4945 }
4946
4947 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4948 CharSequence description) {
4949 if (localLOGV) Slog.v(
4950 TAG, "Activity stopped: token=" + token);
4951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 // Refuse possible leaked file descriptors
4953 if (icicle != null && icicle.hasFileDescriptors()) {
4954 throw new IllegalArgumentException("File descriptors passed in Bundle");
4955 }
4956
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004957 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958
4959 final long origId = Binder.clearCallingIdentity();
4960
4961 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004962 r = mMainStack.isInStackLocked(token);
4963 if (r != null) {
4964 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965 }
4966 }
4967
4968 if (r != null) {
4969 sendPendingThumbnail(r, null, null, null, false);
4970 }
4971
4972 trimApplications();
4973
4974 Binder.restoreCallingIdentity(origId);
4975 }
4976
4977 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004978 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004979 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 }
4981
4982 public String getCallingPackage(IBinder token) {
4983 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004984 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004985 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986 }
4987 }
4988
4989 public ComponentName getCallingActivity(IBinder token) {
4990 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004991 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004992 return r != null ? r.intent.getComponent() : null;
4993 }
4994 }
4995
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004996 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004997 ActivityRecord r = mMainStack.isInStackLocked(token);
4998 if (r == null) {
4999 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005001 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 }
5003
5004 public ComponentName getActivityClassForToken(IBinder token) {
5005 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005006 ActivityRecord r = mMainStack.isInStackLocked(token);
5007 if (r == null) {
5008 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005009 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005010 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 }
5012 }
5013
5014 public String getPackageForToken(IBinder token) {
5015 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005016 ActivityRecord r = mMainStack.isInStackLocked(token);
5017 if (r == null) {
5018 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005019 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005020 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005021 }
5022 }
5023
5024 public IIntentSender getIntentSender(int type,
5025 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005026 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005027 enforceNotIsolatedCaller("getIntentSender");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005028 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005029 if (intents != null) {
5030 if (intents.length < 1) {
5031 throw new IllegalArgumentException("Intents array length must be >= 1");
5032 }
5033 for (int i=0; i<intents.length; i++) {
5034 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07005035 if (intent != null) {
5036 if (intent.hasFileDescriptors()) {
5037 throw new IllegalArgumentException("File descriptors passed in Intent");
5038 }
5039 if (type == INTENT_SENDER_BROADCAST &&
5040 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5041 throw new IllegalArgumentException(
5042 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5043 }
5044 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005045 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005046 }
5047 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005048 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005049 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005050 }
5051 }
5052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 synchronized(this) {
5054 int callingUid = Binder.getCallingUid();
5055 try {
Jeff Brown10e89712011-07-08 18:52:57 -07005056 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005057 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 .getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07005059 if (UserId.getAppId(callingUid) != uid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005060 String msg = "Permission Denial: getIntentSender() from pid="
5061 + Binder.getCallingPid()
5062 + ", uid=" + Binder.getCallingUid()
5063 + ", (need uid=" + uid + ")"
5064 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005065 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 throw new SecurityException(msg);
5067 }
5068 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005069
Amith Yamasani742a6712011-05-04 14:49:28 -07005070 if (DEBUG_MU)
5071 Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
5072 + Binder.getOrigCallingUid());
5073 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005074 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 } catch (RemoteException e) {
5077 throw new SecurityException(e);
5078 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005079 }
5080 }
5081
5082 IIntentSender getIntentSenderLocked(int type,
5083 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005084 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07005085 if (DEBUG_MU)
5086 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005087 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07005088 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005089 activity = mMainStack.isInStackLocked(token);
5090 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005091 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005092 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005093 if (activity.finishing) {
5094 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005095 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005096 }
5097
5098 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5099 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5100 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5101 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5102 |PendingIntent.FLAG_UPDATE_CURRENT);
5103
5104 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5105 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005106 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005107 WeakReference<PendingIntentRecord> ref;
5108 ref = mIntentSenderRecords.get(key);
5109 PendingIntentRecord rec = ref != null ? ref.get() : null;
5110 if (rec != null) {
5111 if (!cancelCurrent) {
5112 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005113 if (rec.key.requestIntent != null) {
5114 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
5115 }
5116 if (intents != null) {
5117 intents[intents.length-1] = rec.key.requestIntent;
5118 rec.key.allIntents = intents;
5119 rec.key.allResolvedTypes = resolvedTypes;
5120 } else {
5121 rec.key.allIntents = null;
5122 rec.key.allResolvedTypes = null;
5123 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005124 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005125 return rec;
5126 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005127 rec.canceled = true;
5128 mIntentSenderRecords.remove(key);
5129 }
5130 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005131 return rec;
5132 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005133 rec = new PendingIntentRecord(this, key, callingUid);
5134 mIntentSenderRecords.put(key, rec.ref);
5135 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5136 if (activity.pendingResults == null) {
5137 activity.pendingResults
5138 = new HashSet<WeakReference<PendingIntentRecord>>();
5139 }
5140 activity.pendingResults.add(rec.ref);
5141 }
5142 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143 }
5144
5145 public void cancelIntentSender(IIntentSender sender) {
5146 if (!(sender instanceof PendingIntentRecord)) {
5147 return;
5148 }
5149 synchronized(this) {
5150 PendingIntentRecord rec = (PendingIntentRecord)sender;
5151 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005152 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153 .getPackageUid(rec.key.packageName);
5154 if (uid != Binder.getCallingUid()) {
5155 String msg = "Permission Denial: cancelIntentSender() from pid="
5156 + Binder.getCallingPid()
5157 + ", uid=" + Binder.getCallingUid()
5158 + " is not allowed to cancel packges "
5159 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005160 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 throw new SecurityException(msg);
5162 }
5163 } catch (RemoteException e) {
5164 throw new SecurityException(e);
5165 }
5166 cancelIntentSenderLocked(rec, true);
5167 }
5168 }
5169
5170 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5171 rec.canceled = true;
5172 mIntentSenderRecords.remove(rec.key);
5173 if (cleanActivity && rec.key.activity != null) {
5174 rec.key.activity.pendingResults.remove(rec.ref);
5175 }
5176 }
5177
5178 public String getPackageForIntentSender(IIntentSender pendingResult) {
5179 if (!(pendingResult instanceof PendingIntentRecord)) {
5180 return null;
5181 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07005182 try {
5183 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5184 return res.key.packageName;
5185 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005186 }
5187 return null;
5188 }
5189
Dianne Hackborn6c418d52011-06-29 14:05:33 -07005190 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5191 if (!(pendingResult instanceof PendingIntentRecord)) {
5192 return false;
5193 }
5194 try {
5195 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5196 if (res.key.allIntents == null) {
5197 return false;
5198 }
5199 for (int i=0; i<res.key.allIntents.length; i++) {
5200 Intent intent = res.key.allIntents[i];
5201 if (intent.getPackage() != null && intent.getComponent() != null) {
5202 return false;
5203 }
5204 }
5205 return true;
5206 } catch (ClassCastException e) {
5207 }
5208 return false;
5209 }
5210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005211 public void setProcessLimit(int max) {
5212 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5213 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005214 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005215 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005216 mProcessLimitOverride = max;
5217 }
5218 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 }
5220
5221 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005222 synchronized (this) {
5223 return mProcessLimitOverride;
5224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 }
5226
5227 void foregroundTokenDied(ForegroundToken token) {
5228 synchronized (ActivityManagerService.this) {
5229 synchronized (mPidsSelfLocked) {
5230 ForegroundToken cur
5231 = mForegroundProcesses.get(token.pid);
5232 if (cur != token) {
5233 return;
5234 }
5235 mForegroundProcesses.remove(token.pid);
5236 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5237 if (pr == null) {
5238 return;
5239 }
5240 pr.forcingToForeground = null;
5241 pr.foregroundServices = false;
5242 }
5243 updateOomAdjLocked();
5244 }
5245 }
5246
5247 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5248 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5249 "setProcessForeground()");
5250 synchronized(this) {
5251 boolean changed = false;
5252
5253 synchronized (mPidsSelfLocked) {
5254 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005255 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005256 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005257 return;
5258 }
5259 ForegroundToken oldToken = mForegroundProcesses.get(pid);
5260 if (oldToken != null) {
5261 oldToken.token.unlinkToDeath(oldToken, 0);
5262 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005263 if (pr != null) {
5264 pr.forcingToForeground = null;
5265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 changed = true;
5267 }
5268 if (isForeground && token != null) {
5269 ForegroundToken newToken = new ForegroundToken() {
5270 public void binderDied() {
5271 foregroundTokenDied(this);
5272 }
5273 };
5274 newToken.pid = pid;
5275 newToken.token = token;
5276 try {
5277 token.linkToDeath(newToken, 0);
5278 mForegroundProcesses.put(pid, newToken);
5279 pr.forcingToForeground = token;
5280 changed = true;
5281 } catch (RemoteException e) {
5282 // If the process died while doing this, we will later
5283 // do the cleanup with the process death link.
5284 }
5285 }
5286 }
5287
5288 if (changed) {
5289 updateOomAdjLocked();
5290 }
5291 }
5292 }
5293
5294 // =========================================================
5295 // PERMISSIONS
5296 // =========================================================
5297
5298 static class PermissionController extends IPermissionController.Stub {
5299 ActivityManagerService mActivityManagerService;
5300 PermissionController(ActivityManagerService activityManagerService) {
5301 mActivityManagerService = activityManagerService;
5302 }
5303
5304 public boolean checkPermission(String permission, int pid, int uid) {
5305 return mActivityManagerService.checkPermission(permission, pid,
5306 uid) == PackageManager.PERMISSION_GRANTED;
5307 }
5308 }
5309
5310 /**
5311 * This can be called with or without the global lock held.
5312 */
5313 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005314 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 // We might be performing an operation on behalf of an indirect binder
5316 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
5317 // client identity accordingly before proceeding.
5318 Identity tlsIdentity = sCallerIdentity.get();
5319 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005320 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5322 uid = tlsIdentity.uid;
5323 pid = tlsIdentity.pid;
5324 }
5325
5326 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005327 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005328 return PackageManager.PERMISSION_GRANTED;
5329 }
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005330 // Isolated processes don't get any permissions.
5331 if (UserId.isIsolated(uid)) {
5332 return PackageManager.PERMISSION_DENIED;
5333 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005334 // If there is a uid that owns whatever is being accessed, it has
5335 // blanket access to it regardless of the permissions it requires.
Amith Yamasani742a6712011-05-04 14:49:28 -07005336 if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005337 return PackageManager.PERMISSION_GRANTED;
5338 }
5339 // If the target is not exported, then nobody else can get to it.
5340 if (!exported) {
5341 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 return PackageManager.PERMISSION_DENIED;
5343 }
5344 if (permission == null) {
5345 return PackageManager.PERMISSION_GRANTED;
5346 }
5347 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005348 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005349 .checkUidPermission(permission, uid);
5350 } catch (RemoteException e) {
5351 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08005352 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005353 }
5354 return PackageManager.PERMISSION_DENIED;
5355 }
5356
5357 /**
5358 * As the only public entry point for permissions checking, this method
5359 * can enforce the semantic that requesting a check on a null global
5360 * permission is automatically denied. (Internally a null permission
5361 * string is used when calling {@link #checkComponentPermission} in cases
5362 * when only uid-based security is needed.)
5363 *
5364 * This can be called with or without the global lock held.
5365 */
5366 public int checkPermission(String permission, int pid, int uid) {
5367 if (permission == null) {
5368 return PackageManager.PERMISSION_DENIED;
5369 }
Amith Yamasani742a6712011-05-04 14:49:28 -07005370 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 }
5372
5373 /**
5374 * Binder IPC calls go through the public entry point.
5375 * This can be called with or without the global lock held.
5376 */
5377 int checkCallingPermission(String permission) {
5378 return checkPermission(permission,
5379 Binder.getCallingPid(),
Amith Yamasani742a6712011-05-04 14:49:28 -07005380 UserId.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 }
5382
5383 /**
5384 * This can be called with or without the global lock held.
5385 */
5386 void enforceCallingPermission(String permission, String func) {
5387 if (checkCallingPermission(permission)
5388 == PackageManager.PERMISSION_GRANTED) {
5389 return;
5390 }
5391
5392 String msg = "Permission Denial: " + func + " from pid="
5393 + Binder.getCallingPid()
5394 + ", uid=" + Binder.getCallingUid()
5395 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005396 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005397 throw new SecurityException(msg);
5398 }
5399
5400 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07005401 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5402 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5403 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5404 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5405 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005406 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07005407 // Is the component private from the target uid?
5408 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
5409
5410 // Acceptable if the there is no read permission needed from the
5411 // target or the target is holding the read permission.
5412 if (!readPerm) {
5413 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005414 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005415 == PackageManager.PERMISSION_GRANTED)) {
5416 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 }
5418 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005419
5420 // Acceptable if the there is no write permission needed from the
5421 // target or the target is holding the read permission.
5422 if (!writePerm) {
5423 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005425 == PackageManager.PERMISSION_GRANTED)) {
5426 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 }
5428 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005429
5430 // Acceptable if there is a path permission matching the URI that
5431 // the target holds the permission on.
5432 PathPermission[] pps = pi.pathPermissions;
5433 if (pps != null && (!readPerm || !writePerm)) {
5434 final String path = uri.getPath();
5435 int i = pps.length;
5436 while (i > 0 && (!readPerm || !writePerm)) {
5437 i--;
5438 PathPermission pp = pps[i];
5439 if (!readPerm) {
5440 final String pprperm = pp.getReadPermission();
5441 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5442 + pprperm + " for " + pp.getPath()
5443 + ": match=" + pp.match(path)
5444 + " check=" + pm.checkUidPermission(pprperm, uid));
5445 if (pprperm != null && pp.match(path) &&
5446 (pm.checkUidPermission(pprperm, uid)
5447 == PackageManager.PERMISSION_GRANTED)) {
5448 readPerm = true;
5449 }
5450 }
5451 if (!writePerm) {
5452 final String ppwperm = pp.getWritePermission();
5453 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5454 + ppwperm + " for " + pp.getPath()
5455 + ": match=" + pp.match(path)
5456 + " check=" + pm.checkUidPermission(ppwperm, uid));
5457 if (ppwperm != null && pp.match(path) &&
5458 (pm.checkUidPermission(ppwperm, uid)
5459 == PackageManager.PERMISSION_GRANTED)) {
5460 writePerm = true;
5461 }
5462 }
5463 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005465 } catch (RemoteException e) {
5466 return false;
5467 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005468
5469 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 }
5471
5472 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5473 int modeFlags) {
5474 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005475 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 return true;
5477 }
5478 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5479 if (perms == null) return false;
5480 UriPermission perm = perms.get(uri);
5481 if (perm == null) return false;
5482 return (modeFlags&perm.modeFlags) == modeFlags;
5483 }
5484
5485 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005486 enforceNotIsolatedCaller("checkUriPermission");
5487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005488 // Another redirected-binder-call permissions check as in
5489 // {@link checkComponentPermission}.
5490 Identity tlsIdentity = sCallerIdentity.get();
5491 if (tlsIdentity != null) {
5492 uid = tlsIdentity.uid;
5493 pid = tlsIdentity.pid;
5494 }
5495
Amith Yamasani742a6712011-05-04 14:49:28 -07005496 uid = UserId.getAppId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005497 // Our own process gets to do everything.
5498 if (pid == MY_PID) {
5499 return PackageManager.PERMISSION_GRANTED;
5500 }
5501 synchronized(this) {
5502 return checkUriPermissionLocked(uri, uid, modeFlags)
5503 ? PackageManager.PERMISSION_GRANTED
5504 : PackageManager.PERMISSION_DENIED;
5505 }
5506 }
5507
Dianne Hackborn39792d22010-08-19 18:01:52 -07005508 /**
5509 * Check if the targetPkg can be granted permission to access uri by
5510 * the callingUid using the given modeFlags. Throws a security exception
5511 * if callingUid is not allowed to do this. Returns the uid of the target
5512 * if the URI permission grant should be performed; returns -1 if it is not
5513 * needed (for example targetPkg already has permission to access the URI).
5514 */
5515 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5516 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005517 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5518 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5519 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005520 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005521 }
5522
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005523 if (targetPkg != null) {
5524 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5525 "Checking grant " + targetPkg + " permission to " + uri);
5526 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005527
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005528 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529
5530 // If this is not a content: uri, we can't do anything with it.
5531 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005532 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005533 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005534 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 }
5536
5537 String name = uri.getAuthority();
5538 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005539 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5540 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005541 if (cpr != null) {
5542 pi = cpr.info;
5543 } else {
5544 try {
5545 pi = pm.resolveContentProvider(name,
5546 PackageManager.GET_URI_PERMISSION_PATTERNS);
5547 } catch (RemoteException ex) {
5548 }
5549 }
5550 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005551 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07005552 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005553 }
5554
5555 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005556 if (targetPkg != null) {
5557 try {
5558 targetUid = pm.getPackageUid(targetPkg);
5559 if (targetUid < 0) {
5560 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5561 "Can't grant URI permission no uid for: " + targetPkg);
5562 return -1;
5563 }
5564 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005565 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005567 } else {
5568 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 }
5570
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005571 if (targetUid >= 0) {
5572 // First... does the target actually need this permission?
5573 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5574 // No need to grant the target this permission.
5575 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5576 "Target " + targetPkg + " already has full permission to " + uri);
5577 return -1;
5578 }
5579 } else {
5580 // First... there is no target package, so can anyone access it?
5581 boolean allowed = pi.exported;
5582 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5583 if (pi.readPermission != null) {
5584 allowed = false;
5585 }
5586 }
5587 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5588 if (pi.writePermission != null) {
5589 allowed = false;
5590 }
5591 }
5592 if (allowed) {
5593 return -1;
5594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 }
5596
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005597 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 if (!pi.grantUriPermissions) {
5599 throw new SecurityException("Provider " + pi.packageName
5600 + "/" + pi.name
5601 + " does not allow granting of Uri permissions (uri "
5602 + uri + ")");
5603 }
5604 if (pi.uriPermissionPatterns != null) {
5605 final int N = pi.uriPermissionPatterns.length;
5606 boolean allowed = false;
5607 for (int i=0; i<N; i++) {
5608 if (pi.uriPermissionPatterns[i] != null
5609 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5610 allowed = true;
5611 break;
5612 }
5613 }
5614 if (!allowed) {
5615 throw new SecurityException("Provider " + pi.packageName
5616 + "/" + pi.name
5617 + " does not allow granting of permission to path of Uri "
5618 + uri);
5619 }
5620 }
5621
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005622 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005624 if (callingUid != Process.myUid()) {
5625 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5626 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5627 throw new SecurityException("Uid " + callingUid
5628 + " does not have permission to uri " + uri);
5629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 }
5631 }
5632
Dianne Hackborn39792d22010-08-19 18:01:52 -07005633 return targetUid;
5634 }
5635
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005636 public int checkGrantUriPermission(int callingUid, String targetPkg,
5637 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005638 enforceNotIsolatedCaller("checkGrantUriPermission");
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005639 synchronized(this) {
5640 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5641 }
5642 }
5643
Dianne Hackborn39792d22010-08-19 18:01:52 -07005644 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5645 Uri uri, int modeFlags, UriPermissionOwner owner) {
5646 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5647 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5648 if (modeFlags == 0) {
5649 return;
5650 }
5651
5652 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653 // to the uri, and the target doesn't. Let's now give this to
5654 // the target.
5655
Joe Onorato8a9b2202010-02-26 18:56:32 -08005656 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005657 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005659 HashMap<Uri, UriPermission> targetUris
5660 = mGrantedUriPermissions.get(targetUid);
5661 if (targetUris == null) {
5662 targetUris = new HashMap<Uri, UriPermission>();
5663 mGrantedUriPermissions.put(targetUid, targetUris);
5664 }
5665
5666 UriPermission perm = targetUris.get(uri);
5667 if (perm == null) {
5668 perm = new UriPermission(targetUid, uri);
5669 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005673 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005675 } else {
5676 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5677 perm.readOwners.add(owner);
5678 owner.addReadPermission(perm);
5679 }
5680 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5681 perm.writeOwners.add(owner);
5682 owner.addWritePermission(perm);
5683 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005684 }
5685 }
5686
Dianne Hackborn39792d22010-08-19 18:01:52 -07005687 void grantUriPermissionLocked(int callingUid,
5688 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005689 if (targetPkg == null) {
5690 throw new NullPointerException("targetPkg");
5691 }
5692
Dianne Hackborn39792d22010-08-19 18:01:52 -07005693 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5694 if (targetUid < 0) {
5695 return;
5696 }
5697
5698 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5699 }
5700
5701 /**
5702 * Like checkGrantUriPermissionLocked, but takes an Intent.
5703 */
5704 int checkGrantUriPermissionFromIntentLocked(int callingUid,
5705 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005706 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005707 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005708 + " from " + intent + "; flags=0x"
5709 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5710
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005711 if (targetPkg == null) {
5712 throw new NullPointerException("targetPkg");
5713 }
5714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005715 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005716 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005717 }
5718 Uri data = intent.getData();
5719 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005720 return -1;
5721 }
5722 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5723 intent.getFlags());
5724 }
5725
5726 /**
5727 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5728 */
5729 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
5730 String targetPkg, Intent intent, UriPermissionOwner owner) {
5731 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
5732 intent.getFlags(), owner);
5733 }
5734
5735 void grantUriPermissionFromIntentLocked(int callingUid,
5736 String targetPkg, Intent intent, UriPermissionOwner owner) {
5737 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
5738 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005739 return;
5740 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005741
5742 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005743 }
5744
5745 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5746 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005747 enforceNotIsolatedCaller("grantUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 synchronized(this) {
5749 final ProcessRecord r = getRecordForAppLocked(caller);
5750 if (r == null) {
5751 throw new SecurityException("Unable to find app for caller "
5752 + caller
5753 + " when granting permission to uri " + uri);
5754 }
5755 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005756 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005757 }
5758 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005759 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 }
5761
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005762 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 null);
5764 }
5765 }
5766
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005767 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005768 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5769 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5770 HashMap<Uri, UriPermission> perms
5771 = mGrantedUriPermissions.get(perm.uid);
5772 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005773 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005774 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005775 perms.remove(perm.uri);
5776 if (perms.size() == 0) {
5777 mGrantedUriPermissions.remove(perm.uid);
5778 }
5779 }
5780 }
5781 }
5782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005783 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5784 int modeFlags) {
5785 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5786 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5787 if (modeFlags == 0) {
5788 return;
5789 }
5790
Joe Onorato8a9b2202010-02-26 18:56:32 -08005791 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005792 "Revoking all granted permissions to " + uri);
5793
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005794 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005795
5796 final String authority = uri.getAuthority();
5797 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005798 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority,
5799 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 if (cpr != null) {
5801 pi = cpr.info;
5802 } else {
5803 try {
5804 pi = pm.resolveContentProvider(authority,
5805 PackageManager.GET_URI_PERMISSION_PATTERNS);
5806 } catch (RemoteException ex) {
5807 }
5808 }
5809 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005810 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005811 return;
5812 }
5813
5814 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005815 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005816 // Right now, if you are not the original owner of the permission,
5817 // you are not allowed to revoke it.
5818 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5819 throw new SecurityException("Uid " + callingUid
5820 + " does not have permission to uri " + uri);
5821 //}
5822 }
5823
5824 // Go through all of the permissions and remove any that match.
5825 final List<String> SEGMENTS = uri.getPathSegments();
5826 if (SEGMENTS != null) {
5827 final int NS = SEGMENTS.size();
5828 int N = mGrantedUriPermissions.size();
5829 for (int i=0; i<N; i++) {
5830 HashMap<Uri, UriPermission> perms
5831 = mGrantedUriPermissions.valueAt(i);
5832 Iterator<UriPermission> it = perms.values().iterator();
5833 toploop:
5834 while (it.hasNext()) {
5835 UriPermission perm = it.next();
5836 Uri targetUri = perm.uri;
5837 if (!authority.equals(targetUri.getAuthority())) {
5838 continue;
5839 }
5840 List<String> targetSegments = targetUri.getPathSegments();
5841 if (targetSegments == null) {
5842 continue;
5843 }
5844 if (targetSegments.size() < NS) {
5845 continue;
5846 }
5847 for (int j=0; j<NS; j++) {
5848 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5849 continue toploop;
5850 }
5851 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005852 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005853 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005854 perm.clearModes(modeFlags);
5855 if (perm.modeFlags == 0) {
5856 it.remove();
5857 }
5858 }
5859 if (perms.size() == 0) {
5860 mGrantedUriPermissions.remove(
5861 mGrantedUriPermissions.keyAt(i));
5862 N--;
5863 i--;
5864 }
5865 }
5866 }
5867 }
5868
5869 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5870 int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005871 enforceNotIsolatedCaller("revokeUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005872 synchronized(this) {
5873 final ProcessRecord r = getRecordForAppLocked(caller);
5874 if (r == null) {
5875 throw new SecurityException("Unable to find app for caller "
5876 + caller
5877 + " when revoking permission to uri " + uri);
5878 }
5879 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005880 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005881 return;
5882 }
5883
5884 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5885 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5886 if (modeFlags == 0) {
5887 return;
5888 }
5889
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005890 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891
5892 final String authority = uri.getAuthority();
5893 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005894 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005895 if (cpr != null) {
5896 pi = cpr.info;
5897 } else {
5898 try {
5899 pi = pm.resolveContentProvider(authority,
5900 PackageManager.GET_URI_PERMISSION_PATTERNS);
5901 } catch (RemoteException ex) {
5902 }
5903 }
5904 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005905 Slog.w(TAG, "No content provider found for permission revoke: "
5906 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 return;
5908 }
5909
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005910 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 }
5912 }
5913
Dianne Hackborn7e269642010-08-25 19:50:20 -07005914 @Override
5915 public IBinder newUriPermissionOwner(String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005916 enforceNotIsolatedCaller("newUriPermissionOwner");
Dianne Hackborn7e269642010-08-25 19:50:20 -07005917 synchronized(this) {
5918 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5919 return owner.getExternalTokenLocked();
5920 }
5921 }
5922
5923 @Override
5924 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5925 Uri uri, int modeFlags) {
5926 synchronized(this) {
5927 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5928 if (owner == null) {
5929 throw new IllegalArgumentException("Unknown owner: " + token);
5930 }
5931 if (fromUid != Binder.getCallingUid()) {
5932 if (Binder.getCallingUid() != Process.myUid()) {
5933 // Only system code can grant URI permissions on behalf
5934 // of other users.
5935 throw new SecurityException("nice try");
5936 }
5937 }
5938 if (targetPkg == null) {
5939 throw new IllegalArgumentException("null target");
5940 }
5941 if (uri == null) {
5942 throw new IllegalArgumentException("null uri");
5943 }
5944
5945 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5946 }
5947 }
5948
5949 @Override
5950 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5951 synchronized(this) {
5952 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5953 if (owner == null) {
5954 throw new IllegalArgumentException("Unknown owner: " + token);
5955 }
5956
5957 if (uri == null) {
5958 owner.removeUriPermissionsLocked(mode);
5959 } else {
5960 owner.removeUriPermissionLocked(uri, mode);
5961 }
5962 }
5963 }
5964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005965 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5966 synchronized (this) {
5967 ProcessRecord app =
5968 who != null ? getRecordForAppLocked(who) : null;
5969 if (app == null) return;
5970
5971 Message msg = Message.obtain();
5972 msg.what = WAIT_FOR_DEBUGGER_MSG;
5973 msg.obj = app;
5974 msg.arg1 = waiting ? 1 : 0;
5975 mHandler.sendMessage(msg);
5976 }
5977 }
5978
5979 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005980 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5981 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005983 outInfo.threshold = homeAppMem;
5984 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5985 outInfo.hiddenAppThreshold = hiddenAppMem;
5986 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005987 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005988 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5989 ProcessList.VISIBLE_APP_ADJ);
5990 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5991 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005992 }
5993
5994 // =========================================================
5995 // TASK MANAGEMENT
5996 // =========================================================
5997
5998 public List getTasks(int maxNum, int flags,
5999 IThumbnailReceiver receiver) {
6000 ArrayList list = new ArrayList();
6001
6002 PendingThumbnailsRecord pending = null;
6003 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006004 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006005
6006 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006007 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006008 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6009 + ", receiver=" + receiver);
6010
6011 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6012 != PackageManager.PERMISSION_GRANTED) {
6013 if (receiver != null) {
6014 // If the caller wants to wait for pending thumbnails,
6015 // it ain't gonna get them.
6016 try {
6017 receiver.finished();
6018 } catch (RemoteException ex) {
6019 }
6020 }
6021 String msg = "Permission Denial: getTasks() from pid="
6022 + Binder.getCallingPid()
6023 + ", uid=" + Binder.getCallingUid()
6024 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006025 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 throw new SecurityException(msg);
6027 }
6028
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006029 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006030 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006031 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006032 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033 TaskRecord curTask = null;
6034 int numActivities = 0;
6035 int numRunning = 0;
6036 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006037 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006038 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006039 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006040
6041 // Initialize state for next task if needed.
6042 if (top == null ||
6043 (top.state == ActivityState.INITIALIZING
6044 && top.task == r.task)) {
6045 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 curTask = r.task;
6047 numActivities = numRunning = 0;
6048 }
6049
6050 // Add 'r' into the current task.
6051 numActivities++;
6052 if (r.app != null && r.app.thread != null) {
6053 numRunning++;
6054 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055
Joe Onorato8a9b2202010-02-26 18:56:32 -08006056 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006057 TAG, r.intent.getComponent().flattenToShortString()
6058 + ": task=" + r.task);
6059
6060 // If the next one is a different task, generate a new
6061 // TaskInfo entry for what we have.
6062 if (next == null || next.task != curTask) {
6063 ActivityManager.RunningTaskInfo ci
6064 = new ActivityManager.RunningTaskInfo();
6065 ci.id = curTask.taskId;
6066 ci.baseActivity = r.intent.getComponent();
6067 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006068 if (top.thumbHolder != null) {
6069 ci.description = top.thumbHolder.lastDescription;
6070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006071 ci.numActivities = numActivities;
6072 ci.numRunning = numRunning;
6073 //System.out.println(
6074 // "#" + maxNum + ": " + " descr=" + ci.description);
6075 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006076 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006077 TAG, "State=" + top.state + "Idle=" + top.idle
6078 + " app=" + top.app
6079 + " thr=" + (top.app != null ? top.app.thread : null));
6080 if (top.state == ActivityState.RESUMED
6081 || top.state == ActivityState.PAUSING) {
6082 if (top.idle && top.app != null
6083 && top.app.thread != null) {
6084 topRecord = top;
6085 topThumbnail = top.app.thread;
6086 } else {
6087 top.thumbnailNeeded = true;
6088 }
6089 }
6090 if (pending == null) {
6091 pending = new PendingThumbnailsRecord(receiver);
6092 }
6093 pending.pendingRecords.add(top);
6094 }
6095 list.add(ci);
6096 maxNum--;
6097 top = null;
6098 }
6099 }
6100
6101 if (pending != null) {
6102 mPendingThumbnails.add(pending);
6103 }
6104 }
6105
Joe Onorato8a9b2202010-02-26 18:56:32 -08006106 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006107
6108 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006109 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08006111 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006112 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006113 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006114 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 }
6116 }
6117
6118 if (pending == null && receiver != null) {
6119 // In this case all thumbnails were available and the client
6120 // is being asked to be told when the remaining ones come in...
6121 // which is unusually, since the top-most currently running
6122 // activity should never have a canned thumbnail! Oh well.
6123 try {
6124 receiver.finished();
6125 } catch (RemoteException ex) {
6126 }
6127 }
6128
6129 return list;
6130 }
6131
6132 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6133 int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006134 final int callingUid = Binder.getCallingUid();
6135 // If it's the system uid asking, then use the current user id.
6136 // TODO: Make sure that there aren't any other legitimate calls from the system uid that
6137 // require the entire list.
6138 final int callingUserId = callingUid == Process.SYSTEM_UID
6139 ? mCurrentUserId : UserId.getUserId(callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 synchronized (this) {
6141 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6142 "getRecentTasks()");
6143
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006144 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006146 final int N = mRecentTasks.size();
6147 ArrayList<ActivityManager.RecentTaskInfo> res
6148 = new ArrayList<ActivityManager.RecentTaskInfo>(
6149 maxNum < N ? maxNum : N);
6150 for (int i=0; i<N && maxNum > 0; i++) {
6151 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006152 // Only add calling user's recent tasks
6153 if (tr.userId != callingUserId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07006154 // Return the entry if desired by the caller. We always return
6155 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07006156 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07006157 // not supplied RECENT_WITH_EXCLUDED and there is some reason
6158 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07006159
Dianne Hackborn905577f2011-09-07 18:31:28 -07006160 if (i == 0
6161 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 || (tr.intent == null)
6163 || ((tr.intent.getFlags()
6164 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6165 ActivityManager.RecentTaskInfo rti
6166 = new ActivityManager.RecentTaskInfo();
6167 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006168 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 rti.baseIntent = new Intent(
6170 tr.intent != null ? tr.intent : tr.affinityIntent);
6171 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08006172 rti.description = tr.lastDescription;
6173
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006174 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6175 // Check whether this activity is currently available.
6176 try {
6177 if (rti.origActivity != null) {
6178 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
6179 continue;
6180 }
6181 } else if (rti.baseIntent != null) {
6182 if (pm.queryIntentActivities(rti.baseIntent,
6183 null, 0) == null) {
6184 continue;
6185 }
6186 }
6187 } catch (RemoteException e) {
6188 // Will never happen.
6189 }
6190 }
6191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006192 res.add(rti);
6193 maxNum--;
6194 }
6195 }
6196 return res;
6197 }
6198 }
6199
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006200 private TaskRecord taskForIdLocked(int id) {
6201 final int N = mRecentTasks.size();
6202 for (int i=0; i<N; i++) {
6203 TaskRecord tr = mRecentTasks.get(i);
6204 if (tr.taskId == id) {
6205 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006206 }
6207 }
6208 return null;
6209 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006210
6211 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6212 synchronized (this) {
6213 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6214 "getTaskThumbnails()");
6215 TaskRecord tr = taskForIdLocked(id);
6216 if (tr != null) {
6217 return mMainStack.getTaskThumbnailsLocked(tr);
6218 }
6219 }
6220 return null;
6221 }
6222
6223 public boolean removeSubTask(int taskId, int subTaskIndex) {
6224 synchronized (this) {
6225 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6226 "removeSubTask()");
6227 long ident = Binder.clearCallingIdentity();
6228 try {
6229 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
6230 } finally {
6231 Binder.restoreCallingIdentity(ident);
6232 }
6233 }
6234 }
6235
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006236 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006237 TaskRecord tr = root.task;
6238 Intent baseIntent = new Intent(
6239 tr.intent != null ? tr.intent : tr.affinityIntent);
6240 ComponentName component = baseIntent.getComponent();
6241 if (component == null) {
6242 Slog.w(TAG, "Now component for base intent of task: " + tr);
6243 return;
6244 }
6245
6246 // Find any running services associated with this app.
6247 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07006248 for (ServiceRecord sr : mServiceMap.getAllServices(root.userId)) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006249 if (sr.packageName.equals(component.getPackageName())) {
6250 services.add(sr);
6251 }
6252 }
6253
6254 // Take care of any running services associated with the app.
6255 for (int i=0; i<services.size(); i++) {
6256 ServiceRecord sr = services.get(i);
6257 if (sr.startRequested) {
6258 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006259 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006260 stopServiceLocked(sr);
6261 } else {
6262 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
6263 sr.makeNextStartId(), baseIntent, -1));
6264 if (sr.app != null && sr.app.thread != null) {
6265 sendServiceArgsLocked(sr, false);
6266 }
6267 }
6268 }
6269 }
6270
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006271 if (killProcesses) {
6272 // Find any running processes associated with this app.
6273 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6274 SparseArray<ProcessRecord> appProcs
6275 = mProcessNames.getMap().get(component.getPackageName());
6276 if (appProcs != null) {
6277 for (int i=0; i<appProcs.size(); i++) {
6278 procs.add(appProcs.valueAt(i));
6279 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006280 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006281
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006282 // Kill the running processes.
6283 for (int i=0; i<procs.size(); i++) {
6284 ProcessRecord pr = procs.get(i);
6285 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6286 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
6287 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
6288 pr.processName, pr.setAdj, "remove task");
6289 Process.killProcessQuiet(pr.pid);
6290 } else {
6291 pr.waitingToKill = "remove task";
6292 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006293 }
6294 }
6295 }
6296
6297 public boolean removeTask(int taskId, int flags) {
6298 synchronized (this) {
6299 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6300 "removeTask()");
6301 long ident = Binder.clearCallingIdentity();
6302 try {
6303 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
6304 if (r != null) {
6305 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006306 cleanUpRemovedTaskLocked(r,
6307 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006308 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07006309 } else {
6310 TaskRecord tr = null;
6311 int i=0;
6312 while (i < mRecentTasks.size()) {
6313 TaskRecord t = mRecentTasks.get(i);
6314 if (t.taskId == taskId) {
6315 tr = t;
6316 break;
6317 }
6318 i++;
6319 }
6320 if (tr != null) {
6321 if (tr.numActivities <= 0) {
6322 // Caller is just removing a recent task that is
6323 // not actively running. That is easy!
6324 mRecentTasks.remove(i);
6325 } else {
6326 Slog.w(TAG, "removeTask: task " + taskId
6327 + " does not have activities to remove, "
6328 + " but numActivities=" + tr.numActivities
6329 + ": " + tr);
6330 }
6331 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006332 }
6333 } finally {
6334 Binder.restoreCallingIdentity(ident);
6335 }
6336 }
6337 return false;
6338 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08006339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006340 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6341 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006342 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006343 TaskRecord jt = startTask;
6344
6345 // First look backwards
6346 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006347 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006348 if (r.task != jt) {
6349 jt = r.task;
6350 if (affinity.equals(jt.affinity)) {
6351 return j;
6352 }
6353 }
6354 }
6355
6356 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006357 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006358 jt = startTask;
6359 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006360 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006361 if (r.task != jt) {
6362 if (affinity.equals(jt.affinity)) {
6363 return j;
6364 }
6365 jt = r.task;
6366 }
6367 }
6368
6369 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006370 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006371 return N-1;
6372 }
6373
6374 return -1;
6375 }
6376
6377 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006378 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006379 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006380 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6382 "moveTaskToFront()");
6383
6384 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006385 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6386 Binder.getCallingUid(), "Task to front")) {
6387 return;
6388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 final long origId = Binder.clearCallingIdentity();
6390 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006391 TaskRecord tr = taskForIdLocked(task);
6392 if (tr != null) {
6393 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6394 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006396 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6397 // Caller wants the home activity moved with it. To accomplish this,
6398 // we'll just move the home task to the top first.
6399 mMainStack.moveHomeToFrontLocked();
6400 }
6401 mMainStack.moveTaskToFrontLocked(tr, null);
6402 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006404 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6405 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08006407 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6408 mMainStack.mUserLeaving = true;
6409 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006410 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6411 // Caller wants the home activity moved with it. To accomplish this,
6412 // we'll just move the home task to the top first.
6413 mMainStack.moveHomeToFrontLocked();
6414 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006415 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006416 return;
6417 }
6418 }
6419 } finally {
6420 Binder.restoreCallingIdentity(origId);
6421 }
6422 }
6423 }
6424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 public void moveTaskToBack(int task) {
6426 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6427 "moveTaskToBack()");
6428
6429 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006430 if (mMainStack.mResumedActivity != null
6431 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006432 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6433 Binder.getCallingUid(), "Task to back")) {
6434 return;
6435 }
6436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006438 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006439 Binder.restoreCallingIdentity(origId);
6440 }
6441 }
6442
6443 /**
6444 * Moves an activity, and all of the other activities within the same task, to the bottom
6445 * of the history stack. The activity's order within the task is unchanged.
6446 *
6447 * @param token A reference to the activity we wish to move
6448 * @param nonRoot If false then this only works if the activity is the root
6449 * of a task; if true it will work for any activity in a task.
6450 * @return Returns true if the move completed, false if not.
6451 */
6452 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006453 enforceNotIsolatedCaller("moveActivityTaskToBack");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 synchronized(this) {
6455 final long origId = Binder.clearCallingIdentity();
6456 int taskId = getTaskForActivityLocked(token, !nonRoot);
6457 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006458 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 }
6460 Binder.restoreCallingIdentity(origId);
6461 }
6462 return false;
6463 }
6464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006465 public void moveTaskBackwards(int task) {
6466 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6467 "moveTaskBackwards()");
6468
6469 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006470 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6471 Binder.getCallingUid(), "Task backwards")) {
6472 return;
6473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 final long origId = Binder.clearCallingIdentity();
6475 moveTaskBackwardsLocked(task);
6476 Binder.restoreCallingIdentity(origId);
6477 }
6478 }
6479
6480 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006481 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006482 }
6483
6484 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6485 synchronized(this) {
6486 return getTaskForActivityLocked(token, onlyRoot);
6487 }
6488 }
6489
6490 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006491 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006492 TaskRecord lastTask = null;
6493 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006494 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006495 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006496 if (!onlyRoot || lastTask != r.task) {
6497 return r.task.taskId;
6498 }
6499 return -1;
6500 }
6501 lastTask = r.task;
6502 }
6503
6504 return -1;
6505 }
6506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507 public void finishOtherInstances(IBinder token, ComponentName className) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006508 enforceNotIsolatedCaller("finishOtherInstances");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 synchronized(this) {
6510 final long origId = Binder.clearCallingIdentity();
6511
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006512 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 TaskRecord lastTask = null;
6514 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006515 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006516 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08006517 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006518 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006519 null, "others")) {
6520 i--;
6521 N--;
6522 }
6523 }
6524 lastTask = r.task;
6525 }
6526
6527 Binder.restoreCallingIdentity(origId);
6528 }
6529 }
6530
6531 // =========================================================
6532 // THUMBNAILS
6533 // =========================================================
6534
6535 public void reportThumbnail(IBinder token,
6536 Bitmap thumbnail, CharSequence description) {
6537 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6538 final long origId = Binder.clearCallingIdentity();
6539 sendPendingThumbnail(null, token, thumbnail, description, true);
6540 Binder.restoreCallingIdentity(origId);
6541 }
6542
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006543 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 Bitmap thumbnail, CharSequence description, boolean always) {
6545 TaskRecord task = null;
6546 ArrayList receivers = null;
6547
6548 //System.out.println("Send pending thumbnail: " + r);
6549
6550 synchronized(this) {
6551 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006552 r = mMainStack.isInStackLocked(token);
6553 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006554 return;
6555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006556 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006557 if (thumbnail == null && r.thumbHolder != null) {
6558 thumbnail = r.thumbHolder.lastThumbnail;
6559 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006560 }
6561 if (thumbnail == null && !always) {
6562 // If there is no thumbnail, and this entry is not actually
6563 // going away, then abort for now and pick up the next
6564 // thumbnail we get.
6565 return;
6566 }
6567 task = r.task;
6568
6569 int N = mPendingThumbnails.size();
6570 int i=0;
6571 while (i<N) {
6572 PendingThumbnailsRecord pr =
6573 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6574 //System.out.println("Looking in " + pr.pendingRecords);
6575 if (pr.pendingRecords.remove(r)) {
6576 if (receivers == null) {
6577 receivers = new ArrayList();
6578 }
6579 receivers.add(pr);
6580 if (pr.pendingRecords.size() == 0) {
6581 pr.finished = true;
6582 mPendingThumbnails.remove(i);
6583 N--;
6584 continue;
6585 }
6586 }
6587 i++;
6588 }
6589 }
6590
6591 if (receivers != null) {
6592 final int N = receivers.size();
6593 for (int i=0; i<N; i++) {
6594 try {
6595 PendingThumbnailsRecord pr =
6596 (PendingThumbnailsRecord)receivers.get(i);
6597 pr.receiver.newThumbnail(
6598 task != null ? task.taskId : -1, thumbnail, description);
6599 if (pr.finished) {
6600 pr.receiver.finished();
6601 }
6602 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006603 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006604 }
6605 }
6606 }
6607 }
6608
6609 // =========================================================
6610 // CONTENT PROVIDERS
6611 // =========================================================
6612
Jeff Brown10e89712011-07-08 18:52:57 -07006613 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6614 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006616 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006617 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006618 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006619 } catch (RemoteException ex) {
6620 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006621 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006622 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6623 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006624 if (providers != null) {
6625 final int N = providers.size();
6626 for (int i=0; i<N; i++) {
6627 ProviderInfo cpi =
6628 (ProviderInfo)providers.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006629
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006630 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006631 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006632 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006633 cpr = new ContentProviderRecord(cpi, app.info, comp);
Amith Yamasani742a6712011-05-04 14:49:28 -07006634 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006635 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006636 if (DEBUG_MU)
6637 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006638 app.pubProviders.put(cpi.name, cpr);
6639 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006640 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 }
6642 }
6643 return providers;
6644 }
6645
6646 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006647 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006649 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006651 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006652 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 return null;
6654 }
6655 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006656 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006657 == PackageManager.PERMISSION_GRANTED) {
6658 return null;
6659 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006660
6661 PathPermission[] pps = cpi.pathPermissions;
6662 if (pps != null) {
6663 int i = pps.length;
6664 while (i > 0) {
6665 i--;
6666 PathPermission pp = pps[i];
6667 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006668 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006669 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006670 return null;
6671 }
6672 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006673 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006674 == PackageManager.PERMISSION_GRANTED) {
6675 return null;
6676 }
6677 }
6678 }
6679
Dianne Hackbornb424b632010-08-18 15:59:05 -07006680 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6681 if (perms != null) {
6682 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6683 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6684 return null;
6685 }
6686 }
6687 }
6688
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006689 String msg;
6690 if (!cpi.exported) {
6691 msg = "Permission Denial: opening provider " + cpi.name
6692 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6693 + ", uid=" + callingUid + ") that is not exported from uid "
6694 + cpi.applicationInfo.uid;
6695 } else {
6696 msg = "Permission Denial: opening provider " + cpi.name
6697 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6698 + ", uid=" + callingUid + ") requires "
6699 + cpi.readPermission + " or " + cpi.writePermission;
6700 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006701 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006702 return msg;
6703 }
6704
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006705 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6706 if (r != null) {
6707 Integer cnt = r.conProviders.get(cpr);
6708 if (DEBUG_PROVIDER) Slog.v(TAG,
6709 "Adding provider requested by "
6710 + r.processName + " from process "
6711 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6712 + " cnt=" + (cnt == null ? 1 : cnt));
6713 if (cnt == null) {
6714 cpr.clients.add(r);
6715 r.conProviders.put(cpr, new Integer(1));
6716 return true;
6717 } else {
6718 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
6719 }
6720 } else {
6721 cpr.externals++;
6722 }
6723 return false;
6724 }
6725
6726 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6727 if (r != null) {
6728 Integer cnt = r.conProviders.get(cpr);
6729 if (DEBUG_PROVIDER) Slog.v(TAG,
6730 "Removing provider requested by "
6731 + r.processName + " from process "
6732 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6733 + " cnt=" + cnt);
6734 if (cnt == null || cnt.intValue() <= 1) {
6735 cpr.clients.remove(r);
6736 r.conProviders.remove(cpr);
6737 return true;
6738 } else {
6739 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
6740 }
6741 } else {
6742 cpr.externals++;
6743 }
6744 return false;
6745 }
6746
Amith Yamasani742a6712011-05-04 14:49:28 -07006747 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6748 String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006749 ContentProviderRecord cpr;
6750 ProviderInfo cpi = null;
6751
6752 synchronized(this) {
6753 ProcessRecord r = null;
6754 if (caller != null) {
6755 r = getRecordForAppLocked(caller);
6756 if (r == null) {
6757 throw new SecurityException(
6758 "Unable to find app for caller " + caller
6759 + " (pid=" + Binder.getCallingPid()
6760 + ") when getting content provider " + name);
6761 }
6762 }
6763
6764 // First check if this content provider has been published...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006765 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
Amith Yamasani742a6712011-05-04 14:49:28 -07006766 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006767 boolean providerRunning = cpr != null;
6768 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006770 String msg;
6771 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6772 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006773 }
6774
6775 if (r != null && cpr.canRunHere(r)) {
6776 // This provider has been published or is in the process
6777 // of being published... but it is also allowed to run
6778 // in the caller's process, so don't make a connection
6779 // and just let the caller instantiate its own instance.
6780 if (cpr.provider != null) {
6781 // don't give caller the provider object, it needs
6782 // to make its own.
6783 cpr = new ContentProviderRecord(cpr);
6784 }
6785 return cpr;
6786 }
6787
6788 final long origId = Binder.clearCallingIdentity();
6789
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006790 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006792 final boolean countChanged = incProviderCount(r, cpr);
6793 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006794 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006795 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006796 // make sure to count it as being accessed and thus
6797 // back up on the LRU list. This is good because
6798 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006799 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006800 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006801 }
6802
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006803 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006804 if (false) {
6805 if (cpr.name.flattenToShortString().equals(
6806 "com.android.providers.calendar/.CalendarProvider2")) {
6807 Slog.v(TAG, "****************** KILLING "
6808 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006809 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006810 }
6811 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006812 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006813 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6814 // NOTE: there is still a race here where a signal could be
6815 // pending on the process even though we managed to update its
6816 // adj level. Not sure what to do about this, but at least
6817 // the race is now smaller.
6818 if (!success) {
6819 // Uh oh... it looks like the provider's process
6820 // has been killed on us. We need to wait for a new
6821 // process to be started, and make sure its death
6822 // doesn't kill our process.
6823 Slog.i(TAG,
6824 "Existing provider " + cpr.name.flattenToShortString()
6825 + " is crashing; detaching " + r);
6826 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006827 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006828 if (!lastRef) {
6829 // This wasn't the last ref our process had on
6830 // the provider... we have now been killed, bail.
6831 return null;
6832 }
6833 providerRunning = false;
6834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006835 }
6836
6837 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006840 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006841 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006842 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006843 resolveContentProvider(name,
6844 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 } catch (RemoteException ex) {
6846 }
6847 if (cpi == null) {
6848 return null;
6849 }
6850
Amith Yamasani742a6712011-05-04 14:49:28 -07006851 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo,
6852 Binder.getOrigCallingUser());
6853
Dianne Hackbornb424b632010-08-18 15:59:05 -07006854 String msg;
6855 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6856 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006857 }
6858
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006859 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006860 && !cpi.processName.equals("system")) {
6861 // If this content provider does not run in the system
6862 // process, and the system is not yet ready to run other
6863 // processes, then fail fast instead of hanging.
6864 throw new IllegalArgumentException(
6865 "Attempt to launch content provider before system ready");
6866 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006867
6868 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006869 cpr = mProviderMap.getProviderByClass(comp, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006870 final boolean firstClass = cpr == null;
6871 if (firstClass) {
6872 try {
6873 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006874 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 getApplicationInfo(
6876 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006877 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006878 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006879 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 + cpi.name);
6881 return null;
6882 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006883 ai = getAppInfoForUser(ai, Binder.getOrigCallingUser());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006884 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 } catch (RemoteException ex) {
6886 // pm is in same process, this will never happen.
6887 }
6888 }
6889
6890 if (r != null && cpr.canRunHere(r)) {
6891 // If this is a multiprocess provider, then just return its
6892 // info and allow the caller to instantiate it. Only do
6893 // this if the provider is the same user as the caller's
6894 // process, or can run as root (so can be in any process).
6895 return cpr;
6896 }
6897
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006898 if (DEBUG_PROVIDER) {
6899 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006900 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006901 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 }
6903
6904 // This is single process, and our app is now connecting to it.
6905 // See if we are already in the process of launching this
6906 // provider.
6907 final int N = mLaunchingProviders.size();
6908 int i;
6909 for (i=0; i<N; i++) {
6910 if (mLaunchingProviders.get(i) == cpr) {
6911 break;
6912 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006913 }
6914
6915 // If the provider is not already being launched, then get it
6916 // started.
6917 if (i >= N) {
6918 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006919
6920 try {
6921 // Content provider is now in use, its package can't be stopped.
6922 try {
6923 AppGlobals.getPackageManager().setPackageStoppedState(
6924 cpr.appInfo.packageName, false);
6925 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006926 } catch (IllegalArgumentException e) {
6927 Slog.w(TAG, "Failed trying to unstop package "
6928 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006929 }
6930
6931 ProcessRecord proc = startProcessLocked(cpi.processName,
6932 cpr.appInfo, false, 0, "content provider",
6933 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006934 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006935 if (proc == null) {
6936 Slog.w(TAG, "Unable to launch app "
6937 + cpi.applicationInfo.packageName + "/"
6938 + cpi.applicationInfo.uid + " for provider "
6939 + name + ": process is bad");
6940 return null;
6941 }
6942 cpr.launchingApp = proc;
6943 mLaunchingProviders.add(cpr);
6944 } finally {
6945 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006947 }
6948
6949 // Make sure the provider is published (the same provider class
6950 // may be published under multiple names).
6951 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006952 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006953 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006954 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006955 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 }
6957 }
6958
6959 // Wait for the provider to be published...
6960 synchronized (cpr) {
6961 while (cpr.provider == null) {
6962 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006963 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 + cpi.applicationInfo.packageName + "/"
6965 + cpi.applicationInfo.uid + " for provider "
6966 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006967 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 cpi.applicationInfo.packageName,
6969 cpi.applicationInfo.uid, name);
6970 return null;
6971 }
6972 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006973 if (DEBUG_MU) {
6974 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6975 + cpr.launchingApp);
6976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 cpr.wait();
6978 } catch (InterruptedException ex) {
6979 }
6980 }
6981 }
6982 return cpr;
6983 }
6984
6985 public final ContentProviderHolder getContentProvider(
6986 IApplicationThread caller, String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006987 enforceNotIsolatedCaller("getContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 if (caller == null) {
6989 String msg = "null IApplicationThread when getting content provider "
6990 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006991 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006992 throw new SecurityException(msg);
6993 }
6994
Amith Yamasani742a6712011-05-04 14:49:28 -07006995 ContentProviderHolder contentProvider = getContentProviderImpl(caller, name);
6996 return contentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006997 }
6998
6999 private ContentProviderHolder getContentProviderExternal(String name) {
7000 return getContentProviderImpl(null, name);
7001 }
7002
7003 /**
7004 * Drop a content provider from a ProcessRecord's bookkeeping
7005 * @param cpr
7006 */
7007 public void removeContentProvider(IApplicationThread caller, String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007008 enforceNotIsolatedCaller("removeContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007010 int userId = UserId.getUserId(Binder.getCallingUid());
7011 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007012 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07007013 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08007014 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07007015 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007016 return;
7017 }
7018 final ProcessRecord r = getRecordForAppLocked(caller);
7019 if (r == null) {
7020 throw new SecurityException(
7021 "Unable to find app for caller " + caller +
7022 " when removing content provider " + name);
7023 }
7024 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007025 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007026 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7027 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
7028 + r.info.processName + " from process "
7029 + localCpr.appInfo.processName);
7030 if (localCpr.launchingApp == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08007032 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07007033 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007034 return;
7035 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07007036 if (decProviderCount(r, localCpr)) {
7037 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07007038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 }
7041 }
7042
7043 private void removeContentProviderExternal(String name) {
7044 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007045 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
7046 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007047 if(cpr == null) {
7048 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08007049 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 return;
7051 }
7052
7053 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007054 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007055 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
7056 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 localCpr.externals--;
7058 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007059 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 }
7061 updateOomAdjLocked();
7062 }
7063 }
7064
7065 public final void publishContentProviders(IApplicationThread caller,
7066 List<ContentProviderHolder> providers) {
7067 if (providers == null) {
7068 return;
7069 }
7070
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007071 enforceNotIsolatedCaller("publishContentProviders");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007072 synchronized(this) {
7073 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07007074 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007075 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 if (r == null) {
7077 throw new SecurityException(
7078 "Unable to find app for caller " + caller
7079 + " (pid=" + Binder.getCallingPid()
7080 + ") when publishing content providers");
7081 }
7082
7083 final long origId = Binder.clearCallingIdentity();
7084
7085 final int N = providers.size();
7086 for (int i=0; i<N; i++) {
7087 ContentProviderHolder src = providers.get(i);
7088 if (src == null || src.info == null || src.provider == null) {
7089 continue;
7090 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07007091 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007092 if (DEBUG_MU)
7093 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007094 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007095 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007096 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007097 String names[] = dst.info.authority.split(";");
7098 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007099 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007100 }
7101
7102 int NL = mLaunchingProviders.size();
7103 int j;
7104 for (j=0; j<NL; j++) {
7105 if (mLaunchingProviders.get(j) == dst) {
7106 mLaunchingProviders.remove(j);
7107 j--;
7108 NL--;
7109 }
7110 }
7111 synchronized (dst) {
7112 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07007113 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007114 dst.notifyAll();
7115 }
7116 updateOomAdjLocked(r);
7117 }
7118 }
7119
7120 Binder.restoreCallingIdentity(origId);
7121 }
7122 }
7123
7124 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07007125 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06007126 synchronized (mSelf) {
7127 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7128 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08007129 if (providers != null) {
7130 for (int i=providers.size()-1; i>=0; i--) {
7131 ProviderInfo pi = (ProviderInfo)providers.get(i);
7132 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7133 Slog.w(TAG, "Not installing system proc provider " + pi.name
7134 + ": not system .apk");
7135 providers.remove(i);
7136 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08007137 }
7138 }
7139 }
Josh Bartel2ecce342010-02-25 10:55:48 -06007140 if (providers != null) {
7141 mSystemThread.installSystemProviders(providers);
7142 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08007143
7144 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01007145
7146 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007147 }
7148
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007149 /**
7150 * Allows app to retrieve the MIME type of a URI without having permission
7151 * to access its content provider.
7152 *
7153 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7154 *
7155 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7156 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7157 */
7158 public String getProviderMimeType(Uri uri) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007159 enforceNotIsolatedCaller("getProviderMimeType");
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007160 final String name = uri.getAuthority();
7161 final long ident = Binder.clearCallingIdentity();
7162 ContentProviderHolder holder = null;
7163
7164 try {
7165 holder = getContentProviderExternal(name);
7166 if (holder != null) {
7167 return holder.provider.getType(uri);
7168 }
7169 } catch (RemoteException e) {
7170 Log.w(TAG, "Content provider dead retrieving " + uri, e);
7171 return null;
7172 } finally {
7173 if (holder != null) {
7174 removeContentProviderExternal(name);
7175 }
7176 Binder.restoreCallingIdentity(ident);
7177 }
7178
7179 return null;
7180 }
7181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007182 // =========================================================
7183 // GLOBAL MANAGEMENT
7184 // =========================================================
7185
7186 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007187 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 String proc = customProcess != null ? customProcess : info.processName;
7189 BatteryStatsImpl.Uid.Proc ps = null;
7190 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007191 int uid = info.uid;
7192 if (isolated) {
7193 int userId = UserId.getUserId(uid);
7194 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7195 uid = 0;
7196 while (true) {
7197 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7198 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7199 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7200 }
7201 uid = UserId.getUid(userId, mNextIsolatedProcessUid);
7202 mNextIsolatedProcessUid++;
7203 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7204 // No process for this uid, use it.
7205 break;
7206 }
7207 stepsLeft--;
7208 if (stepsLeft <= 0) {
7209 return null;
7210 }
7211 }
7212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213 synchronized (stats) {
7214 ps = stats.getProcessStatsLocked(info.uid, proc);
7215 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007216 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007217 }
7218
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007219 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7220 ProcessRecord app;
7221 if (!isolated) {
7222 app = getProcessRecordLocked(info.processName, info.uid);
7223 } else {
7224 app = null;
7225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226
7227 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007228 app = newProcessRecordLocked(null, info, null, isolated);
7229 mProcessNames.put(info.processName, app.uid, app);
7230 if (isolated) {
7231 mIsolatedProcesses.put(app.uid, app);
7232 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007233 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007234 }
7235
Dianne Hackborne7f97212011-02-24 14:40:20 -08007236 // This package really, really can not be stopped.
7237 try {
7238 AppGlobals.getPackageManager().setPackageStoppedState(
7239 info.packageName, false);
7240 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08007241 } catch (IllegalArgumentException e) {
7242 Slog.w(TAG, "Failed trying to unstop package "
7243 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08007244 }
7245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007246 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7247 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7248 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007249 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007250 }
7251 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7252 mPersistentStartingProcesses.add(app);
7253 startProcessLocked(app, "added application", app.processName);
7254 }
7255
7256 return app;
7257 }
7258
7259 public void unhandledBack() {
7260 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7261 "unhandledBack()");
7262
7263 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007264 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007265 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007266 TAG, "Performing unhandledBack(): stack size = " + count);
7267 if (count > 1) {
7268 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007269 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7271 Binder.restoreCallingIdentity(origId);
7272 }
7273 }
7274 }
7275
7276 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007277 enforceNotIsolatedCaller("openContentUri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007278 String name = uri.getAuthority();
7279 ContentProviderHolder cph = getContentProviderExternal(name);
7280 ParcelFileDescriptor pfd = null;
7281 if (cph != null) {
7282 // We record the binder invoker's uid in thread-local storage before
7283 // going to the content provider to open the file. Later, in the code
7284 // that handles all permissions checks, we look for this uid and use
7285 // that rather than the Activity Manager's own uid. The effect is that
7286 // we do the check against the caller's permissions even though it looks
7287 // to the content provider like the Activity Manager itself is making
7288 // the request.
7289 sCallerIdentity.set(new Identity(
7290 Binder.getCallingPid(), Binder.getCallingUid()));
7291 try {
7292 pfd = cph.provider.openFile(uri, "r");
7293 } catch (FileNotFoundException e) {
7294 // do nothing; pfd will be returned null
7295 } finally {
7296 // Ensure that whatever happens, we clean up the identity state
7297 sCallerIdentity.remove();
7298 }
7299
7300 // We've got the fd now, so we're done with the provider.
7301 removeContentProviderExternal(name);
7302 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007303 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007304 }
7305 return pfd;
7306 }
7307
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007308 // Actually is sleeping or shutting down or whatever else in the future
7309 // is an inactive state.
7310 public boolean isSleeping() {
7311 return mSleeping || mShuttingDown;
7312 }
7313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007314 public void goingToSleep() {
7315 synchronized(this) {
7316 mSleeping = true;
7317 mWindowManager.setEventDispatching(false);
7318
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007319 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007320
7321 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07007322 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007323 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7324 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007325 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 }
7327 }
7328
Dianne Hackborn55280a92009-05-07 15:53:46 -07007329 public boolean shutdown(int timeout) {
7330 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7331 != PackageManager.PERMISSION_GRANTED) {
7332 throw new SecurityException("Requires permission "
7333 + android.Manifest.permission.SHUTDOWN);
7334 }
7335
7336 boolean timedout = false;
7337
7338 synchronized(this) {
7339 mShuttingDown = true;
7340 mWindowManager.setEventDispatching(false);
7341
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007342 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007343 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07007344 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007345 while (mMainStack.mResumedActivity != null
Dianne Hackborncbb722e2012-02-07 18:33:49 -08007346 || mMainStack.mPausingActivities.size() > 0) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07007347 long delay = endTime - System.currentTimeMillis();
7348 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007349 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07007350 timedout = true;
7351 break;
7352 }
7353 try {
7354 this.wait();
7355 } catch (InterruptedException e) {
7356 }
7357 }
7358 }
7359 }
7360
7361 mUsageStatsService.shutdown();
7362 mBatteryStatsService.shutdown();
7363
7364 return timedout;
7365 }
7366
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007367 public final void activitySlept(IBinder token) {
7368 if (localLOGV) Slog.v(
7369 TAG, "Activity slept: token=" + token);
7370
7371 ActivityRecord r = null;
7372
7373 final long origId = Binder.clearCallingIdentity();
7374
7375 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007376 r = mMainStack.isInStackLocked(token);
7377 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007378 mMainStack.activitySleptLocked(r);
7379 }
7380 }
7381
7382 Binder.restoreCallingIdentity(origId);
7383 }
7384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007385 public void wakingUp() {
7386 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007387 mWindowManager.setEventDispatching(true);
7388 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007389 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007390 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007391 }
7392 }
7393
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007394 public void stopAppSwitches() {
7395 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7396 != PackageManager.PERMISSION_GRANTED) {
7397 throw new SecurityException("Requires permission "
7398 + android.Manifest.permission.STOP_APP_SWITCHES);
7399 }
7400
7401 synchronized(this) {
7402 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7403 + APP_SWITCH_DELAY_TIME;
7404 mDidAppSwitch = false;
7405 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7406 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7407 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7408 }
7409 }
7410
7411 public void resumeAppSwitches() {
7412 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7413 != PackageManager.PERMISSION_GRANTED) {
7414 throw new SecurityException("Requires permission "
7415 + android.Manifest.permission.STOP_APP_SWITCHES);
7416 }
7417
7418 synchronized(this) {
7419 // Note that we don't execute any pending app switches... we will
7420 // let those wait until either the timeout, or the next start
7421 // activity request.
7422 mAppSwitchesAllowedTime = 0;
7423 }
7424 }
7425
7426 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7427 String name) {
7428 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7429 return true;
7430 }
7431
7432 final int perm = checkComponentPermission(
7433 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007434 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007435 if (perm == PackageManager.PERMISSION_GRANTED) {
7436 return true;
7437 }
7438
Joe Onorato8a9b2202010-02-26 18:56:32 -08007439 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007440 return false;
7441 }
7442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007443 public void setDebugApp(String packageName, boolean waitForDebugger,
7444 boolean persistent) {
7445 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7446 "setDebugApp()");
7447
7448 // Note that this is not really thread safe if there are multiple
7449 // callers into it at the same time, but that's not a situation we
7450 // care about.
7451 if (persistent) {
7452 final ContentResolver resolver = mContext.getContentResolver();
7453 Settings.System.putString(
7454 resolver, Settings.System.DEBUG_APP,
7455 packageName);
7456 Settings.System.putInt(
7457 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7458 waitForDebugger ? 1 : 0);
7459 }
7460
7461 synchronized (this) {
7462 if (!persistent) {
7463 mOrigDebugApp = mDebugApp;
7464 mOrigWaitForDebugger = mWaitForDebugger;
7465 }
7466 mDebugApp = packageName;
7467 mWaitForDebugger = waitForDebugger;
7468 mDebugTransient = !persistent;
7469 if (packageName != null) {
7470 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07007471 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007472 Binder.restoreCallingIdentity(origId);
7473 }
7474 }
7475 }
7476
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007477 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7478 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7479 synchronized (this) {
7480 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7481 if (!isDebuggable) {
7482 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7483 throw new SecurityException("Process not debuggable: " + app.packageName);
7484 }
7485 }
7486 mProfileApp = processName;
7487 mProfileFile = profileFile;
7488 if (mProfileFd != null) {
7489 try {
7490 mProfileFd.close();
7491 } catch (IOException e) {
7492 }
7493 mProfileFd = null;
7494 }
7495 mProfileFd = profileFd;
7496 mProfileType = 0;
7497 mAutoStopProfiler = autoStopProfiler;
7498 }
7499 }
7500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007501 public void setAlwaysFinish(boolean enabled) {
7502 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7503 "setAlwaysFinish()");
7504
7505 Settings.System.putInt(
7506 mContext.getContentResolver(),
7507 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7508
7509 synchronized (this) {
7510 mAlwaysFinishActivities = enabled;
7511 }
7512 }
7513
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007514 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007515 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007516 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007517 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007518 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 }
7520 }
7521
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007522 public boolean isUserAMonkey() {
7523 // For now the fact that there is a controller implies
7524 // we have a monkey.
7525 synchronized (this) {
7526 return mController != null;
7527 }
7528 }
7529
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007530 public void registerActivityWatcher(IActivityWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007531 enforceNotIsolatedCaller("registerActivityWatcher");
Josh Bartel2ecce342010-02-25 10:55:48 -06007532 synchronized (this) {
7533 mWatchers.register(watcher);
7534 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007535 }
7536
7537 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06007538 synchronized (this) {
7539 mWatchers.unregister(watcher);
7540 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007541 }
7542
Jeff Sharkeya4620792011-05-20 15:29:23 -07007543 public void registerProcessObserver(IProcessObserver observer) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007544 enforceNotIsolatedCaller("registerProcessObserver");
Jeff Sharkeya4620792011-05-20 15:29:23 -07007545 mProcessObservers.register(observer);
7546 }
7547
7548 public void unregisterProcessObserver(IProcessObserver observer) {
7549 mProcessObservers.unregister(observer);
7550 }
7551
Daniel Sandler69a48172010-06-23 16:29:36 -04007552 public void setImmersive(IBinder token, boolean immersive) {
7553 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007554 ActivityRecord r = mMainStack.isInStackLocked(token);
7555 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007556 throw new IllegalArgumentException();
7557 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007558 r.immersive = immersive;
7559 }
7560 }
7561
7562 public boolean isImmersive(IBinder token) {
7563 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007564 ActivityRecord r = mMainStack.isInStackLocked(token);
7565 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007566 throw new IllegalArgumentException();
7567 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007568 return r.immersive;
7569 }
7570 }
7571
7572 public boolean isTopActivityImmersive() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007573 enforceNotIsolatedCaller("startActivity");
Daniel Sandler69a48172010-06-23 16:29:36 -04007574 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007575 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007576 return (r != null) ? r.immersive : false;
7577 }
7578 }
7579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 public final void enterSafeMode() {
7581 synchronized(this) {
7582 // It only makes sense to do this before the system is ready
7583 // and started launching other packages.
7584 if (!mSystemReady) {
7585 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007586 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007587 } catch (RemoteException e) {
7588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 }
7590 }
7591 }
7592
Jeff Brownb09abc12011-01-13 21:08:27 -08007593 public final void showSafeModeOverlay() {
7594 View v = LayoutInflater.from(mContext).inflate(
7595 com.android.internal.R.layout.safe_mode, null);
7596 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7597 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7598 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7599 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7600 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7601 lp.format = v.getBackground().getOpacity();
7602 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7603 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7604 ((WindowManager)mContext.getSystemService(
7605 Context.WINDOW_SERVICE)).addView(v, lp);
7606 }
7607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007608 public void noteWakeupAlarm(IIntentSender sender) {
7609 if (!(sender instanceof PendingIntentRecord)) {
7610 return;
7611 }
7612 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7613 synchronized (stats) {
7614 if (mBatteryStatsService.isOnBattery()) {
7615 mBatteryStatsService.enforceCallingPermission();
7616 PendingIntentRecord rec = (PendingIntentRecord)sender;
7617 int MY_UID = Binder.getCallingUid();
7618 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7619 BatteryStatsImpl.Uid.Pkg pkg =
7620 stats.getPackageStatsLocked(uid, rec.key.packageName);
7621 pkg.incWakeupsLocked();
7622 }
7623 }
7624 }
7625
Dianne Hackborn64825172011-03-02 21:32:58 -08007626 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007627 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007628 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007630 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 // XXX Note: don't acquire main activity lock here, because the window
7632 // manager calls in with its locks held.
7633
7634 boolean killed = false;
7635 synchronized (mPidsSelfLocked) {
7636 int[] types = new int[pids.length];
7637 int worstType = 0;
7638 for (int i=0; i<pids.length; i++) {
7639 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7640 if (proc != null) {
7641 int type = proc.setAdj;
7642 types[i] = type;
7643 if (type > worstType) {
7644 worstType = type;
7645 }
7646 }
7647 }
7648
Dianne Hackborn64825172011-03-02 21:32:58 -08007649 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007650 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007651 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7652 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007653 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007654 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007655
7656 // If this is not a secure call, don't let it kill processes that
7657 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007658 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7659 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007660 }
7661
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007662 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007663 for (int i=0; i<pids.length; i++) {
7664 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7665 if (proc == null) {
7666 continue;
7667 }
7668 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007669 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007670 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007671 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7672 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007673 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007674 proc.killedBackground = true;
7675 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007676 }
7677 }
7678 }
7679 return killed;
7680 }
7681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 public final void startRunning(String pkg, String cls, String action,
7683 String data) {
7684 synchronized(this) {
7685 if (mStartRunning) {
7686 return;
7687 }
7688 mStartRunning = true;
7689 mTopComponent = pkg != null && cls != null
7690 ? new ComponentName(pkg, cls) : null;
7691 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7692 mTopData = data;
7693 if (!mSystemReady) {
7694 return;
7695 }
7696 }
7697
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007698 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699 }
7700
7701 private void retrieveSettings() {
7702 final ContentResolver resolver = mContext.getContentResolver();
7703 String debugApp = Settings.System.getString(
7704 resolver, Settings.System.DEBUG_APP);
7705 boolean waitForDebugger = Settings.System.getInt(
7706 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7707 boolean alwaysFinishActivities = Settings.System.getInt(
7708 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7709
7710 Configuration configuration = new Configuration();
7711 Settings.System.getConfiguration(resolver, configuration);
7712
7713 synchronized (this) {
7714 mDebugApp = mOrigDebugApp = debugApp;
7715 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7716 mAlwaysFinishActivities = alwaysFinishActivities;
7717 // This happens before any activities are started, so we can
7718 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007719 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007720 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007721 }
7722 }
7723
7724 public boolean testIsSystemReady() {
7725 // no need to synchronize(this) just to read & return the value
7726 return mSystemReady;
7727 }
7728
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007729 private static File getCalledPreBootReceiversFile() {
7730 File dataDir = Environment.getDataDirectory();
7731 File systemDir = new File(dataDir, "system");
7732 File fname = new File(systemDir, "called_pre_boots.dat");
7733 return fname;
7734 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007735
7736 static final int LAST_DONE_VERSION = 10000;
7737
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007738 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7739 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7740 File file = getCalledPreBootReceiversFile();
7741 FileInputStream fis = null;
7742 try {
7743 fis = new FileInputStream(file);
7744 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007745 int fvers = dis.readInt();
7746 if (fvers == LAST_DONE_VERSION) {
7747 String vers = dis.readUTF();
7748 String codename = dis.readUTF();
7749 String build = dis.readUTF();
7750 if (android.os.Build.VERSION.RELEASE.equals(vers)
7751 && android.os.Build.VERSION.CODENAME.equals(codename)
7752 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7753 int num = dis.readInt();
7754 while (num > 0) {
7755 num--;
7756 String pkg = dis.readUTF();
7757 String cls = dis.readUTF();
7758 lastDoneReceivers.add(new ComponentName(pkg, cls));
7759 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007760 }
7761 }
7762 } catch (FileNotFoundException e) {
7763 } catch (IOException e) {
7764 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7765 } finally {
7766 if (fis != null) {
7767 try {
7768 fis.close();
7769 } catch (IOException e) {
7770 }
7771 }
7772 }
7773 return lastDoneReceivers;
7774 }
7775
7776 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7777 File file = getCalledPreBootReceiversFile();
7778 FileOutputStream fos = null;
7779 DataOutputStream dos = null;
7780 try {
7781 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7782 fos = new FileOutputStream(file);
7783 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007784 dos.writeInt(LAST_DONE_VERSION);
7785 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007786 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007787 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007788 dos.writeInt(list.size());
7789 for (int i=0; i<list.size(); i++) {
7790 dos.writeUTF(list.get(i).getPackageName());
7791 dos.writeUTF(list.get(i).getClassName());
7792 }
7793 } catch (IOException e) {
7794 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7795 file.delete();
7796 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007797 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007798 if (dos != null) {
7799 try {
7800 dos.close();
7801 } catch (IOException e) {
7802 // TODO Auto-generated catch block
7803 e.printStackTrace();
7804 }
7805 }
7806 }
7807 }
7808
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007809 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007810 synchronized(this) {
7811 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007812 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007813 return;
7814 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007815
7816 // Check to see if there are any update receivers to run.
7817 if (!mDidUpdate) {
7818 if (mWaitingUpdate) {
7819 return;
7820 }
7821 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7822 List<ResolveInfo> ris = null;
7823 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007824 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007825 intent, null, 0);
7826 } catch (RemoteException e) {
7827 }
7828 if (ris != null) {
7829 for (int i=ris.size()-1; i>=0; i--) {
7830 if ((ris.get(i).activityInfo.applicationInfo.flags
7831 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7832 ris.remove(i);
7833 }
7834 }
7835 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007836
7837 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7838
7839 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007840 for (int i=0; i<ris.size(); i++) {
7841 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007842 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7843 if (lastDoneReceivers.contains(comp)) {
7844 ris.remove(i);
7845 i--;
7846 }
7847 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007848
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007849 for (int i=0; i<ris.size(); i++) {
7850 ActivityInfo ai = ris.get(i).activityInfo;
7851 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7852 doneReceivers.add(comp);
7853 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007854 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08007855 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007856 finisher = new IIntentReceiver.Stub() {
7857 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07007858 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007859 boolean sticky) {
7860 // The raw IIntentReceiver interface is called
7861 // with the AM lock held, so redispatch to
7862 // execute our code without the lock.
7863 mHandler.post(new Runnable() {
7864 public void run() {
7865 synchronized (ActivityManagerService.this) {
7866 mDidUpdate = true;
7867 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007868 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007869 showBootMessage(mContext.getText(
7870 R.string.android_upgrading_complete),
7871 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007872 systemReady(goingCallback);
7873 }
7874 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007875 }
7876 };
7877 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007878 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Amith Yamasani742a6712011-05-04 14:49:28 -07007879 /* TODO: Send this to all users */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007880 broadcastIntentLocked(null, null, intent, null, finisher,
Amith Yamasani742a6712011-05-04 14:49:28 -07007881 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7882 Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08007883 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007884 mWaitingUpdate = true;
7885 }
7886 }
7887 }
7888 if (mWaitingUpdate) {
7889 return;
7890 }
7891 mDidUpdate = true;
7892 }
7893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 mSystemReady = true;
7895 if (!mStartRunning) {
7896 return;
7897 }
7898 }
7899
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007900 ArrayList<ProcessRecord> procsToKill = null;
7901 synchronized(mPidsSelfLocked) {
7902 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7903 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7904 if (!isAllowedWhileBooting(proc.info)){
7905 if (procsToKill == null) {
7906 procsToKill = new ArrayList<ProcessRecord>();
7907 }
7908 procsToKill.add(proc);
7909 }
7910 }
7911 }
7912
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007913 synchronized(this) {
7914 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007915 for (int i=procsToKill.size()-1; i>=0; i--) {
7916 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007917 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007918 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007919 }
7920 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007921
7922 // Now that we have cleaned up any update processes, we
7923 // are ready to start launching real processes and know that
7924 // we won't trample on them any more.
7925 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007926 }
7927
Joe Onorato8a9b2202010-02-26 18:56:32 -08007928 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007929 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007930 SystemClock.uptimeMillis());
7931
7932 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007933 // Make sure we have no pre-ready processes sitting around.
7934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7936 ResolveInfo ri = mContext.getPackageManager()
7937 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007938 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939 CharSequence errorMsg = null;
7940 if (ri != null) {
7941 ActivityInfo ai = ri.activityInfo;
7942 ApplicationInfo app = ai.applicationInfo;
7943 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7944 mTopAction = Intent.ACTION_FACTORY_TEST;
7945 mTopData = null;
7946 mTopComponent = new ComponentName(app.packageName,
7947 ai.name);
7948 } else {
7949 errorMsg = mContext.getResources().getText(
7950 com.android.internal.R.string.factorytest_not_system);
7951 }
7952 } else {
7953 errorMsg = mContext.getResources().getText(
7954 com.android.internal.R.string.factorytest_no_action);
7955 }
7956 if (errorMsg != null) {
7957 mTopAction = null;
7958 mTopData = null;
7959 mTopComponent = null;
7960 Message msg = Message.obtain();
7961 msg.what = SHOW_FACTORY_ERROR_MSG;
7962 msg.getData().putCharSequence("msg", errorMsg);
7963 mHandler.sendMessage(msg);
7964 }
7965 }
7966 }
7967
7968 retrieveSettings();
7969
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007970 if (goingCallback != null) goingCallback.run();
7971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007972 synchronized (this) {
7973 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7974 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007975 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007976 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007977 if (apps != null) {
7978 int N = apps.size();
7979 int i;
7980 for (i=0; i<N; i++) {
7981 ApplicationInfo info
7982 = (ApplicationInfo)apps.get(i);
7983 if (info != null &&
7984 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007985 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 }
7987 }
7988 }
7989 } catch (RemoteException ex) {
7990 // pm is in same process, this will never happen.
7991 }
7992 }
7993
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007994 // Start up initial activity.
7995 mBooting = true;
7996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007997 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007998 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007999 Message msg = Message.obtain();
8000 msg.what = SHOW_UID_ERROR_MSG;
8001 mHandler.sendMessage(msg);
8002 }
8003 } catch (RemoteException e) {
8004 }
8005
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008006 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008007 }
8008 }
8009
Dan Egnorb7f03672009-12-09 16:22:32 -08008010 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008011 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08008013 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08008014 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008015 startAppProblemLocked(app);
8016 app.stopFreezingAllLocked();
8017 return handleAppCrashLocked(app);
8018 }
8019
Dan Egnorb7f03672009-12-09 16:22:32 -08008020 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008021 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008022 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08008023 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08008024 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8025 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 startAppProblemLocked(app);
8027 app.stopFreezingAllLocked();
8028 }
8029
8030 /**
8031 * Generate a process error record, suitable for attachment to a ProcessRecord.
8032 *
8033 * @param app The ProcessRecord in which the error occurred.
8034 * @param condition Crashing, Application Not Responding, etc. Values are defined in
8035 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08008036 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 * @param shortMsg Short message describing the crash.
8038 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08008039 * @param stackTrace Full crash stack trace, may be null.
8040 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008041 * @return Returns a fully-formed AppErrorStateInfo record.
8042 */
8043 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008044 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008045 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08008046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 report.condition = condition;
8048 report.processName = app.processName;
8049 report.pid = app.pid;
8050 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08008051 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008052 report.shortMsg = shortMsg;
8053 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08008054 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055
8056 return report;
8057 }
8058
Dan Egnor42471dd2010-01-07 17:25:22 -08008059 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008060 synchronized (this) {
8061 app.crashing = false;
8062 app.crashingReport = null;
8063 app.notResponding = false;
8064 app.notRespondingReport = null;
8065 if (app.anrDialog == fromDialog) {
8066 app.anrDialog = null;
8067 }
8068 if (app.waitDialog == fromDialog) {
8069 app.waitDialog = null;
8070 }
8071 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08008072 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008073 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07008074 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
8075 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008076 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008078 }
8079 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008080
Dan Egnorb7f03672009-12-09 16:22:32 -08008081 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008082 long now = SystemClock.uptimeMillis();
8083
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008084 Long crashTime;
8085 if (!app.isolated) {
8086 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8087 } else {
8088 crashTime = null;
8089 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07008090 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008092 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008093 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08008094 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008095 app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008096 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8097 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008099 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008101 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008102 }
8103 }
8104 if (!app.persistent) {
8105 // We don't want to start this process again until the user
8106 // explicitly does so... but for persistent process, we really
8107 // need to keep it running. If a persistent process is actually
8108 // repeatedly crashing, then badness for everyone.
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008109 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008111 if (!app.isolated) {
8112 // XXX We don't have a way to mark isolated processes
8113 // as bad, since they don't have a peristent identity.
8114 mBadProcesses.put(app.info.processName, app.uid, now);
8115 mProcessCrashTimes.remove(app.info.processName, app.uid);
8116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008118 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07008119 // Don't let services in this process be restarted and potentially
8120 // annoy the user repeatedly. Unless it is persistent, since those
8121 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08008122 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08008123 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008124 return false;
8125 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08008126 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008127 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008128 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008129 if (r.app == app) {
8130 // If the top running activity is from this crashing
8131 // process, then terminate it to avoid getting in a loop.
8132 Slog.w(TAG, " Force finishing activity "
8133 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08008134 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008135 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008136 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08008137 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008138 // stopped, to avoid a situation where one will get
8139 // re-start our crashing activity once it gets resumed again.
8140 index--;
8141 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008142 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008143 if (r.state == ActivityState.RESUMED
8144 || r.state == ActivityState.PAUSING
8145 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008146 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008147 Slog.w(TAG, " Force finishing activity "
8148 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008149 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008150 Activity.RESULT_CANCELED, null, "crashed");
8151 }
8152 }
8153 }
8154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 }
8156
8157 // Bump up the crash count of any services currently running in the proc.
8158 if (app.services.size() != 0) {
8159 // Any services running in the application need to be placed
8160 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008161 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008162 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008163 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164 sr.crashCount++;
8165 }
8166 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02008167
8168 // If the crashing process is what we consider to be the "home process" and it has been
8169 // replaced by a third-party app, clear the package preferred activities from packages
8170 // with a home activity running in the process to prevent a repeatedly crashing app
8171 // from blocking the user to manually clear the list.
8172 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8173 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8174 Iterator it = mHomeProcess.activities.iterator();
8175 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07008176 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02008177 if (r.isHomeActivity) {
8178 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8179 try {
8180 ActivityThread.getPackageManager()
8181 .clearPackagePreferredActivities(r.packageName);
8182 } catch (RemoteException c) {
8183 // pm is in same process, this will never happen.
8184 }
8185 }
8186 }
8187 }
8188
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008189 if (!app.isolated) {
8190 // XXX Can't keep track of crash times for isolated processes,
8191 // because they don't have a perisistent identity.
8192 mProcessCrashTimes.put(app.info.processName, app.uid, now);
8193 }
8194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008195 return true;
8196 }
8197
8198 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08008199 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8200 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201 skipCurrentReceiverLocked(app);
8202 }
8203
8204 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08008205 for (BroadcastQueue queue : mBroadcastQueues) {
8206 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008207 }
8208 }
8209
Dan Egnor60d87622009-12-16 16:32:58 -08008210 /**
8211 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8212 * The application process will exit immediately after this call returns.
8213 * @param app object of the crashing app, null for the system server
8214 * @param crashInfo describing the exception
8215 */
8216 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008217 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008218 final String processName = app == null ? "system_server"
8219 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008220
8221 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008222 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008223 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008224 crashInfo.exceptionClassName,
8225 crashInfo.exceptionMessage,
8226 crashInfo.throwFileName,
8227 crashInfo.throwLineNumber);
8228
Jeff Sharkeya353d262011-10-28 11:12:06 -07008229 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008230
8231 crashApplication(r, crashInfo);
8232 }
8233
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008234 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008235 IBinder app,
8236 int violationMask,
8237 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008238 ProcessRecord r = findAppProcess(app, "StrictMode");
8239 if (r == null) {
8240 return;
8241 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008242
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008243 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08008244 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008245 boolean logIt = true;
8246 synchronized (mAlreadyLoggedViolatedStacks) {
8247 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8248 logIt = false;
8249 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008250 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008251 // the relative pain numbers, without logging all
8252 // the stack traces repeatedly. We'd want to do
8253 // likewise in the client code, which also does
8254 // dup suppression, before the Binder call.
8255 } else {
8256 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8257 mAlreadyLoggedViolatedStacks.clear();
8258 }
8259 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8260 }
8261 }
8262 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008263 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008264 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008265 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008266
8267 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8268 AppErrorResult result = new AppErrorResult();
8269 synchronized (this) {
8270 final long origId = Binder.clearCallingIdentity();
8271
8272 Message msg = Message.obtain();
8273 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8274 HashMap<String, Object> data = new HashMap<String, Object>();
8275 data.put("result", result);
8276 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008277 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008278 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008279 msg.obj = data;
8280 mHandler.sendMessage(msg);
8281
8282 Binder.restoreCallingIdentity(origId);
8283 }
8284 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07008285 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008286 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008287 }
8288
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008289 // Depending on the policy in effect, there could be a bunch of
8290 // these in quick succession so we try to batch these together to
8291 // minimize disk writes, number of dropbox entries, and maximize
8292 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008293 private void logStrictModeViolationToDropBox(
8294 ProcessRecord process,
8295 StrictMode.ViolationInfo info) {
8296 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008297 return;
8298 }
8299 final boolean isSystemApp = process == null ||
8300 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8301 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008302 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008303 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8304 final DropBoxManager dbox = (DropBoxManager)
8305 mContext.getSystemService(Context.DROPBOX_SERVICE);
8306
8307 // Exit early if the dropbox isn't configured to accept this report type.
8308 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8309
8310 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008311 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008312 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8313 synchronized (sb) {
8314 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008315 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008316 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8317 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008318 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8319 if (info.violationNumThisLoop != 0) {
8320 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8321 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07008322 if (info.numAnimationsRunning != 0) {
8323 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8324 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07008325 if (info.broadcastIntentAction != null) {
8326 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8327 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008328 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008329 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008330 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08008331 if (info.numInstances != -1) {
8332 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8333 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008334 if (info.tags != null) {
8335 for (String tag : info.tags) {
8336 sb.append("Span-Tag: ").append(tag).append("\n");
8337 }
8338 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008339 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008340 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8341 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008342 }
8343 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008344
8345 // Only buffer up to ~64k. Various logging bits truncate
8346 // things at 128k.
8347 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008348 }
8349
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008350 // Flush immediately if the buffer's grown too large, or this
8351 // is a non-system app. Non-system apps are isolated with a
8352 // different tag & policy and not batched.
8353 //
8354 // Batching is useful during internal testing with
8355 // StrictMode settings turned up high. Without batching,
8356 // thousands of separate files could be created on boot.
8357 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008358 new Thread("Error dump: " + dropboxTag) {
8359 @Override
8360 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008361 String report;
8362 synchronized (sb) {
8363 report = sb.toString();
8364 sb.delete(0, sb.length());
8365 sb.trimToSize();
8366 }
8367 if (report.length() != 0) {
8368 dbox.addText(dropboxTag, report);
8369 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008370 }
8371 }.start();
8372 return;
8373 }
8374
8375 // System app batching:
8376 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008377 // An existing dropbox-writing thread is outstanding, so
8378 // we don't need to start it up. The existing thread will
8379 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008380 return;
8381 }
8382
8383 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8384 // (After this point, we shouldn't access AMS internal data structures.)
8385 new Thread("Error dump: " + dropboxTag) {
8386 @Override
8387 public void run() {
8388 // 5 second sleep to let stacks arrive and be batched together
8389 try {
8390 Thread.sleep(5000); // 5 seconds
8391 } catch (InterruptedException e) {}
8392
8393 String errorReport;
8394 synchronized (mStrictModeBuffer) {
8395 errorReport = mStrictModeBuffer.toString();
8396 if (errorReport.length() == 0) {
8397 return;
8398 }
8399 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8400 mStrictModeBuffer.trimToSize();
8401 }
8402 dbox.addText(dropboxTag, errorReport);
8403 }
8404 }.start();
8405 }
8406
Dan Egnor60d87622009-12-16 16:32:58 -08008407 /**
8408 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8409 * @param app object of the crashing app, null for the system server
8410 * @param tag reported by the caller
8411 * @param crashInfo describing the context of the error
8412 * @return true if the process should exit immediately (WTF is fatal)
8413 */
8414 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008415 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008416 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008417 final String processName = app == null ? "system_server"
8418 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008419
8420 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008421 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008422 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008423 tag, crashInfo.exceptionMessage);
8424
Jeff Sharkeya353d262011-10-28 11:12:06 -07008425 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008426
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008427 if (r != null && r.pid != Process.myPid() &&
8428 Settings.Secure.getInt(mContext.getContentResolver(),
8429 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008430 crashApplication(r, crashInfo);
8431 return true;
8432 } else {
8433 return false;
8434 }
8435 }
8436
8437 /**
8438 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8439 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8440 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008441 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008442 if (app == null) {
8443 return null;
8444 }
8445
8446 synchronized (this) {
8447 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8448 final int NA = apps.size();
8449 for (int ia=0; ia<NA; ia++) {
8450 ProcessRecord p = apps.valueAt(ia);
8451 if (p.thread != null && p.thread.asBinder() == app) {
8452 return p;
8453 }
8454 }
8455 }
8456
Dianne Hackborncb44d962011-03-10 17:02:27 -08008457 Slog.w(TAG, "Can't find mystery application for " + reason
8458 + " from pid=" + Binder.getCallingPid()
8459 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008460 return null;
8461 }
8462 }
8463
8464 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008465 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8466 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008467 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008468 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8469 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008470 // Watchdog thread ends up invoking this function (with
8471 // a null ProcessRecord) to add the stack file to dropbox.
8472 // Do not acquire a lock on this (am) in such cases, as it
8473 // could cause a potential deadlock, if and when watchdog
8474 // is invoked due to unavailability of lock on am and it
8475 // would prevent watchdog from killing system_server.
8476 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008477 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008478 return;
8479 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008480 // Note: ProcessRecord 'process' is guarded by the service
8481 // instance. (notably process.pkgList, which could otherwise change
8482 // concurrently during execution of this method)
8483 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008484 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008485 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008486 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008487 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8488 for (String pkg : process.pkgList) {
8489 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008490 try {
Dan Egnora455d192010-03-12 08:52:28 -08008491 PackageInfo pi = pm.getPackageInfo(pkg, 0);
8492 if (pi != null) {
8493 sb.append(" v").append(pi.versionCode);
8494 if (pi.versionName != null) {
8495 sb.append(" (").append(pi.versionName).append(")");
8496 }
8497 }
8498 } catch (RemoteException e) {
8499 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008500 }
Dan Egnora455d192010-03-12 08:52:28 -08008501 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008502 }
Dan Egnora455d192010-03-12 08:52:28 -08008503 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008504 }
8505
8506 private static String processClass(ProcessRecord process) {
8507 if (process == null || process.pid == MY_PID) {
8508 return "system_server";
8509 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8510 return "system_app";
8511 } else {
8512 return "data_app";
8513 }
8514 }
8515
8516 /**
8517 * Write a description of an error (crash, WTF, ANR) to the drop box.
8518 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8519 * @param process which caused the error, null means the system server
8520 * @param activity which triggered the error, null if unknown
8521 * @param parent activity related to the error, null if unknown
8522 * @param subject line related to the error, null if absent
8523 * @param report in long form describing the error, null if absent
8524 * @param logFile to include in the report, null if none
8525 * @param crashInfo giving an application stack trace, null if absent
8526 */
8527 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008528 ProcessRecord process, String processName, ActivityRecord activity,
8529 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008530 final String report, final File logFile,
8531 final ApplicationErrorReport.CrashInfo crashInfo) {
8532 // NOTE -- this must never acquire the ActivityManagerService lock,
8533 // otherwise the watchdog may be prevented from resetting the system.
8534
8535 final String dropboxTag = processClass(process) + "_" + eventType;
8536 final DropBoxManager dbox = (DropBoxManager)
8537 mContext.getSystemService(Context.DROPBOX_SERVICE);
8538
8539 // Exit early if the dropbox isn't configured to accept this report type.
8540 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8541
8542 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008543 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008544 if (activity != null) {
8545 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8546 }
8547 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8548 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8549 }
8550 if (parent != null && parent != activity) {
8551 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8552 }
8553 if (subject != null) {
8554 sb.append("Subject: ").append(subject).append("\n");
8555 }
8556 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008557 if (Debug.isDebuggerConnected()) {
8558 sb.append("Debugger: Connected\n");
8559 }
Dan Egnora455d192010-03-12 08:52:28 -08008560 sb.append("\n");
8561
8562 // Do the rest in a worker thread to avoid blocking the caller on I/O
8563 // (After this point, we shouldn't access AMS internal data structures.)
8564 Thread worker = new Thread("Error dump: " + dropboxTag) {
8565 @Override
8566 public void run() {
8567 if (report != null) {
8568 sb.append(report);
8569 }
8570 if (logFile != null) {
8571 try {
8572 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8573 } catch (IOException e) {
8574 Slog.e(TAG, "Error reading " + logFile, e);
8575 }
8576 }
8577 if (crashInfo != null && crashInfo.stackTrace != null) {
8578 sb.append(crashInfo.stackTrace);
8579 }
8580
8581 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8582 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8583 if (lines > 0) {
8584 sb.append("\n");
8585
8586 // Merge several logcat streams, and take the last N lines
8587 InputStreamReader input = null;
8588 try {
8589 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8590 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8591 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8592
8593 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8594 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8595 input = new InputStreamReader(logcat.getInputStream());
8596
8597 int num;
8598 char[] buf = new char[8192];
8599 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8600 } catch (IOException e) {
8601 Slog.e(TAG, "Error running logcat", e);
8602 } finally {
8603 if (input != null) try { input.close(); } catch (IOException e) {}
8604 }
8605 }
8606
8607 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008608 }
Dan Egnora455d192010-03-12 08:52:28 -08008609 };
8610
8611 if (process == null || process.pid == MY_PID) {
8612 worker.run(); // We may be about to die -- need to run this synchronously
8613 } else {
8614 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008615 }
8616 }
8617
8618 /**
8619 * Bring up the "unexpected error" dialog box for a crashing app.
8620 * Deal with edge cases (intercepts from instrumented applications,
8621 * ActivityController, error intent receivers, that sort of thing).
8622 * @param r the application crashing
8623 * @param crashInfo describing the failure
8624 */
8625 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008626 long timeMillis = System.currentTimeMillis();
8627 String shortMsg = crashInfo.exceptionClassName;
8628 String longMsg = crashInfo.exceptionMessage;
8629 String stackTrace = crashInfo.stackTrace;
8630 if (shortMsg != null && longMsg != null) {
8631 longMsg = shortMsg + ": " + longMsg;
8632 } else if (shortMsg != null) {
8633 longMsg = shortMsg;
8634 }
8635
Dan Egnor60d87622009-12-16 16:32:58 -08008636 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008638 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008639 try {
8640 String name = r != null ? r.processName : null;
8641 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008642 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008643 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008644 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008645 + " at watcher's request");
8646 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008647 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008648 }
8649 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008650 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008651 }
8652 }
8653
8654 final long origId = Binder.clearCallingIdentity();
8655
8656 // If this process is running instrumentation, finish it.
8657 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008658 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008659 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008660 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8661 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008662 Bundle info = new Bundle();
8663 info.putString("shortMsg", shortMsg);
8664 info.putString("longMsg", longMsg);
8665 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8666 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008667 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008668 }
8669
Dan Egnor60d87622009-12-16 16:32:58 -08008670 // If we can't identify the process or it's already exceeded its crash quota,
8671 // quit right away without showing a crash dialog.
8672 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008673 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008674 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008675 }
8676
8677 Message msg = Message.obtain();
8678 msg.what = SHOW_ERROR_MSG;
8679 HashMap data = new HashMap();
8680 data.put("result", result);
8681 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008682 msg.obj = data;
8683 mHandler.sendMessage(msg);
8684
8685 Binder.restoreCallingIdentity(origId);
8686 }
8687
8688 int res = result.get();
8689
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008690 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008691 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008692 if (r != null && !r.isolated) {
8693 // XXX Can't keep track of crash time for isolated processes,
8694 // since they don't have a persistent identity.
8695 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008696 SystemClock.uptimeMillis());
8697 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008698 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008699 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008700 }
8701 }
8702
8703 if (appErrorIntent != null) {
8704 try {
8705 mContext.startActivity(appErrorIntent);
8706 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008707 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008710 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008711
8712 Intent createAppErrorIntentLocked(ProcessRecord r,
8713 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8714 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008715 if (report == null) {
8716 return null;
8717 }
8718 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8719 result.setComponent(r.errorReportReceiver);
8720 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8721 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8722 return result;
8723 }
8724
Dan Egnorb7f03672009-12-09 16:22:32 -08008725 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8726 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008727 if (r.errorReportReceiver == null) {
8728 return null;
8729 }
8730
8731 if (!r.crashing && !r.notResponding) {
8732 return null;
8733 }
8734
Dan Egnorb7f03672009-12-09 16:22:32 -08008735 ApplicationErrorReport report = new ApplicationErrorReport();
8736 report.packageName = r.info.packageName;
8737 report.installerPackageName = r.errorReportReceiver.getPackageName();
8738 report.processName = r.processName;
8739 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008740 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008741
Dan Egnorb7f03672009-12-09 16:22:32 -08008742 if (r.crashing) {
8743 report.type = ApplicationErrorReport.TYPE_CRASH;
8744 report.crashInfo = crashInfo;
8745 } else if (r.notResponding) {
8746 report.type = ApplicationErrorReport.TYPE_ANR;
8747 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008748
Dan Egnorb7f03672009-12-09 16:22:32 -08008749 report.anrInfo.activity = r.notRespondingReport.tag;
8750 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8751 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008752 }
8753
Dan Egnorb7f03672009-12-09 16:22:32 -08008754 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008755 }
8756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008757 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008758 enforceNotIsolatedCaller("getProcessesInErrorState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 // assume our apps are happy - lazy create the list
8760 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8761
8762 synchronized (this) {
8763
8764 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008765 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8766 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008767 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8768 // This one's in trouble, so we'll generate a report for it
8769 // crashes are higher priority (in case there's a crash *and* an anr)
8770 ActivityManager.ProcessErrorStateInfo report = null;
8771 if (app.crashing) {
8772 report = app.crashingReport;
8773 } else if (app.notResponding) {
8774 report = app.notRespondingReport;
8775 }
8776
8777 if (report != null) {
8778 if (errList == null) {
8779 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8780 }
8781 errList.add(report);
8782 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008783 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008784 " crashing = " + app.crashing +
8785 " notResponding = " + app.notResponding);
8786 }
8787 }
8788 }
8789 }
8790
8791 return errList;
8792 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008793
8794 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008795 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008796 if (currApp != null) {
8797 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8798 }
8799 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008800 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8801 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008802 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8803 if (currApp != null) {
8804 currApp.lru = 0;
8805 }
8806 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008807 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008808 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8809 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8810 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8811 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8812 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8813 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8814 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8815 } else {
8816 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8817 }
8818 }
8819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008820 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008821 enforceNotIsolatedCaller("getRunningAppProcesses");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008822 // Lazy instantiation of list
8823 List<ActivityManager.RunningAppProcessInfo> runList = null;
8824 synchronized (this) {
8825 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008826 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8827 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8829 // Generate process state info for running application
8830 ActivityManager.RunningAppProcessInfo currApp =
8831 new ActivityManager.RunningAppProcessInfo(app.processName,
8832 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07008833 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008834 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07008835 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008836 }
Dianne Hackborn42499172010-10-15 18:45:07 -07008837 if (app.persistent) {
8838 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008840 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008841 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008842 currApp.importanceReasonCode = app.adjTypeCode;
8843 if (app.adjSource instanceof ProcessRecord) {
8844 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008845 currApp.importanceReasonImportance = oomAdjToImportance(
8846 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008847 } else if (app.adjSource instanceof ActivityRecord) {
8848 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008849 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8850 }
8851 if (app.adjTarget instanceof ComponentName) {
8852 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8853 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008854 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008855 // + " lru=" + currApp.lru);
8856 if (runList == null) {
8857 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8858 }
8859 runList.add(currApp);
8860 }
8861 }
8862 }
8863 return runList;
8864 }
8865
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008866 public List<ApplicationInfo> getRunningExternalApplications() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008867 enforceNotIsolatedCaller("getRunningExternalApplications");
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008868 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8869 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8870 if (runningApps != null && runningApps.size() > 0) {
8871 Set<String> extList = new HashSet<String>();
8872 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8873 if (app.pkgList != null) {
8874 for (String pkg : app.pkgList) {
8875 extList.add(pkg);
8876 }
8877 }
8878 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008879 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008880 for (String pkg : extList) {
8881 try {
8882 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
8883 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8884 retList.add(info);
8885 }
8886 } catch (RemoteException e) {
8887 }
8888 }
8889 }
8890 return retList;
8891 }
8892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008893 @Override
8894 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008895 if (checkCallingPermission(android.Manifest.permission.DUMP)
8896 != PackageManager.PERMISSION_GRANTED) {
8897 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8898 + Binder.getCallingPid()
8899 + ", uid=" + Binder.getCallingUid()
8900 + " without permission "
8901 + android.Manifest.permission.DUMP);
8902 return;
8903 }
8904
8905 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008906 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008907 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008908
8909 int opti = 0;
8910 while (opti < args.length) {
8911 String opt = args[opti];
8912 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8913 break;
8914 }
8915 opti++;
8916 if ("-a".equals(opt)) {
8917 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008918 } else if ("-c".equals(opt)) {
8919 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008920 } else if ("-h".equals(opt)) {
8921 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008922 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008923 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008924 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008925 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8926 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8927 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008928 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008929 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008930 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008931 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008932 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008933 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008934 pw.println(" all: dump all activities");
8935 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008936 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008937 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8938 pw.println(" a partial substring in a component name, a");
8939 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008940 pw.println(" -a: include all available server state.");
8941 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008942 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008943 } else {
8944 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008945 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008946 }
8947
8948 // Is the caller requesting to dump a particular piece of data?
8949 if (opti < args.length) {
8950 String cmd = args[opti];
8951 opti++;
8952 if ("activities".equals(cmd) || "a".equals(cmd)) {
8953 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008954 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008956 return;
8957 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008958 String[] newArgs;
8959 String name;
8960 if (opti >= args.length) {
8961 name = null;
8962 newArgs = EMPTY_STRING_ARRAY;
8963 } else {
8964 name = args[opti];
8965 opti++;
8966 newArgs = new String[args.length - opti];
8967 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8968 args.length - opti);
8969 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008970 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008971 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008972 }
8973 return;
8974 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008975 String[] newArgs;
8976 String name;
8977 if (opti >= args.length) {
8978 name = null;
8979 newArgs = EMPTY_STRING_ARRAY;
8980 } else {
8981 name = args[opti];
8982 opti++;
8983 newArgs = new String[args.length - opti];
8984 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8985 args.length - opti);
8986 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008987 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008988 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008989 }
8990 return;
8991 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008992 String[] newArgs;
8993 String name;
8994 if (opti >= args.length) {
8995 name = null;
8996 newArgs = EMPTY_STRING_ARRAY;
8997 } else {
8998 name = args[opti];
8999 opti++;
9000 newArgs = new String[args.length - opti];
9001 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9002 args.length - opti);
9003 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009004 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009005 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009006 }
9007 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009008 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9009 synchronized (this) {
9010 dumpOomLocked(fd, pw, args, opti, true);
9011 }
9012 return;
Marco Nelissen18cb2872011-11-15 11:19:53 -08009013 } else if ("provider".equals(cmd)) {
9014 String[] newArgs;
9015 String name;
9016 if (opti >= args.length) {
9017 name = null;
9018 newArgs = EMPTY_STRING_ARRAY;
9019 } else {
9020 name = args[opti];
9021 opti++;
9022 newArgs = new String[args.length - opti];
9023 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9024 }
9025 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9026 pw.println("No providers match: " + name);
9027 pw.println("Use -h for help.");
9028 }
9029 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009030 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9031 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009032 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009033 }
9034 return;
9035 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009036 String[] newArgs;
9037 String name;
9038 if (opti >= args.length) {
9039 name = null;
9040 newArgs = EMPTY_STRING_ARRAY;
9041 } else {
9042 name = args[opti];
9043 opti++;
9044 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009045 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9046 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009047 }
9048 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9049 pw.println("No services match: " + name);
9050 pw.println("Use -h for help.");
9051 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009052 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009053 } else if ("package".equals(cmd)) {
9054 String[] newArgs;
9055 if (opti >= args.length) {
9056 pw.println("package: no package name specified");
9057 pw.println("Use -h for help.");
9058 return;
9059 } else {
9060 dumpPackage = args[opti];
9061 opti++;
9062 newArgs = new String[args.length - opti];
9063 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9064 args.length - opti);
9065 args = newArgs;
9066 opti = 0;
9067 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009068 } else if ("services".equals(cmd) || "s".equals(cmd)) {
9069 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009070 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009071 }
9072 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07009073 } else {
9074 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009075 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9076 pw.println("Bad activity command, or no activities match: " + cmd);
9077 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009078 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009079 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009080 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009081 }
9082
9083 // No piece of data specified, dump everything.
9084 synchronized (this) {
9085 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009086 needSep = dumpPendingIntentsLocked(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 = dumpBroadcastsLocked(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 = dumpProvidersLocked(fd, pw, args, opti, dumpAll, 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 = dumpServicesLocked(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 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009115 if (needSep) {
9116 pw.println(" ");
9117 }
9118 if (dumpAll) {
9119 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009120 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009121 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009122 }
9123 }
9124
9125 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009126 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009127 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9128 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009129 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
9130 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009131 pw.println(" ");
9132 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009133 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
9134 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009135 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009136 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009137 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009138 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009139 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009140 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009141 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009143 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009144 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009145 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009146 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009147 if (mMainStack.mGoingToSleepActivities.size() > 0) {
9148 pw.println(" ");
9149 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009150 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009151 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009152 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009153 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009154 pw.println(" ");
9155 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009156 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009157 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009159
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009160 pw.println(" ");
Dianne Hackborncbb722e2012-02-07 18:33:49 -08009161 if (mMainStack.mPausingActivities.size() > 0) {
9162 pw.println(" mPausingActivities: " + Arrays.toString(
9163 mMainStack.mPausingActivities.toArray()));
9164 }
9165 if (mMainStack.mInputPausedActivities.size() > 0) {
9166 pw.println(" mInputPausedActivities: " + Arrays.toString(
9167 mMainStack.mInputPausedActivities.toArray()));
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009168 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009169 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009170 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009171 if (dumpAll) {
9172 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9173 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009174 pw.println(" mDismissKeyguardOnNextActivity: "
9175 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009178 if (mRecentTasks.size() > 0) {
9179 pw.println();
9180 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009181
9182 final int N = mRecentTasks.size();
9183 for (int i=0; i<N; i++) {
9184 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009185 if (dumpPackage != null) {
9186 if (tr.realActivity == null ||
9187 !dumpPackage.equals(tr.realActivity)) {
9188 continue;
9189 }
9190 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009191 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
9192 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009193 if (dumpAll) {
9194 mRecentTasks.get(i).dump(pw, " ");
9195 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009196 }
9197 }
9198
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009199 if (dumpAll) {
9200 pw.println(" ");
9201 pw.println(" mCurTask: " + mCurTask);
9202 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009203
9204 return true;
9205 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009206
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009207 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009208 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009209 boolean needSep = false;
9210 int numPers = 0;
9211
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009212 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9213
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009214 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009215 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9216 final int NA = procs.size();
9217 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009218 ProcessRecord r = procs.valueAt(ia);
9219 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9220 continue;
9221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222 if (!needSep) {
9223 pw.println(" All known processes:");
9224 needSep = true;
9225 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009226 pw.print(r.persistent ? " *PERS*" : " *APP*");
9227 pw.print(" UID "); pw.print(procs.keyAt(ia));
9228 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009229 r.dump(pw, " ");
9230 if (r.persistent) {
9231 numPers++;
9232 }
9233 }
9234 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009235 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08009236
9237 if (mIsolatedProcesses.size() > 0) {
9238 if (needSep) pw.println(" ");
9239 needSep = true;
9240 pw.println(" Isolated process list (sorted by uid):");
9241 for (int i=0; i<mIsolatedProcesses.size(); i++) {
9242 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9243 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9244 continue;
9245 }
9246 pw.println(String.format("%sIsolated #%2d: %s",
9247 " ", i, r.toString()));
9248 }
9249 }
9250
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009251 if (mLruProcesses.size() > 0) {
9252 if (needSep) pw.println(" ");
9253 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07009254 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009255 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009256 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009257 needSep = true;
9258 }
9259
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009260 if (dumpAll) {
9261 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009262 boolean printed = false;
9263 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9264 ProcessRecord r = mPidsSelfLocked.valueAt(i);
9265 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9266 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009267 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009268 if (!printed) {
9269 if (needSep) pw.println(" ");
9270 needSep = true;
9271 pw.println(" PID mappings:");
9272 printed = true;
9273 }
9274 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9275 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009276 }
9277 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009278 }
9279
9280 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009281 synchronized (mPidsSelfLocked) {
9282 boolean printed = false;
9283 for (int i=0; i<mForegroundProcesses.size(); i++) {
9284 ProcessRecord r = mPidsSelfLocked.get(
9285 mForegroundProcesses.valueAt(i).pid);
9286 if (dumpPackage != null && (r == null
9287 || !dumpPackage.equals(r.info.packageName))) {
9288 continue;
9289 }
9290 if (!printed) {
9291 if (needSep) pw.println(" ");
9292 needSep = true;
9293 pw.println(" Foreground Processes:");
9294 printed = true;
9295 }
9296 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9297 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009299 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009300 }
9301
9302 if (mPersistentStartingProcesses.size() > 0) {
9303 if (needSep) pw.println(" ");
9304 needSep = true;
9305 pw.println(" Persisent processes that are starting:");
9306 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009307 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009310 if (mRemovedProcesses.size() > 0) {
9311 if (needSep) pw.println(" ");
9312 needSep = true;
9313 pw.println(" Processes that are being removed:");
9314 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009315 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009316 }
9317
9318 if (mProcessesOnHold.size() > 0) {
9319 if (needSep) pw.println(" ");
9320 needSep = true;
9321 pw.println(" Processes that are on old until the system is ready:");
9322 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009323 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009326 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009327
9328 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009329 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009330 long now = SystemClock.uptimeMillis();
9331 for (Map.Entry<String, SparseArray<Long>> procs
9332 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009333 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009334 SparseArray<Long> uids = procs.getValue();
9335 final int N = uids.size();
9336 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009337 int puid = uids.keyAt(i);
9338 ProcessRecord r = mProcessNames.get(pname, puid);
9339 if (dumpPackage != null && (r == null
9340 || !dumpPackage.equals(r.info.packageName))) {
9341 continue;
9342 }
9343 if (!printed) {
9344 if (needSep) pw.println(" ");
9345 needSep = true;
9346 pw.println(" Time since processes crashed:");
9347 printed = true;
9348 }
9349 pw.print(" Process "); pw.print(pname);
9350 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009351 pw.print(": last crashed ");
9352 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009353 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009354 }
9355 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009358 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009359 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009360 for (Map.Entry<String, SparseArray<Long>> procs
9361 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009362 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009363 SparseArray<Long> uids = procs.getValue();
9364 final int N = uids.size();
9365 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009366 int puid = uids.keyAt(i);
9367 ProcessRecord r = mProcessNames.get(pname, puid);
9368 if (dumpPackage != null && (r == null
9369 || !dumpPackage.equals(r.info.packageName))) {
9370 continue;
9371 }
9372 if (!printed) {
9373 if (needSep) pw.println(" ");
9374 needSep = true;
9375 pw.println(" Bad processes:");
9376 }
9377 pw.print(" Bad process "); pw.print(pname);
9378 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009379 pw.print(": crashed at time ");
9380 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 }
9382 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009384
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009385 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009386 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009387 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009388 if (dumpAll) {
9389 StringBuilder sb = new StringBuilder(128);
9390 sb.append(" mPreviousProcessVisibleTime: ");
9391 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9392 pw.println(sb);
9393 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009394 if (mHeavyWeightProcess != null) {
9395 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9396 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009397 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009398 if (dumpAll) {
9399 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009400 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009401 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009402 for (Map.Entry<String, Integer> entry
9403 : mCompatModePackages.getPackages().entrySet()) {
9404 String pkg = entry.getKey();
9405 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009406 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9407 continue;
9408 }
9409 if (!printed) {
9410 pw.println(" mScreenCompatPackages:");
9411 printed = true;
9412 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009413 pw.print(" "); pw.print(pkg); pw.print(": ");
9414 pw.print(mode); pw.println();
9415 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009416 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009417 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009418 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9419 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9420 || mOrigWaitForDebugger) {
9421 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9422 + " mDebugTransient=" + mDebugTransient
9423 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9424 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009425 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9426 || mProfileFd != null) {
9427 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9428 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9429 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9430 + mAutoStopProfiler);
9431 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009432 if (mAlwaysFinishActivities || mController != null) {
9433 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9434 + " mController=" + mController);
9435 }
9436 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009437 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009438 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009439 + " mProcessesReady=" + mProcessesReady
9440 + " mSystemReady=" + mSystemReady);
9441 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 + " mBooted=" + mBooted
9443 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009444 pw.print(" mLastPowerCheckRealtime=");
9445 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9446 pw.println("");
9447 pw.print(" mLastPowerCheckUptime=");
9448 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9449 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009450 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9451 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009452 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009453 pw.println(" mNumServiceProcs=" + mNumServiceProcs
9454 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009455 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009456
9457 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009458 }
9459
Dianne Hackborn287952c2010-09-22 22:34:31 -07009460 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009461 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009462 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009463 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009464 long now = SystemClock.uptimeMillis();
9465 for (int i=0; i<mProcessesToGc.size(); i++) {
9466 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009467 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9468 continue;
9469 }
9470 if (!printed) {
9471 if (needSep) pw.println(" ");
9472 needSep = true;
9473 pw.println(" Processes that are waiting to GC:");
9474 printed = true;
9475 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009476 pw.print(" Process "); pw.println(proc);
9477 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9478 pw.print(", last gced=");
9479 pw.print(now-proc.lastRequestedGc);
9480 pw.print(" ms ago, last lowMem=");
9481 pw.print(now-proc.lastLowMemory);
9482 pw.println(" ms ago");
9483
9484 }
9485 }
9486 return needSep;
9487 }
9488
9489 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9490 int opti, boolean dumpAll) {
9491 boolean needSep = false;
9492
9493 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009494 if (needSep) pw.println(" ");
9495 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009496 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009497 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009498 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009499 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9500 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9501 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9502 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9503 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009504 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009505 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009506 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009507 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009508 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009509 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009510
9511 if (needSep) pw.println(" ");
9512 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009513 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009514 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009515 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009516 needSep = true;
9517 }
9518
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009519 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009520
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009521 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009522 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009523 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009524 if (mHeavyWeightProcess != null) {
9525 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9526 }
9527
9528 return true;
9529 }
9530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 /**
9532 * There are three ways to call this:
9533 * - no service specified: dump all the services
9534 * - a flattened component name that matched an existing service was specified as the
9535 * first arg: dump that one service
9536 * - the first arg isn't the flattened component name of an existing service:
9537 * dump all services whose component contains the first arg as a substring
9538 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009539 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9540 int opti, boolean dumpAll) {
9541 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009542
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009543 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009544 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009545 try {
9546 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9547 for (UserInfo user : users) {
9548 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9549 services.add(r1);
9550 }
9551 }
9552 } catch (RemoteException re) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009553 }
9554 }
9555 } else {
9556 ComponentName componentName = name != null
9557 ? ComponentName.unflattenFromString(name) : null;
9558 int objectId = 0;
9559 if (componentName == null) {
9560 // Not a '/' separated full component name; maybe an object ID?
9561 try {
9562 objectId = Integer.parseInt(name, 16);
9563 name = null;
9564 componentName = null;
9565 } catch (RuntimeException e) {
9566 }
9567 }
9568
9569 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009570 try {
9571 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9572 for (UserInfo user : users) {
9573 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9574 if (componentName != null) {
9575 if (r1.name.equals(componentName)) {
9576 services.add(r1);
9577 }
9578 } else if (name != null) {
9579 if (r1.name.flattenToString().contains(name)) {
9580 services.add(r1);
9581 }
9582 } else if (System.identityHashCode(r1) == objectId) {
9583 services.add(r1);
9584 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009585 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009586 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009587 } catch (RemoteException re) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009588 }
9589 }
9590 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009591
9592 if (services.size() <= 0) {
9593 return false;
9594 }
9595
9596 boolean needSep = false;
9597 for (int i=0; i<services.size(); i++) {
9598 if (needSep) {
9599 pw.println();
9600 }
9601 needSep = true;
9602 dumpService("", fd, pw, services.get(i), args, dumpAll);
9603 }
9604 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009605 }
9606
9607 /**
9608 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9609 * there is a thread associated with the service.
9610 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009611 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9612 final ServiceRecord r, String[] args, boolean dumpAll) {
9613 String innerPrefix = prefix + " ";
9614 synchronized (this) {
9615 pw.print(prefix); pw.print("SERVICE ");
9616 pw.print(r.shortName); pw.print(" ");
9617 pw.print(Integer.toHexString(System.identityHashCode(r)));
9618 pw.print(" pid=");
9619 if (r.app != null) pw.println(r.app.pid);
9620 else pw.println("(not running)");
9621 if (dumpAll) {
9622 r.dump(pw, innerPrefix);
9623 }
9624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009625 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009626 pw.print(prefix); pw.println(" Client:");
9627 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009628 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009629 TransferPipe tp = new TransferPipe();
9630 try {
9631 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9632 tp.setBufferPrefix(prefix + " ");
9633 tp.go(fd);
9634 } finally {
9635 tp.kill();
9636 }
9637 } catch (IOException e) {
9638 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009639 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009640 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009641 }
9642 }
9643 }
9644
Marco Nelissen18cb2872011-11-15 11:19:53 -08009645 /**
9646 * There are three ways to call this:
9647 * - no provider specified: dump all the providers
9648 * - a flattened component name that matched an existing provider was specified as the
9649 * first arg: dump that one provider
9650 * - the first arg isn't the flattened component name of an existing provider:
9651 * dump all providers whose component contains the first arg as a substring
9652 */
9653 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9654 int opti, boolean dumpAll) {
Marco Nelissende7408c2012-02-08 14:57:38 -08009655 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
Marco Nelissen18cb2872011-11-15 11:19:53 -08009656 }
9657
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009658 static class ItemMatcher {
9659 ArrayList<ComponentName> components;
9660 ArrayList<String> strings;
9661 ArrayList<Integer> objects;
9662 boolean all;
9663
9664 ItemMatcher() {
9665 all = true;
9666 }
9667
9668 void build(String name) {
9669 ComponentName componentName = ComponentName.unflattenFromString(name);
9670 if (componentName != null) {
9671 if (components == null) {
9672 components = new ArrayList<ComponentName>();
9673 }
9674 components.add(componentName);
9675 all = false;
9676 } else {
9677 int objectId = 0;
9678 // Not a '/' separated full component name; maybe an object ID?
9679 try {
9680 objectId = Integer.parseInt(name, 16);
9681 if (objects == null) {
9682 objects = new ArrayList<Integer>();
9683 }
9684 objects.add(objectId);
9685 all = false;
9686 } catch (RuntimeException e) {
9687 // Not an integer; just do string match.
9688 if (strings == null) {
9689 strings = new ArrayList<String>();
9690 }
9691 strings.add(name);
9692 all = false;
9693 }
9694 }
9695 }
9696
9697 int build(String[] args, int opti) {
9698 for (; opti<args.length; opti++) {
9699 String name = args[opti];
9700 if ("--".equals(name)) {
9701 return opti+1;
9702 }
9703 build(name);
9704 }
9705 return opti;
9706 }
9707
9708 boolean match(Object object, ComponentName comp) {
9709 if (all) {
9710 return true;
9711 }
9712 if (components != null) {
9713 for (int i=0; i<components.size(); i++) {
9714 if (components.get(i).equals(comp)) {
9715 return true;
9716 }
9717 }
9718 }
9719 if (objects != null) {
9720 for (int i=0; i<objects.size(); i++) {
9721 if (System.identityHashCode(object) == objects.get(i)) {
9722 return true;
9723 }
9724 }
9725 }
9726 if (strings != null) {
9727 String flat = comp.flattenToString();
9728 for (int i=0; i<strings.size(); i++) {
9729 if (flat.contains(strings.get(i))) {
9730 return true;
9731 }
9732 }
9733 }
9734 return false;
9735 }
9736 }
9737
Dianne Hackborn625ac272010-09-17 18:29:22 -07009738 /**
9739 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009740 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009741 * - the cmd arg isn't the flattened component name of an existing activity:
9742 * dump all activity whose component contains the cmd as a substring
9743 * - A hex number of the ActivityRecord object instance.
9744 */
9745 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9746 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009747 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009748
9749 if ("all".equals(name)) {
9750 synchronized (this) {
9751 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009752 activities.add(r1);
9753 }
9754 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009755 } else if ("top".equals(name)) {
9756 synchronized (this) {
9757 final int N = mMainStack.mHistory.size();
9758 if (N > 0) {
9759 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9760 }
9761 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009762 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009763 ItemMatcher matcher = new ItemMatcher();
9764 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009765
9766 synchronized (this) {
9767 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009768 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009769 activities.add(r1);
9770 }
9771 }
9772 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009773 }
9774
9775 if (activities.size() <= 0) {
9776 return false;
9777 }
9778
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009779 String[] newArgs = new String[args.length - opti];
9780 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9781
Dianne Hackborn30d71892010-12-11 10:37:55 -08009782 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009783 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009784 for (int i=activities.size()-1; i>=0; i--) {
9785 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009786 if (needSep) {
9787 pw.println();
9788 }
9789 needSep = true;
9790 synchronized (this) {
9791 if (lastTask != r.task) {
9792 lastTask = r.task;
9793 pw.print("TASK "); pw.print(lastTask.affinity);
9794 pw.print(" id="); pw.println(lastTask.taskId);
9795 if (dumpAll) {
9796 lastTask.dump(pw, " ");
9797 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009798 }
9799 }
9800 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009801 }
9802 return true;
9803 }
9804
9805 /**
9806 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9807 * there is a thread associated with the activity.
9808 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009809 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009810 final ActivityRecord r, String[] args, boolean dumpAll) {
9811 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009812 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009813 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9814 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9815 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009816 if (r.app != null) pw.println(r.app.pid);
9817 else pw.println("(not running)");
9818 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009819 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009820 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009821 }
9822 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009823 // flush anything that is already in the PrintWriter since the thread is going
9824 // to write to the file descriptor directly
9825 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009826 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009827 TransferPipe tp = new TransferPipe();
9828 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009829 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9830 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009831 tp.go(fd);
9832 } finally {
9833 tp.kill();
9834 }
9835 } catch (IOException e) {
9836 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009837 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009838 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009839 }
9840 }
9841 }
9842
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009843 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009844 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009845 boolean needSep = false;
9846
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009847 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009848 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009849 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009850 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851 Iterator it = mRegisteredReceivers.values().iterator();
9852 while (it.hasNext()) {
9853 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009854 if (dumpPackage != null && (r.app == null ||
9855 !dumpPackage.equals(r.app.info.packageName))) {
9856 continue;
9857 }
9858 if (!printed) {
9859 pw.println(" Registered Receivers:");
9860 needSep = true;
9861 printed = true;
9862 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009863 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 r.dump(pw, " ");
9865 }
9866 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009867
9868 if (mReceiverResolver.dump(pw, needSep ?
9869 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9870 " ", dumpPackage, false)) {
9871 needSep = true;
9872 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009873 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009874
9875 for (BroadcastQueue q : mBroadcastQueues) {
9876 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009879 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009880
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009881 if (mStickyBroadcasts != null && dumpPackage == null) {
9882 if (needSep) {
9883 pw.println();
9884 }
9885 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009886 pw.println(" Sticky broadcasts:");
9887 StringBuilder sb = new StringBuilder(128);
9888 for (Map.Entry<String, ArrayList<Intent>> ent
9889 : mStickyBroadcasts.entrySet()) {
9890 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009891 if (dumpAll) {
9892 pw.println(":");
9893 ArrayList<Intent> intents = ent.getValue();
9894 final int N = intents.size();
9895 for (int i=0; i<N; i++) {
9896 sb.setLength(0);
9897 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009898 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009899 pw.println(sb.toString());
9900 Bundle bundle = intents.get(i).getExtras();
9901 if (bundle != null) {
9902 pw.print(" ");
9903 pw.println(bundle.toString());
9904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009906 } else {
9907 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009908 }
9909 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009910 needSep = true;
9911 }
9912
9913 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009914 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009915 for (BroadcastQueue queue : mBroadcastQueues) {
9916 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9917 + queue.mBroadcastsScheduled);
9918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009919 pw.println(" mHandler:");
9920 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009921 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009922 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009923
9924 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 }
9926
Marco Nelissen18cb2872011-11-15 11:19:53 -08009927 /**
9928 * Prints a list of ServiceRecords (dumpsys activity services)
9929 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009930 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009931 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009932 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009934 ItemMatcher matcher = new ItemMatcher();
9935 matcher.build(args, opti);
9936
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009937 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009938 try {
9939 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9940 for (UserInfo user : users) {
9941 if (mServiceMap.getAllServices(user.id).size() > 0) {
9942 boolean printed = false;
9943 long nowReal = SystemClock.elapsedRealtime();
9944 Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9945 user.id).iterator();
9946 needSep = false;
9947 while (it.hasNext()) {
9948 ServiceRecord r = it.next();
9949 if (!matcher.match(r, r.name)) {
9950 continue;
9951 }
9952 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9953 continue;
9954 }
9955 if (!printed) {
9956 pw.println(" Active services:");
9957 printed = true;
9958 }
9959 if (needSep) {
9960 pw.println();
9961 }
9962 pw.print(" * ");
9963 pw.println(r);
9964 if (dumpAll) {
9965 r.dump(pw, " ");
9966 needSep = true;
9967 } else {
9968 pw.print(" app=");
9969 pw.println(r.app);
9970 pw.print(" created=");
9971 TimeUtils.formatDuration(r.createTime, nowReal, pw);
9972 pw.print(" started=");
9973 pw.print(r.startRequested);
9974 pw.print(" connections=");
9975 pw.println(r.connections.size());
9976 if (r.connections.size() > 0) {
9977 pw.println(" Connections:");
9978 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9979 for (int i = 0; i < clist.size(); i++) {
9980 ConnectionRecord conn = clist.get(i);
9981 pw.print(" ");
9982 pw.print(conn.binding.intent.intent.getIntent()
9983 .toShortString(false, false, false));
9984 pw.print(" -> ");
9985 ProcessRecord proc = conn.binding.client;
9986 pw.println(proc != null ? proc.toShortString() : "null");
9987 }
9988 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009989 }
9990 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009991 if (dumpClient && r.app != null && r.app.thread != null) {
9992 pw.println(" Client:");
9993 pw.flush();
9994 try {
9995 TransferPipe tp = new TransferPipe();
9996 try {
9997 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9998 r, args);
9999 tp.setBufferPrefix(" ");
10000 // Short timeout, since blocking here can
10001 // deadlock with the application.
10002 tp.go(fd, 2000);
10003 } finally {
10004 tp.kill();
10005 }
10006 } catch (IOException e) {
10007 pw.println(" Failure while dumping the service: " + e);
10008 } catch (RemoteException e) {
10009 pw.println(" Got a RemoteException while dumping the service");
10010 }
10011 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010012 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010013 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010014 needSep = printed;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010017 } catch (RemoteException re) {
10018
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010021 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010022 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010023 for (int i=0; i<mPendingServices.size(); i++) {
10024 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010025 if (!matcher.match(r, r.name)) {
10026 continue;
10027 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010028 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10029 continue;
10030 }
10031 if (!printed) {
10032 if (needSep) pw.println(" ");
10033 needSep = true;
10034 pw.println(" Pending services:");
10035 printed = true;
10036 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010037 pw.print(" * Pending "); pw.println(r);
10038 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010039 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010040 needSep = true;
10041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010042
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010043 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010044 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010045 for (int i=0; i<mRestartingServices.size(); i++) {
10046 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010047 if (!matcher.match(r, r.name)) {
10048 continue;
10049 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010050 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10051 continue;
10052 }
10053 if (!printed) {
10054 if (needSep) pw.println(" ");
10055 needSep = true;
10056 pw.println(" Restarting services:");
10057 printed = true;
10058 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010059 pw.print(" * Restarting "); pw.println(r);
10060 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010062 needSep = true;
10063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010064
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010065 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010066 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010067 for (int i=0; i<mStoppingServices.size(); i++) {
10068 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010069 if (!matcher.match(r, r.name)) {
10070 continue;
10071 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010072 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10073 continue;
10074 }
10075 if (!printed) {
10076 if (needSep) pw.println(" ");
10077 needSep = true;
10078 pw.println(" Stopping services:");
10079 printed = true;
10080 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010081 pw.print(" * Stopping "); pw.println(r);
10082 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010084 needSep = true;
10085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010086
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010087 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010088 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010089 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010090 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 = mServiceConnections.values().iterator();
10092 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010093 ArrayList<ConnectionRecord> r = it.next();
10094 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010095 ConnectionRecord cr = r.get(i);
10096 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
10097 continue;
10098 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010099 if (dumpPackage != null && (cr.binding.client == null
10100 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
10101 continue;
10102 }
10103 if (!printed) {
10104 if (needSep) pw.println(" ");
10105 needSep = true;
10106 pw.println(" Connection bindings to services:");
10107 printed = true;
10108 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010109 pw.print(" * "); pw.println(cr);
10110 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010113 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010114 }
10115 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010116
10117 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010118 }
10119
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010120 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010121 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010122 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010123
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010124 ItemMatcher matcher = new ItemMatcher();
10125 matcher.build(args, opti);
10126
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010127 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -070010128
10129 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010130
10131 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010132 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010133 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010134 ContentProviderRecord r = mLaunchingProviders.get(i);
10135 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
10136 continue;
10137 }
10138 if (!printed) {
10139 if (needSep) pw.println(" ");
10140 needSep = true;
10141 pw.println(" Launching content providers:");
10142 printed = true;
10143 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010144 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010145 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010146 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010147 }
10148
10149 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010150 if (needSep) pw.println();
10151 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010152 pw.println("Granted Uri Permissions:");
10153 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
10154 int uid = mGrantedUriPermissions.keyAt(i);
10155 HashMap<Uri, UriPermission> perms
10156 = mGrantedUriPermissions.valueAt(i);
10157 pw.print(" * UID "); pw.print(uid);
10158 pw.println(" holds:");
10159 for (UriPermission perm : perms.values()) {
10160 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010161 if (dumpAll) {
10162 perm.dump(pw, " ");
10163 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010164 }
10165 }
10166 needSep = true;
10167 }
10168
10169 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170 }
10171
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010172 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010173 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010174 boolean needSep = false;
10175
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010176 if (mIntentSenderRecords.size() > 0) {
10177 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010178 Iterator<WeakReference<PendingIntentRecord>> it
10179 = mIntentSenderRecords.values().iterator();
10180 while (it.hasNext()) {
10181 WeakReference<PendingIntentRecord> ref = it.next();
10182 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010183 if (dumpPackage != null && (rec == null
10184 || !dumpPackage.equals(rec.key.packageName))) {
10185 continue;
10186 }
10187 if (!printed) {
10188 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
10189 printed = true;
10190 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010191 needSep = true;
10192 if (rec != null) {
10193 pw.print(" * "); pw.println(rec);
10194 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010195 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010197 } else {
10198 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 }
10200 }
10201 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010202
10203 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010204 }
10205
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010206 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010207 String prefix, String label, boolean complete, boolean brief, boolean client,
10208 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010209 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010210 boolean needNL = false;
10211 final String innerPrefix = prefix + " ";
10212 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010214 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010215 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
10216 continue;
10217 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -070010218 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010219 if (needNL) {
10220 pw.println(" ");
10221 needNL = false;
10222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 if (lastTask != r.task) {
10224 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010225 pw.print(prefix);
10226 pw.print(full ? "* " : " ");
10227 pw.println(lastTask);
10228 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010229 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010230 } else if (complete) {
10231 // Complete + brief == give a summary. Isn't that obvious?!?
10232 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010233 pw.print(prefix); pw.print(" ");
10234 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010235 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010237 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010238 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
10239 pw.print(" #"); pw.print(i); pw.print(": ");
10240 pw.println(r);
10241 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010242 r.dump(pw, innerPrefix);
10243 } else if (complete) {
10244 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010245 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010246 if (r.app != null) {
10247 pw.print(innerPrefix); pw.println(r.app);
10248 }
10249 }
10250 if (client && r.app != null && r.app.thread != null) {
10251 // flush anything that is already in the PrintWriter since the thread is going
10252 // to write to the file descriptor directly
10253 pw.flush();
10254 try {
10255 TransferPipe tp = new TransferPipe();
10256 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -080010257 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10258 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010259 // Short timeout, since blocking here can
10260 // deadlock with the application.
10261 tp.go(fd, 2000);
10262 } finally {
10263 tp.kill();
10264 }
10265 } catch (IOException e) {
10266 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10267 } catch (RemoteException e) {
10268 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10269 }
10270 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010272 }
10273 }
10274
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010275 private static String buildOomTag(String prefix, String space, int val, int base) {
10276 if (val == base) {
10277 if (space == null) return prefix;
10278 return prefix + " ";
10279 }
10280 return prefix + "+" + Integer.toString(val-base);
10281 }
10282
10283 private static final int dumpProcessList(PrintWriter pw,
10284 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010285 String prefix, String normalLabel, String persistentLabel,
10286 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010288 final int N = list.size()-1;
10289 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010290 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010291 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10292 continue;
10293 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010294 pw.println(String.format("%s%s #%2d: %s",
10295 prefix, (r.persistent ? persistentLabel : normalLabel),
10296 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 if (r.persistent) {
10298 numPers++;
10299 }
10300 }
10301 return numPers;
10302 }
10303
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010304 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -070010305 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -070010306 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010307 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010308
Dianne Hackborn905577f2011-09-07 18:31:28 -070010309 ArrayList<Pair<ProcessRecord, Integer>> list
10310 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10311 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010312 ProcessRecord r = origList.get(i);
10313 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10314 continue;
10315 }
Dianne Hackborn905577f2011-09-07 18:31:28 -070010316 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10317 }
10318
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010319 if (list.size() <= 0) {
10320 return false;
10321 }
10322
Dianne Hackborn905577f2011-09-07 18:31:28 -070010323 Comparator<Pair<ProcessRecord, Integer>> comparator
10324 = new Comparator<Pair<ProcessRecord, Integer>>() {
10325 @Override
10326 public int compare(Pair<ProcessRecord, Integer> object1,
10327 Pair<ProcessRecord, Integer> object2) {
10328 if (object1.first.setAdj != object2.first.setAdj) {
10329 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10330 }
10331 if (object1.second.intValue() != object2.second.intValue()) {
10332 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10333 }
10334 return 0;
10335 }
10336 };
10337
10338 Collections.sort(list, comparator);
10339
Dianne Hackborn287952c2010-09-22 22:34:31 -070010340 final long curRealtime = SystemClock.elapsedRealtime();
10341 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10342 final long curUptime = SystemClock.uptimeMillis();
10343 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10344
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010345 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070010346 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010347 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010348 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070010349 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010350 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10351 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010352 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10353 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010354 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10355 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010356 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10357 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010358 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010359 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010360 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10361 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10362 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10363 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10364 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10365 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10366 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10367 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010368 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10369 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010370 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10371 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010372 } else {
10373 oomAdj = Integer.toString(r.setAdj);
10374 }
10375 String schedGroup;
10376 switch (r.setSchedGroup) {
10377 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10378 schedGroup = "B";
10379 break;
10380 case Process.THREAD_GROUP_DEFAULT:
10381 schedGroup = "F";
10382 break;
10383 default:
10384 schedGroup = Integer.toString(r.setSchedGroup);
10385 break;
10386 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010387 String foreground;
10388 if (r.foregroundActivities) {
10389 foreground = "A";
10390 } else if (r.foregroundServices) {
10391 foreground = "S";
10392 } else {
10393 foreground = " ";
10394 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010395 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -070010396 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010397 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10398 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -070010399 if (r.adjSource != null || r.adjTarget != null) {
10400 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010401 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070010402 if (r.adjTarget instanceof ComponentName) {
10403 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10404 } else if (r.adjTarget != null) {
10405 pw.print(r.adjTarget.toString());
10406 } else {
10407 pw.print("{null}");
10408 }
10409 pw.print("<=");
10410 if (r.adjSource instanceof ProcessRecord) {
10411 pw.print("Proc{");
10412 pw.print(((ProcessRecord)r.adjSource).toShortString());
10413 pw.println("}");
10414 } else if (r.adjSource != null) {
10415 pw.println(r.adjSource.toString());
10416 } else {
10417 pw.println("{null}");
10418 }
10419 }
10420 if (inclDetails) {
10421 pw.print(prefix);
10422 pw.print(" ");
10423 pw.print("oom: max="); pw.print(r.maxAdj);
10424 pw.print(" hidden="); pw.print(r.hiddenAdj);
10425 pw.print(" curRaw="); pw.print(r.curRawAdj);
10426 pw.print(" setRaw="); pw.print(r.setRawAdj);
10427 pw.print(" cur="); pw.print(r.curAdj);
10428 pw.print(" set="); pw.println(r.setAdj);
10429 pw.print(prefix);
10430 pw.print(" ");
10431 pw.print("keeping="); pw.print(r.keeping);
10432 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010433 pw.print(" empty="); pw.print(r.empty);
10434 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010435
10436 if (!r.keeping) {
10437 if (r.lastWakeTime != 0) {
10438 long wtime;
10439 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10440 synchronized (stats) {
10441 wtime = stats.getProcessWakeTime(r.info.uid,
10442 r.pid, curRealtime);
10443 }
10444 long timeUsed = wtime - r.lastWakeTime;
10445 pw.print(prefix);
10446 pw.print(" ");
10447 pw.print("keep awake over ");
10448 TimeUtils.formatDuration(realtimeSince, pw);
10449 pw.print(" used ");
10450 TimeUtils.formatDuration(timeUsed, pw);
10451 pw.print(" (");
10452 pw.print((timeUsed*100)/realtimeSince);
10453 pw.println("%)");
10454 }
10455 if (r.lastCpuTime != 0) {
10456 long timeUsed = r.curCpuTime - r.lastCpuTime;
10457 pw.print(prefix);
10458 pw.print(" ");
10459 pw.print("run cpu over ");
10460 TimeUtils.formatDuration(uptimeSince, pw);
10461 pw.print(" used ");
10462 TimeUtils.formatDuration(timeUsed, pw);
10463 pw.print(" (");
10464 pw.print((timeUsed*100)/uptimeSince);
10465 pw.println("%)");
10466 }
10467 }
10468 }
10469 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010470 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010471 }
10472
Dianne Hackbornb437e092011-08-05 17:50:29 -070010473 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010474 ArrayList<ProcessRecord> procs;
10475 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010476 if (args != null && args.length > start
10477 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010478 procs = new ArrayList<ProcessRecord>();
10479 int pid = -1;
10480 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010481 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010482 } catch (NumberFormatException e) {
10483
10484 }
10485 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10486 ProcessRecord proc = mLruProcesses.get(i);
10487 if (proc.pid == pid) {
10488 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010489 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010490 procs.add(proc);
10491 }
10492 }
10493 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010494 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010495 return null;
10496 }
10497 } else {
10498 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10499 }
10500 }
10501 return procs;
10502 }
10503
10504 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10505 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010506 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010507 if (procs == null) {
10508 return;
10509 }
10510
10511 long uptime = SystemClock.uptimeMillis();
10512 long realtime = SystemClock.elapsedRealtime();
10513 pw.println("Applications Graphics Acceleration Info:");
10514 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10515
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010516 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10517 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010518 if (r.thread != null) {
10519 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10520 pw.flush();
10521 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010522 TransferPipe tp = new TransferPipe();
10523 try {
10524 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10525 tp.go(fd);
10526 } finally {
10527 tp.kill();
10528 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010529 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010530 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010531 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -070010532 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010533 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010534 pw.flush();
10535 }
10536 }
10537 }
Chet Haase9c1e23b2011-03-24 10:51:31 -070010538 }
10539
Jeff Brown6754ba22011-12-14 20:20:01 -080010540 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10541 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10542 if (procs == null) {
10543 return;
10544 }
10545
10546 pw.println("Applications Database Info:");
10547
10548 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10549 ProcessRecord r = procs.get(i);
10550 if (r.thread != null) {
10551 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10552 pw.flush();
10553 try {
10554 TransferPipe tp = new TransferPipe();
10555 try {
10556 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10557 tp.go(fd);
10558 } finally {
10559 tp.kill();
10560 }
10561 } catch (IOException e) {
10562 pw.println("Failure while dumping the app: " + r);
10563 pw.flush();
10564 } catch (RemoteException e) {
10565 pw.println("Got a RemoteException while dumping the app " + r);
10566 pw.flush();
10567 }
10568 }
10569 }
10570 }
10571
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010572 final static class MemItem {
10573 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010574 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010575 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010576 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010577 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010578
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010579 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010580 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010581 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010582 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010583 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010584 }
10585 }
10586
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010587 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010588 boolean sort) {
10589 if (sort) {
10590 Collections.sort(items, new Comparator<MemItem>() {
10591 @Override
10592 public int compare(MemItem lhs, MemItem rhs) {
10593 if (lhs.pss < rhs.pss) {
10594 return 1;
10595 } else if (lhs.pss > rhs.pss) {
10596 return -1;
10597 }
10598 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010599 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010600 });
10601 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010602
10603 for (int i=0; i<items.size(); i++) {
10604 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010605 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010606 if (mi.subitems != null) {
10607 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10608 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010609 }
10610 }
10611
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010612 // These are in KB.
10613 static final long[] DUMP_MEM_BUCKETS = new long[] {
10614 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10615 120*1024, 160*1024, 200*1024,
10616 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10617 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10618 };
10619
Dianne Hackborn672342c2011-11-29 11:29:02 -080010620 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10621 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010622 int start = label.lastIndexOf('.');
10623 if (start >= 0) start++;
10624 else start = 0;
10625 int end = label.length();
10626 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10627 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10628 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10629 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010630 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010631 out.append(label, start, end);
10632 return;
10633 }
10634 }
10635 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010636 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010637 out.append(label, start, end);
10638 }
10639
10640 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10641 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10642 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10643 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10644 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10645 };
10646 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10647 "System", "Persistent", "Foreground",
10648 "Visible", "Perceptible", "Heavy Weight",
10649 "Backup", "A Services", "Home", "Previous",
10650 "B Services", "Background"
10651 };
10652
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010653 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010654 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010655 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010656 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010657 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010658
10659 int opti = 0;
10660 while (opti < args.length) {
10661 String opt = args[opti];
10662 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10663 break;
10664 }
10665 opti++;
10666 if ("-a".equals(opt)) {
10667 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010668 } else if ("--oom".equals(opt)) {
10669 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010670 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010671 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010672 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010673 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010674 pw.println("If [process] is specified it can be the name or ");
10675 pw.println("pid of a specific process to dump.");
10676 return;
10677 } else {
10678 pw.println("Unknown argument: " + opt + "; use -h for help");
10679 }
10680 }
10681
10682 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010683 if (procs == null) {
10684 return;
10685 }
10686
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010687 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010688 long uptime = SystemClock.uptimeMillis();
10689 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010690
10691 if (procs.size() == 1 || isCheckinRequest) {
10692 dumpAll = true;
10693 }
10694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010695 if (isCheckinRequest) {
10696 // short checkin version
10697 pw.println(uptime + "," + realtime);
10698 pw.flush();
10699 } else {
10700 pw.println("Applications Memory Usage (kB):");
10701 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10702 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010703
Dianne Hackbornb437e092011-08-05 17:50:29 -070010704 String[] innerArgs = new String[args.length-opti];
10705 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10706
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010707 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10708 long nativePss=0, dalvikPss=0, otherPss=0;
10709 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10710
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010711 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10712 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10713 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010714
10715 long totalPss = 0;
10716
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010717 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10718 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010719 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010720 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010721 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10722 pw.flush();
10723 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010724 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010725 if (dumpAll) {
10726 try {
10727 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10728 } catch (RemoteException e) {
10729 if (!isCheckinRequest) {
10730 pw.println("Got RemoteException!");
10731 pw.flush();
10732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010733 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010734 } else {
10735 mi = new Debug.MemoryInfo();
10736 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010737 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010738
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010739 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010740 long myTotalPss = mi.getTotalPss();
10741 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010742 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010743 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010744 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010745
10746 nativePss += mi.nativePss;
10747 dalvikPss += mi.dalvikPss;
10748 otherPss += mi.otherPss;
10749 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10750 long mem = mi.getOtherPss(j);
10751 miscPss[j] += mem;
10752 otherPss -= mem;
10753 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010754
10755 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010756 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10757 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010758 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010759 if (oomProcs[oomIndex] == null) {
10760 oomProcs[oomIndex] = new ArrayList<MemItem>();
10761 }
10762 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010763 break;
10764 }
10765 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 }
10768 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010769
10770 if (!isCheckinRequest && procs.size() > 1) {
10771 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10772
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010773 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10774 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10775 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010776 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010777 String label = Debug.MemoryInfo.getOtherLabel(j);
10778 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010779 }
10780
Dianne Hackbornb437e092011-08-05 17:50:29 -070010781 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10782 for (int j=0; j<oomPss.length; j++) {
10783 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010784 String label = DUMP_MEM_OOM_LABEL[j];
10785 MemItem item = new MemItem(label, label, oomPss[j],
10786 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010787 item.subitems = oomProcs[j];
10788 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010789 }
10790 }
10791
Dianne Hackborn672342c2011-11-29 11:29:02 -080010792 if (outTag != null || outStack != null) {
10793 if (outTag != null) {
10794 appendMemBucket(outTag, totalPss, "total", false);
10795 }
10796 if (outStack != null) {
10797 appendMemBucket(outStack, totalPss, "total", true);
10798 }
10799 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010800 for (int i=0; i<oomMems.size(); i++) {
10801 MemItem miCat = oomMems.get(i);
10802 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10803 continue;
10804 }
10805 if (miCat.id < ProcessList.SERVICE_ADJ
10806 || miCat.id == ProcessList.HOME_APP_ADJ
10807 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010808 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10809 outTag.append(" / ");
10810 }
10811 if (outStack != null) {
10812 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10813 if (firstLine) {
10814 outStack.append(":");
10815 firstLine = false;
10816 }
10817 outStack.append("\n\t at ");
10818 } else {
10819 outStack.append("$");
10820 }
10821 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010822 for (int j=0; j<miCat.subitems.size(); j++) {
10823 MemItem mi = miCat.subitems.get(j);
10824 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010825 if (outTag != null) {
10826 outTag.append(" ");
10827 }
10828 if (outStack != null) {
10829 outStack.append("$");
10830 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010831 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010832 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10833 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10834 }
10835 if (outStack != null) {
10836 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10837 }
10838 }
10839 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10840 outStack.append("(");
10841 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10842 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10843 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10844 outStack.append(":");
10845 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10846 }
10847 }
10848 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010849 }
10850 }
10851 }
10852 }
10853
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010854 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010855 pw.println();
10856 pw.println("Total PSS by process:");
10857 dumpMemItems(pw, " ", procMems, true);
10858 pw.println();
10859 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010860 pw.println("Total PSS by OOM adjustment:");
10861 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010862 if (!oomOnly) {
10863 PrintWriter out = categoryPw != null ? categoryPw : pw;
10864 out.println();
10865 out.println("Total PSS by category:");
10866 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010867 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010868 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010869 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 }
10872
10873 /**
10874 * Searches array of arguments for the specified string
10875 * @param args array of argument strings
10876 * @param value value to search for
10877 * @return true if the value is contained in the array
10878 */
10879 private static boolean scanArgs(String[] args, String value) {
10880 if (args != null) {
10881 for (String arg : args) {
10882 if (value.equals(arg)) {
10883 return true;
10884 }
10885 }
10886 }
10887 return false;
10888 }
10889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010890 private final void killServicesLocked(ProcessRecord app,
10891 boolean allowRestart) {
10892 // Report disconnected services.
10893 if (false) {
10894 // XXX we are letting the client link to the service for
10895 // death notifications.
10896 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010897 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010899 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010901 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010902 = r.connections.values().iterator();
10903 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010904 ArrayList<ConnectionRecord> cl = jt.next();
10905 for (int i=0; i<cl.size(); i++) {
10906 ConnectionRecord c = cl.get(i);
10907 if (c.binding.client != app) {
10908 try {
10909 //c.conn.connected(r.className, null);
10910 } catch (Exception e) {
10911 // todo: this should be asynchronous!
10912 Slog.w(TAG, "Exception thrown disconnected servce "
10913 + r.shortName
10914 + " from app " + app.processName, e);
10915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010916 }
10917 }
10918 }
10919 }
10920 }
10921 }
10922 }
10923
10924 // Clean up any connections this application has to other services.
10925 if (app.connections.size() > 0) {
10926 Iterator<ConnectionRecord> it = app.connections.iterator();
10927 while (it.hasNext()) {
10928 ConnectionRecord r = it.next();
10929 removeConnectionLocked(r, app, null);
10930 }
10931 }
10932 app.connections.clear();
10933
10934 if (app.services.size() != 0) {
10935 // Any services running in the application need to be placed
10936 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010937 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010938 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010939 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010940 synchronized (sr.stats.getBatteryStats()) {
10941 sr.stats.stopLaunchedLocked();
10942 }
10943 sr.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010944 sr.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010945 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010946 if (mStoppingServices.remove(sr)) {
10947 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10948 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010949
10950 boolean hasClients = sr.bindings.size() > 0;
10951 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010952 Iterator<IntentBindRecord> bindings
10953 = sr.bindings.values().iterator();
10954 while (bindings.hasNext()) {
10955 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010956 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010957 + ": shouldUnbind=" + b.hasBound);
10958 b.binder = null;
10959 b.requested = b.received = b.hasBound = false;
10960 }
10961 }
10962
Dianne Hackborn070783f2010-12-29 16:46:28 -080010963 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10964 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010965 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010966 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010967 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010968 sr.crashCount, sr.shortName, app.pid);
10969 bringDownServiceLocked(sr, true);
10970 } else if (!allowRestart) {
10971 bringDownServiceLocked(sr, true);
10972 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010973 boolean canceled = scheduleServiceRestartLocked(sr, true);
10974
10975 // Should the service remain running? Note that in the
10976 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010977 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010978 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10979 if (sr.pendingStarts.size() == 0) {
10980 sr.startRequested = false;
10981 if (!hasClients) {
10982 // Whoops, no reason to restart!
10983 bringDownServiceLocked(sr, true);
10984 }
10985 }
10986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010987 }
10988 }
10989
10990 if (!allowRestart) {
10991 app.services.clear();
10992 }
10993 }
10994
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010995 // Make sure we have no more records on the stopping list.
10996 int i = mStoppingServices.size();
10997 while (i > 0) {
10998 i--;
10999 ServiceRecord sr = mStoppingServices.get(i);
11000 if (sr.app == app) {
11001 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011002 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011003 }
11004 }
11005
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011006 app.executingServices.clear();
11007 }
11008
11009 private final void removeDyingProviderLocked(ProcessRecord proc,
11010 ContentProviderRecord cpr) {
11011 synchronized (cpr) {
11012 cpr.launchingApp = null;
11013 cpr.notifyAll();
11014 }
11015
Amith Yamasani742a6712011-05-04 14:49:28 -070011016 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 String names[] = cpr.info.authority.split(";");
11018 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011019 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011020 }
11021
11022 Iterator<ProcessRecord> cit = cpr.clients.iterator();
11023 while (cit.hasNext()) {
11024 ProcessRecord capp = cit.next();
11025 if (!capp.persistent && capp.thread != null
11026 && capp.pid != 0
11027 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011028 Slog.i(TAG, "Kill " + capp.processName
11029 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011030 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070011031 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011032 capp.processName, capp.setAdj, "dying provider "
11033 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011034 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 }
11036 }
11037
11038 mLaunchingProviders.remove(cpr);
11039 }
11040
11041 /**
11042 * Main code for cleaning up a process when it has gone away. This is
11043 * called both as a result of the process dying, or directly when stopping
11044 * a process when running in single process mode.
11045 */
11046 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011047 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011048 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011049 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 }
11051
Dianne Hackborn36124872009-10-08 16:22:03 -070011052 mProcessesToGc.remove(app);
11053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011054 // Dismiss any open dialogs.
11055 if (app.crashDialog != null) {
11056 app.crashDialog.dismiss();
11057 app.crashDialog = null;
11058 }
11059 if (app.anrDialog != null) {
11060 app.anrDialog.dismiss();
11061 app.anrDialog = null;
11062 }
11063 if (app.waitDialog != null) {
11064 app.waitDialog.dismiss();
11065 app.waitDialog = null;
11066 }
11067
11068 app.crashing = false;
11069 app.notResponding = false;
11070
11071 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070011072 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011073 app.thread = null;
11074 app.forcingToForeground = null;
11075 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011076 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070011077 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011078 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011079
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011080 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011081
11082 boolean restart = false;
11083
11084 int NL = mLaunchingProviders.size();
11085
11086 // Remove published content providers.
11087 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011088 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011090 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011091 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011092 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011093
11094 // See if someone is waiting for this provider... in which
11095 // case we don't remove it, but just let it restart.
11096 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011097 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011098 for (; i<NL; i++) {
11099 if (mLaunchingProviders.get(i) == cpr) {
11100 restart = true;
11101 break;
11102 }
11103 }
11104 } else {
11105 i = NL;
11106 }
11107
11108 if (i >= NL) {
11109 removeDyingProviderLocked(app, cpr);
11110 NL = mLaunchingProviders.size();
11111 }
11112 }
11113 app.pubProviders.clear();
11114 }
11115
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011116 // Take care of any launching providers waiting for this process.
11117 if (checkAppInLaunchingProvidersLocked(app, false)) {
11118 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011121 // Unregister from connected content providers.
11122 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070011123 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011124 while (it.hasNext()) {
11125 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
11126 cpr.clients.remove(app);
11127 }
11128 app.conProviders.clear();
11129 }
11130
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011131 // At this point there may be remaining entries in mLaunchingProviders
11132 // where we were the only one waiting, so they are no longer of use.
11133 // Look for these and clean up if found.
11134 // XXX Commented out for now. Trying to figure out a way to reproduce
11135 // the actual situation to identify what is actually going on.
11136 if (false) {
11137 for (int i=0; i<NL; i++) {
11138 ContentProviderRecord cpr = (ContentProviderRecord)
11139 mLaunchingProviders.get(i);
11140 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
11141 synchronized (cpr) {
11142 cpr.launchingApp = null;
11143 cpr.notifyAll();
11144 }
11145 }
11146 }
11147 }
11148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 skipCurrentReceiverLocked(app);
11150
11151 // Unregister any receivers.
11152 if (app.receivers.size() > 0) {
11153 Iterator<ReceiverList> it = app.receivers.iterator();
11154 while (it.hasNext()) {
11155 removeReceiverLocked(it.next());
11156 }
11157 app.receivers.clear();
11158 }
11159
Christopher Tate181fafa2009-05-14 11:12:14 -070011160 // If the app is undergoing backup, tell the backup manager about it
11161 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011162 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070011163 try {
11164 IBackupManager bm = IBackupManager.Stub.asInterface(
11165 ServiceManager.getService(Context.BACKUP_SERVICE));
11166 bm.agentDisconnected(app.info.packageName);
11167 } catch (RemoteException e) {
11168 // can't happen; backup manager is local
11169 }
11170 }
11171
Jeff Sharkey287bd832011-05-28 19:36:26 -070011172 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011174 // If the caller is restarting this app, then leave it in its
11175 // current lists and let the caller take care of it.
11176 if (restarting) {
11177 return;
11178 }
11179
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011180 if (!app.persistent || app.isolated) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011181 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011183 mProcessNames.remove(app.processName, app.uid);
11184 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070011185 if (mHeavyWeightProcess == app) {
11186 mHeavyWeightProcess = null;
11187 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
11188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011189 } else if (!app.removed) {
11190 // This app is persistent, so we need to keep its record around.
11191 // If it is not already on the pending app list, add it there
11192 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011193 if (mPersistentStartingProcesses.indexOf(app) < 0) {
11194 mPersistentStartingProcesses.add(app);
11195 restart = true;
11196 }
11197 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011198 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
11199 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011200 mProcessesOnHold.remove(app);
11201
The Android Open Source Project4df24232009-03-05 14:34:35 -080011202 if (app == mHomeProcess) {
11203 mHomeProcess = null;
11204 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070011205 if (app == mPreviousProcess) {
11206 mPreviousProcess = null;
11207 }
11208
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011209 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011210 // We have components that still need to be running in the
11211 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011212 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011213 startProcessLocked(app, "restart", app.processName);
11214 } else if (app.pid > 0 && app.pid != MY_PID) {
11215 // Goodbye!
11216 synchronized (mPidsSelfLocked) {
11217 mPidsSelfLocked.remove(app.pid);
11218 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
11219 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070011220 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011221 }
11222 }
11223
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011224 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
11225 // Look through the content providers we are waiting to have launched,
11226 // and if any run in this process then either schedule a restart of
11227 // the process or kill the client waiting for it if this process has
11228 // gone bad.
11229 int NL = mLaunchingProviders.size();
11230 boolean restart = false;
11231 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011232 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011233 if (cpr.launchingApp == app) {
11234 if (!alwaysBad && !app.bad) {
11235 restart = true;
11236 } else {
11237 removeDyingProviderLocked(app, cpr);
11238 NL = mLaunchingProviders.size();
11239 }
11240 }
11241 }
11242 return restart;
11243 }
11244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011245 // =========================================================
11246 // SERVICES
11247 // =========================================================
11248
11249 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
11250 ActivityManager.RunningServiceInfo info =
11251 new ActivityManager.RunningServiceInfo();
11252 info.service = r.name;
11253 if (r.app != null) {
11254 info.pid = r.app.pid;
11255 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011256 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011257 info.process = r.processName;
11258 info.foreground = r.isForeground;
11259 info.activeSince = r.createTime;
11260 info.started = r.startRequested;
11261 info.clientCount = r.connections.size();
11262 info.crashCount = r.crashCount;
11263 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011264 if (r.isForeground) {
11265 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
11266 }
11267 if (r.startRequested) {
11268 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
11269 }
Dan Egnor42471dd2010-01-07 17:25:22 -080011270 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011271 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
11272 }
11273 if (r.app != null && r.app.persistent) {
11274 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
11275 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011276
11277 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
11278 for (int i=0; i<connl.size(); i++) {
11279 ConnectionRecord conn = connl.get(i);
11280 if (conn.clientLabel != 0) {
11281 info.clientPackage = conn.binding.client.info.packageName;
11282 info.clientLabel = conn.clientLabel;
11283 return info;
11284 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011285 }
11286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011287 return info;
11288 }
11289
11290 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11291 int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011292 enforceNotIsolatedCaller("getServices");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011293 synchronized (this) {
11294 ArrayList<ActivityManager.RunningServiceInfo> res
11295 = new ArrayList<ActivityManager.RunningServiceInfo>();
11296
Amith Yamasani742a6712011-05-04 14:49:28 -070011297 int userId = UserId.getUserId(Binder.getCallingUid());
11298 if (mServiceMap.getAllServices(userId).size() > 0) {
11299 Iterator<ServiceRecord> it
11300 = mServiceMap.getAllServices(userId).iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011301 while (it.hasNext() && res.size() < maxNum) {
11302 res.add(makeRunningServiceInfoLocked(it.next()));
11303 }
11304 }
11305
11306 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11307 ServiceRecord r = mRestartingServices.get(i);
11308 ActivityManager.RunningServiceInfo info =
11309 makeRunningServiceInfoLocked(r);
11310 info.restarting = r.nextRestartTime;
11311 res.add(info);
11312 }
11313
11314 return res;
11315 }
11316 }
11317
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011318 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011319 enforceNotIsolatedCaller("getRunningServiceControlPanel");
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011320 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011321 int userId = UserId.getUserId(Binder.getCallingUid());
11322 ServiceRecord r = mServiceMap.getServiceByName(name, userId);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011323 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011324 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11325 for (int i=0; i<conn.size(); i++) {
11326 if (conn.get(i).clientIntent != null) {
11327 return conn.get(i).clientIntent;
11328 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011329 }
11330 }
11331 }
11332 }
11333 return null;
11334 }
11335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011336 private final ServiceRecord findServiceLocked(ComponentName name,
11337 IBinder token) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011338 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 return r == token ? r : null;
11340 }
11341
11342 private final class ServiceLookupResult {
11343 final ServiceRecord record;
11344 final String permission;
11345
11346 ServiceLookupResult(ServiceRecord _record, String _permission) {
11347 record = _record;
11348 permission = _permission;
11349 }
11350 };
11351
11352 private ServiceLookupResult findServiceLocked(Intent service,
11353 String resolvedType) {
11354 ServiceRecord r = null;
11355 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011356 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011357 }
11358 if (r == null) {
11359 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani742a6712011-05-04 14:49:28 -070011360 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 }
11362
11363 if (r == null) {
11364 try {
11365 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011366 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011367 service, resolvedType, 0);
11368 ServiceInfo sInfo =
11369 rInfo != null ? rInfo.serviceInfo : null;
11370 if (sInfo == null) {
11371 return null;
11372 }
11373
11374 ComponentName name = new ComponentName(
11375 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011376 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011377 } catch (RemoteException ex) {
11378 // pm is in same process, this will never happen.
11379 }
11380 }
11381 if (r != null) {
11382 int callingPid = Binder.getCallingPid();
11383 int callingUid = Binder.getCallingUid();
11384 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011385 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011386 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011387 if (!r.exported) {
11388 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11389 + " from pid=" + callingPid
11390 + ", uid=" + callingUid
11391 + " that is not exported from uid " + r.appInfo.uid);
11392 return new ServiceLookupResult(null, "not exported from uid "
11393 + r.appInfo.uid);
11394 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011395 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011396 + " from pid=" + callingPid
11397 + ", uid=" + callingUid
11398 + " requires " + r.permission);
11399 return new ServiceLookupResult(null, r.permission);
11400 }
11401 return new ServiceLookupResult(r, null);
11402 }
11403 return null;
11404 }
11405
11406 private class ServiceRestarter implements Runnable {
11407 private ServiceRecord mService;
11408
11409 void setService(ServiceRecord service) {
11410 mService = service;
11411 }
11412
11413 public void run() {
11414 synchronized(ActivityManagerService.this) {
11415 performServiceRestartLocked(mService);
11416 }
11417 }
11418 }
11419
11420 private ServiceLookupResult retrieveServiceLocked(Intent service,
11421 String resolvedType, int callingPid, int callingUid) {
11422 ServiceRecord r = null;
Amith Yamasani742a6712011-05-04 14:49:28 -070011423 if (DEBUG_SERVICE)
11424 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
11425 + " origCallingUid=" + callingUid);
11426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011427 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011428 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011429 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011430 if (r == null) {
11431 Intent.FilterComparison filter = new Intent.FilterComparison(service);
11432 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
11433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011434 if (r == null) {
11435 try {
11436 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011437 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011438 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011439 ServiceInfo sInfo =
11440 rInfo != null ? rInfo.serviceInfo : null;
11441 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011442 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011443 ": not found");
11444 return null;
11445 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011446 if (Binder.getOrigCallingUser() > 0) {
11447 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo,
11448 Binder.getOrigCallingUser());
11449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 ComponentName name = new ComponentName(
11451 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011452 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 if (r == null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011454 Intent.FilterComparison filter = new Intent.FilterComparison(
11455 service.cloneFilter());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011456 ServiceRestarter res = new ServiceRestarter();
11457 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11458 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11459 synchronized (stats) {
11460 ss = stats.getServiceStatsLocked(
11461 sInfo.applicationInfo.uid, sInfo.packageName,
11462 sInfo.name);
11463 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080011464 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 res.setService(r);
Amith Yamasani742a6712011-05-04 14:49:28 -070011466 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11467 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011468
11469 // Make sure this component isn't in the pending list.
11470 int N = mPendingServices.size();
11471 for (int i=0; i<N; i++) {
11472 ServiceRecord pr = mPendingServices.get(i);
11473 if (pr.name.equals(name)) {
11474 mPendingServices.remove(i);
11475 i--;
11476 N--;
11477 }
11478 }
11479 }
11480 } catch (RemoteException ex) {
11481 // pm is in same process, this will never happen.
11482 }
11483 }
11484 if (r != null) {
11485 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011486 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011487 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011488 if (!r.exported) {
11489 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11490 + " from pid=" + callingPid
11491 + ", uid=" + callingUid
11492 + " that is not exported from uid " + r.appInfo.uid);
11493 return new ServiceLookupResult(null, "not exported from uid "
11494 + r.appInfo.uid);
11495 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011496 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011497 + " from pid=" + callingPid
11498 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011499 + " requires " + r.permission);
11500 return new ServiceLookupResult(null, r.permission);
11501 }
11502 return new ServiceLookupResult(r, null);
11503 }
11504 return null;
11505 }
11506
Dianne Hackborn287952c2010-09-22 22:34:31 -070011507 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11508 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11509 + why + " of " + r + " in app " + r.app);
11510 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11511 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011512 long now = SystemClock.uptimeMillis();
11513 if (r.executeNesting == 0 && r.app != null) {
11514 if (r.app.executingServices.size() == 0) {
11515 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11516 msg.obj = r.app;
11517 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11518 }
11519 r.app.executingServices.add(r);
11520 }
11521 r.executeNesting++;
11522 r.executingStart = now;
11523 }
11524
11525 private final void sendServiceArgsLocked(ServiceRecord r,
11526 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011527 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 if (N == 0) {
11529 return;
11530 }
11531
Dianne Hackborn39792d22010-08-19 18:01:52 -070011532 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011533 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011534 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011535 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11536 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011537 if (si.intent == null && N > 1) {
11538 // If somehow we got a dummy null intent in the middle,
11539 // then skip it. DO NOT skip a null intent when it is
11540 // the only one in the list -- this is to support the
11541 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011542 continue;
11543 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070011544 si.deliveredTime = SystemClock.uptimeMillis();
11545 r.deliveredStarts.add(si);
11546 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011547 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011548 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070011549 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070011550 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070011551 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011552 if (!oomAdjusted) {
11553 oomAdjusted = true;
11554 updateOomAdjLocked(r.app);
11555 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011556 int flags = 0;
11557 if (si.deliveryCount > 0) {
11558 flags |= Service.START_FLAG_RETRY;
11559 }
11560 if (si.doneExecutingCount > 0) {
11561 flags |= Service.START_FLAG_REDELIVERY;
11562 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011563 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011564 } catch (RemoteException e) {
11565 // Remote process gone... we'll let the normal cleanup take
11566 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011567 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011568 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011569 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011570 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011571 break;
11572 }
11573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011574 }
11575
11576 private final boolean requestServiceBindingLocked(ServiceRecord r,
11577 IntentBindRecord i, boolean rebind) {
11578 if (r.app == null || r.app.thread == null) {
11579 // If service is not currently running, can't yet bind.
11580 return false;
11581 }
11582 if ((!i.requested || rebind) && i.apps.size() > 0) {
11583 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011584 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11586 if (!rebind) {
11587 i.requested = true;
11588 }
11589 i.hasBound = true;
11590 i.doRebind = false;
11591 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011592 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011593 return false;
11594 }
11595 }
11596 return true;
11597 }
11598
11599 private final void requestServiceBindingsLocked(ServiceRecord r) {
11600 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11601 while (bindings.hasNext()) {
11602 IntentBindRecord i = bindings.next();
11603 if (!requestServiceBindingLocked(r, i, false)) {
11604 break;
11605 }
11606 }
11607 }
11608
11609 private final void realStartServiceLocked(ServiceRecord r,
11610 ProcessRecord app) throws RemoteException {
11611 if (app.thread == null) {
11612 throw new RemoteException();
11613 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011614 if (DEBUG_MU)
11615 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011616 + ", ProcessRecord.uid = " + app.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011617 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070011618 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011619
11620 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011621 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011622 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011623
11624 boolean created = false;
11625 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011626 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070011627 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011628 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011630 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011631 synchronized (r.stats.getBatteryStats()) {
11632 r.stats.startLaunchedLocked();
11633 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011634 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011635 app.thread.scheduleCreateService(r, r.serviceInfo,
11636 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011637 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011638 created = true;
11639 } finally {
11640 if (!created) {
11641 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011642 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011643 }
11644 }
11645
11646 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011647
11648 // If the service is in the started state, and there are no
11649 // pending arguments, then fake up one so its onStartCommand() will
11650 // be called.
11651 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011652 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11653 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011654 }
11655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011656 sendServiceArgsLocked(r, true);
11657 }
11658
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011659 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11660 boolean allowCancel) {
11661 boolean canceled = false;
11662
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011663 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011664 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070011665 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011666
Dianne Hackborn070783f2010-12-29 16:46:28 -080011667 if ((r.serviceInfo.applicationInfo.flags
11668 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11669 minDuration /= 4;
11670 }
11671
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011672 // Any delivered but not yet finished starts should be put back
11673 // on the pending list.
11674 final int N = r.deliveredStarts.size();
11675 if (N > 0) {
11676 for (int i=N-1; i>=0; i--) {
11677 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070011678 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011679 if (si.intent == null) {
11680 // We'll generate this again if needed.
11681 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11682 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11683 r.pendingStarts.add(0, si);
11684 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11685 dur *= 2;
11686 if (minDuration < dur) minDuration = dur;
11687 if (resetTime < dur) resetTime = dur;
11688 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011689 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011690 + r.name);
11691 canceled = true;
11692 }
11693 }
11694 r.deliveredStarts.clear();
11695 }
11696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011697 r.totalRestartCount++;
11698 if (r.restartDelay == 0) {
11699 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011700 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011701 } else {
11702 // If it has been a "reasonably long time" since the service
11703 // was started, then reset our restart duration back to
11704 // the beginning, so we don't infinitely increase the duration
11705 // on a service that just occasionally gets killed (which is
11706 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011707 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011708 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011709 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011710 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080011711 if ((r.serviceInfo.applicationInfo.flags
11712 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11713 // Services in peristent processes will restart much more
11714 // quickly, since they are pretty important. (Think SystemUI).
11715 r.restartDelay += minDuration/2;
11716 } else {
11717 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11718 if (r.restartDelay < minDuration) {
11719 r.restartDelay = minDuration;
11720 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011722 }
11723 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011724
11725 r.nextRestartTime = now + r.restartDelay;
11726
11727 // Make sure that we don't end up restarting a bunch of services
11728 // all at the same time.
11729 boolean repeat;
11730 do {
11731 repeat = false;
11732 for (int i=mRestartingServices.size()-1; i>=0; i--) {
11733 ServiceRecord r2 = mRestartingServices.get(i);
11734 if (r2 != r && r.nextRestartTime
11735 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11736 && r.nextRestartTime
11737 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11738 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11739 r.restartDelay = r.nextRestartTime - now;
11740 repeat = true;
11741 break;
11742 }
11743 }
11744 } while (repeat);
11745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 if (!mRestartingServices.contains(r)) {
11747 mRestartingServices.add(r);
11748 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011749
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011750 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011752 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011753 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011754 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011755 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011756 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080011757 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011758 r.shortName, r.restartDelay);
11759
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011760 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011761 }
11762
11763 final void performServiceRestartLocked(ServiceRecord r) {
11764 if (!mRestartingServices.contains(r)) {
11765 return;
11766 }
11767 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11768 }
11769
11770 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11771 if (r.restartDelay == 0) {
11772 return false;
11773 }
11774 r.resetRestartCounter();
11775 mRestartingServices.remove(r);
11776 mHandler.removeCallbacks(r.restarter);
11777 return true;
11778 }
11779
11780 private final boolean bringUpServiceLocked(ServiceRecord r,
11781 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011782 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 //r.dump(" ");
11784
Dianne Hackborn36124872009-10-08 16:22:03 -070011785 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011786 sendServiceArgsLocked(r, false);
11787 return true;
11788 }
11789
11790 if (!whileRestarting && r.restartDelay > 0) {
11791 // If waiting for a restart, then do nothing.
11792 return true;
11793 }
11794
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011795 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011796
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011797 // We are now bringing the service up, so no longer in the
11798 // restarting state.
11799 mRestartingServices.remove(r);
11800
Dianne Hackborne7f97212011-02-24 14:40:20 -080011801 // Service is now being launched, its package can't be stopped.
11802 try {
11803 AppGlobals.getPackageManager().setPackageStoppedState(
11804 r.packageName, false);
11805 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011806 } catch (IllegalArgumentException e) {
11807 Slog.w(TAG, "Failed trying to unstop package "
11808 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011809 }
11810
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011811 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011812 final String appName = r.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011813 ProcessRecord app;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011814
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011815 if (!isolated) {
11816 app = getProcessRecordLocked(appName, r.appInfo.uid);
11817 if (DEBUG_MU)
11818 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11819 if (app != null && app.thread != null) {
11820 try {
11821 app.addPackage(r.appInfo.packageName);
11822 realStartServiceLocked(r, app);
11823 return true;
11824 } catch (RemoteException e) {
11825 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11826 }
11827
11828 // If a dead object exception was thrown -- fall through to
11829 // restart the application.
11830 }
11831 } else {
11832 // If this service runs in an isolated process, then each time
11833 // we call startProcessLocked() we will get a new isolated
11834 // process, starting another process if we are currently waiting
11835 // for a previous process to come up. To deal with this, we store
11836 // in the service any current isolated process it is running in or
11837 // waiting to have come up.
11838 app = r.isolatedProc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011839 }
11840
Dianne Hackborn36124872009-10-08 16:22:03 -070011841 // Not running -- get it started, and enqueue this service record
11842 // to be executed when the app comes up.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011843 if (app == null) {
11844 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11845 "service", r.name, false, isolated)) == null) {
11846 Slog.w(TAG, "Unable to launch app "
11847 + r.appInfo.packageName + "/"
11848 + r.appInfo.uid + " for service "
11849 + r.intent.getIntent() + ": process is bad");
11850 bringDownServiceLocked(r, true);
11851 return false;
11852 }
11853 if (isolated) {
11854 r.isolatedProc = app;
11855 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011856 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011859 mPendingServices.add(r);
11860 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011862 return true;
11863 }
11864
11865 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011866 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 //r.dump(" ");
11868
11869 // Does it still need to run?
11870 if (!force && r.startRequested) {
11871 return;
11872 }
11873 if (r.connections.size() > 0) {
11874 if (!force) {
11875 // XXX should probably keep a count of the number of auto-create
11876 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011877 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011878 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011879 ArrayList<ConnectionRecord> cr = it.next();
11880 for (int i=0; i<cr.size(); i++) {
11881 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11882 return;
11883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011884 }
11885 }
11886 }
11887
11888 // Report to all of the connections that the service is no longer
11889 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011890 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011891 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011892 ArrayList<ConnectionRecord> c = it.next();
11893 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011894 ConnectionRecord cr = c.get(i);
11895 // There is still a connection to the service that is
11896 // being brought down. Mark it as dead.
11897 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011898 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011899 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011900 } catch (Exception e) {
11901 Slog.w(TAG, "Failure disconnecting service " + r.name +
11902 " to connection " + c.get(i).conn.asBinder() +
11903 " (in " + c.get(i).binding.client.processName + ")", e);
11904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011905 }
11906 }
11907 }
11908
11909 // Tell the service that it has been unbound.
11910 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11911 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11912 while (it.hasNext()) {
11913 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011914 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011915 + ": hasBound=" + ibr.hasBound);
11916 if (r.app != null && r.app.thread != null && ibr.hasBound) {
11917 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011918 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011919 updateOomAdjLocked(r.app);
11920 ibr.hasBound = false;
11921 r.app.thread.scheduleUnbindService(r,
11922 ibr.intent.getIntent());
11923 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011924 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011925 + r.shortName, e);
11926 serviceDoneExecutingLocked(r, true);
11927 }
11928 }
11929 }
11930 }
11931
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011932 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011933 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011934 System.identityHashCode(r), r.shortName,
11935 (r.app != null) ? r.app.pid : -1);
11936
Amith Yamasani742a6712011-05-04 14:49:28 -070011937 mServiceMap.removeServiceByName(r.name, r.userId);
11938 mServiceMap.removeServiceByIntent(r.intent, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011939 r.totalRestartCount = 0;
11940 unscheduleServiceRestartLocked(r);
11941
11942 // Also make sure it is not on the pending list.
11943 int N = mPendingServices.size();
11944 for (int i=0; i<N; i++) {
11945 if (mPendingServices.get(i) == r) {
11946 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011947 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011948 i--;
11949 N--;
11950 }
11951 }
11952
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011953 r.cancelNotification();
11954 r.isForeground = false;
11955 r.foregroundId = 0;
11956 r.foregroundNoti = null;
11957
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011958 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011959 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011960 r.pendingStarts.clear();
11961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011962 if (r.app != null) {
11963 synchronized (r.stats.getBatteryStats()) {
11964 r.stats.stopLaunchedLocked();
11965 }
11966 r.app.services.remove(r);
11967 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011968 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011969 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011970 mStoppingServices.add(r);
11971 updateOomAdjLocked(r.app);
11972 r.app.thread.scheduleStopService(r);
11973 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011974 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011975 + r.shortName, e);
11976 serviceDoneExecutingLocked(r, true);
11977 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011978 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011979 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011980 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011981 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011982 }
11983 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011984 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011985 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080011987
11988 if (r.bindings.size() > 0) {
11989 r.bindings.clear();
11990 }
11991
11992 if (r.restarter instanceof ServiceRestarter) {
11993 ((ServiceRestarter)r.restarter).setService(null);
11994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 }
11996
11997 ComponentName startServiceLocked(IApplicationThread caller,
11998 Intent service, String resolvedType,
11999 int callingPid, int callingUid) {
12000 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012001 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 + " type=" + resolvedType + " args=" + service.getExtras());
12003
12004 if (caller != null) {
12005 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12006 if (callerApp == null) {
12007 throw new SecurityException(
12008 "Unable to find app for caller " + caller
12009 + " (pid=" + Binder.getCallingPid()
12010 + ") when starting service " + service);
12011 }
12012 }
12013
12014 ServiceLookupResult res =
12015 retrieveServiceLocked(service, resolvedType,
12016 callingPid, callingUid);
12017 if (res == null) {
12018 return null;
12019 }
12020 if (res.record == null) {
12021 return new ComponentName("!", res.permission != null
12022 ? res.permission : "private to package");
12023 }
12024 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070012025 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
12026 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012027 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012028 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012029 }
12030 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012031 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012032 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070012033 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012034 r.lastActivity = SystemClock.uptimeMillis();
12035 synchronized (r.stats.getBatteryStats()) {
12036 r.stats.startRunningLocked();
12037 }
12038 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
12039 return new ComponentName("!", "Service process is bad");
12040 }
12041 return r.name;
12042 }
12043 }
12044
12045 public ComponentName startService(IApplicationThread caller, Intent service,
12046 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012047 enforceNotIsolatedCaller("startService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012048 // Refuse possible leaked file descriptors
12049 if (service != null && service.hasFileDescriptors() == true) {
12050 throw new IllegalArgumentException("File descriptors passed in Intent");
12051 }
12052
Amith Yamasani742a6712011-05-04 14:49:28 -070012053 if (DEBUG_SERVICE)
12054 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012055 synchronized(this) {
12056 final int callingPid = Binder.getCallingPid();
12057 final int callingUid = Binder.getCallingUid();
12058 final long origId = Binder.clearCallingIdentity();
12059 ComponentName res = startServiceLocked(caller, service,
12060 resolvedType, callingPid, callingUid);
12061 Binder.restoreCallingIdentity(origId);
12062 return res;
12063 }
12064 }
12065
12066 ComponentName startServiceInPackage(int uid,
12067 Intent service, String resolvedType) {
12068 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070012069 if (DEBUG_SERVICE)
12070 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 final long origId = Binder.clearCallingIdentity();
12072 ComponentName res = startServiceLocked(null, service,
12073 resolvedType, -1, uid);
12074 Binder.restoreCallingIdentity(origId);
12075 return res;
12076 }
12077 }
12078
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012079 private void stopServiceLocked(ServiceRecord service) {
12080 synchronized (service.stats.getBatteryStats()) {
12081 service.stats.stopRunningLocked();
12082 }
12083 service.startRequested = false;
12084 service.callStart = false;
12085 bringDownServiceLocked(service, false);
12086 }
12087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012088 public int stopService(IApplicationThread caller, Intent service,
12089 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012090 enforceNotIsolatedCaller("stopService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012091 // Refuse possible leaked file descriptors
12092 if (service != null && service.hasFileDescriptors() == true) {
12093 throw new IllegalArgumentException("File descriptors passed in Intent");
12094 }
12095
12096 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012097 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012098 + " type=" + resolvedType);
12099
12100 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12101 if (caller != null && callerApp == null) {
12102 throw new SecurityException(
12103 "Unable to find app for caller " + caller
12104 + " (pid=" + Binder.getCallingPid()
12105 + ") when stopping service " + service);
12106 }
12107
12108 // If this service is active, make sure it is stopped.
12109 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12110 if (r != null) {
12111 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012112 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012113 try {
12114 stopServiceLocked(r.record);
12115 } finally {
12116 Binder.restoreCallingIdentity(origId);
12117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118 return 1;
12119 }
12120 return -1;
12121 }
12122 }
12123
12124 return 0;
12125 }
12126
12127 public IBinder peekService(Intent service, String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012128 enforceNotIsolatedCaller("peekService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012129 // Refuse possible leaked file descriptors
12130 if (service != null && service.hasFileDescriptors() == true) {
12131 throw new IllegalArgumentException("File descriptors passed in Intent");
12132 }
12133
12134 IBinder ret = null;
12135
12136 synchronized(this) {
12137 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12138
12139 if (r != null) {
12140 // r.record is null if findServiceLocked() failed the caller permission check
12141 if (r.record == null) {
12142 throw new SecurityException(
12143 "Permission Denial: Accessing service " + r.record.name
12144 + " from pid=" + Binder.getCallingPid()
12145 + ", uid=" + Binder.getCallingUid()
12146 + " requires " + r.permission);
12147 }
12148 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
12149 if (ib != null) {
12150 ret = ib.binder;
12151 }
12152 }
12153 }
12154
12155 return ret;
12156 }
12157
12158 public boolean stopServiceToken(ComponentName className, IBinder token,
12159 int startId) {
12160 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012161 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012162 + " " + token + " startId=" + startId);
12163 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012164 if (r != null) {
12165 if (startId >= 0) {
12166 // Asked to only stop if done with all work. Note that
12167 // to avoid leaks, we will take this as dropping all
12168 // start items up to and including this one.
12169 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12170 if (si != null) {
12171 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070012172 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
12173 cur.removeUriPermissionsLocked();
12174 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012175 break;
12176 }
12177 }
12178 }
12179
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012180 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012181 return false;
12182 }
12183
12184 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012185 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012186 + " is last, but have " + r.deliveredStarts.size()
12187 + " remaining args");
12188 }
12189 }
12190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012191 synchronized (r.stats.getBatteryStats()) {
12192 r.stats.stopRunningLocked();
12193 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012194 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012195 }
12196 final long origId = Binder.clearCallingIdentity();
12197 bringDownServiceLocked(r, false);
12198 Binder.restoreCallingIdentity(origId);
12199 return true;
12200 }
12201 }
12202 return false;
12203 }
12204
12205 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012206 int id, Notification notification, boolean removeNotification) {
12207 final long origId = Binder.clearCallingIdentity();
12208 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012209 synchronized(this) {
12210 ServiceRecord r = findServiceLocked(className, token);
12211 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012212 if (id != 0) {
12213 if (notification == null) {
12214 throw new IllegalArgumentException("null notification");
12215 }
12216 if (r.foregroundId != id) {
12217 r.cancelNotification();
12218 r.foregroundId = id;
12219 }
12220 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
12221 r.foregroundNoti = notification;
12222 r.isForeground = true;
12223 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 if (r.app != null) {
12225 updateServiceForegroundLocked(r.app, true);
12226 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012227 } else {
12228 if (r.isForeground) {
12229 r.isForeground = false;
12230 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070012231 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012232 updateServiceForegroundLocked(r.app, true);
12233 }
12234 }
12235 if (removeNotification) {
12236 r.cancelNotification();
12237 r.foregroundId = 0;
12238 r.foregroundNoti = null;
12239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012240 }
12241 }
12242 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012243 } finally {
12244 Binder.restoreCallingIdentity(origId);
12245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 }
12247
12248 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
12249 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070012250 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012251 if (sr.isForeground) {
12252 anyForeground = true;
12253 break;
12254 }
12255 }
12256 if (anyForeground != proc.foregroundServices) {
12257 proc.foregroundServices = anyForeground;
12258 if (oomAdj) {
12259 updateOomAdjLocked();
12260 }
12261 }
12262 }
12263
12264 public int bindService(IApplicationThread caller, IBinder token,
12265 Intent service, String resolvedType,
12266 IServiceConnection connection, int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012267 enforceNotIsolatedCaller("bindService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 // Refuse possible leaked file descriptors
12269 if (service != null && service.hasFileDescriptors() == true) {
12270 throw new IllegalArgumentException("File descriptors passed in Intent");
12271 }
12272
12273 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012274 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275 + " type=" + resolvedType + " conn=" + connection.asBinder()
12276 + " flags=0x" + Integer.toHexString(flags));
Amith Yamasani742a6712011-05-04 14:49:28 -070012277 if (DEBUG_MU)
12278 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12279 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012280 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12281 if (callerApp == null) {
12282 throw new SecurityException(
12283 "Unable to find app for caller " + caller
12284 + " (pid=" + Binder.getCallingPid()
12285 + ") when binding service " + service);
12286 }
12287
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012288 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012290 activity = mMainStack.isInStackLocked(token);
12291 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012292 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012293 return 0;
12294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012295 }
12296
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012297 int clientLabel = 0;
12298 PendingIntent clientIntent = null;
12299
12300 if (callerApp.info.uid == Process.SYSTEM_UID) {
12301 // Hacky kind of thing -- allow system stuff to tell us
12302 // what they are, so we can report this elsewhere for
12303 // others to know why certain services are running.
12304 try {
12305 clientIntent = (PendingIntent)service.getParcelableExtra(
12306 Intent.EXTRA_CLIENT_INTENT);
12307 } catch (RuntimeException e) {
12308 }
12309 if (clientIntent != null) {
12310 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12311 if (clientLabel != 0) {
12312 // There are no useful extras in the intent, trash them.
12313 // System code calling with this stuff just needs to know
12314 // this will happen.
12315 service = service.cloneFilter();
12316 }
12317 }
12318 }
12319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012320 ServiceLookupResult res =
12321 retrieveServiceLocked(service, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -070012322 Binder.getCallingPid(), Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012323 if (res == null) {
12324 return 0;
12325 }
12326 if (res.record == null) {
12327 return -1;
12328 }
12329 ServiceRecord s = res.record;
12330
12331 final long origId = Binder.clearCallingIdentity();
12332
12333 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012334 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012335 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336 }
12337
12338 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12339 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012340 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341
12342 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012343 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12344 if (clist == null) {
12345 clist = new ArrayList<ConnectionRecord>();
12346 s.connections.put(binder, clist);
12347 }
12348 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 b.connections.add(c);
12350 if (activity != null) {
12351 if (activity.connections == null) {
12352 activity.connections = new HashSet<ConnectionRecord>();
12353 }
12354 activity.connections.add(c);
12355 }
12356 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012357 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12358 b.client.hasAboveClient = true;
12359 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012360 clist = mServiceConnections.get(binder);
12361 if (clist == null) {
12362 clist = new ArrayList<ConnectionRecord>();
12363 mServiceConnections.put(binder, clist);
12364 }
12365 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012366
12367 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12368 s.lastActivity = SystemClock.uptimeMillis();
12369 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12370 return 0;
12371 }
12372 }
12373
12374 if (s.app != null) {
12375 // This could have made the service more important.
12376 updateOomAdjLocked(s.app);
12377 }
12378
Joe Onorato8a9b2202010-02-26 18:56:32 -080012379 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012380 + ": received=" + b.intent.received
12381 + " apps=" + b.intent.apps.size()
12382 + " doRebind=" + b.intent.doRebind);
12383
12384 if (s.app != null && b.intent.received) {
12385 // Service is already running, so we can immediately
12386 // publish the connection.
12387 try {
12388 c.conn.connected(s.name, b.intent.binder);
12389 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012390 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012391 + " to connection " + c.conn.asBinder()
12392 + " (in " + c.binding.client.processName + ")", e);
12393 }
12394
12395 // If this is the first app connected back to this binding,
12396 // and the service had previously asked to be told when
12397 // rebound, then do so.
12398 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12399 requestServiceBindingLocked(s, b.intent, true);
12400 }
12401 } else if (!b.intent.requested) {
12402 requestServiceBindingLocked(s, b.intent, false);
12403 }
12404
12405 Binder.restoreCallingIdentity(origId);
12406 }
12407
12408 return 1;
12409 }
12410
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012411 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012412 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413 IBinder binder = c.conn.asBinder();
12414 AppBindRecord b = c.binding;
12415 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012416 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12417 if (clist != null) {
12418 clist.remove(c);
12419 if (clist.size() == 0) {
12420 s.connections.remove(binder);
12421 }
12422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012423 b.connections.remove(c);
12424 if (c.activity != null && c.activity != skipAct) {
12425 if (c.activity.connections != null) {
12426 c.activity.connections.remove(c);
12427 }
12428 }
12429 if (b.client != skipApp) {
12430 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012431 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12432 b.client.updateHasAboveClientLocked();
12433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012434 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012435 clist = mServiceConnections.get(binder);
12436 if (clist != null) {
12437 clist.remove(c);
12438 if (clist.size() == 0) {
12439 mServiceConnections.remove(binder);
12440 }
12441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012442
12443 if (b.connections.size() == 0) {
12444 b.intent.apps.remove(b.client);
12445 }
12446
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012447 if (!c.serviceDead) {
12448 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12449 + ": shouldUnbind=" + b.intent.hasBound);
12450 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12451 && b.intent.hasBound) {
12452 try {
12453 bumpServiceExecutingLocked(s, "unbind");
12454 updateOomAdjLocked(s.app);
12455 b.intent.hasBound = false;
12456 // Assume the client doesn't want to know about a rebind;
12457 // we will deal with that later if it asks for one.
12458 b.intent.doRebind = false;
12459 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12460 } catch (Exception e) {
12461 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12462 serviceDoneExecutingLocked(s, true);
12463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012465
12466 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12467 bringDownServiceLocked(s, false);
12468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012469 }
12470 }
12471
12472 public boolean unbindService(IServiceConnection connection) {
12473 synchronized (this) {
12474 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012475 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012476 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12477 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012478 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012479 + connection.asBinder());
12480 return false;
12481 }
12482
12483 final long origId = Binder.clearCallingIdentity();
12484
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012485 while (clist.size() > 0) {
12486 ConnectionRecord r = clist.get(0);
12487 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012488
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012489 if (r.binding.service.app != null) {
12490 // This could have made the service less important.
12491 updateOomAdjLocked(r.binding.service.app);
12492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012493 }
12494
12495 Binder.restoreCallingIdentity(origId);
12496 }
12497
12498 return true;
12499 }
12500
12501 public void publishService(IBinder token, Intent intent, IBinder service) {
12502 // Refuse possible leaked file descriptors
12503 if (intent != null && intent.hasFileDescriptors() == true) {
12504 throw new IllegalArgumentException("File descriptors passed in Intent");
12505 }
12506
12507 synchronized(this) {
12508 if (!(token instanceof ServiceRecord)) {
12509 throw new IllegalArgumentException("Invalid service token");
12510 }
12511 ServiceRecord r = (ServiceRecord)token;
12512
12513 final long origId = Binder.clearCallingIdentity();
12514
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012515 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012516 + " " + intent + ": " + service);
12517 if (r != null) {
12518 Intent.FilterComparison filter
12519 = new Intent.FilterComparison(intent);
12520 IntentBindRecord b = r.bindings.get(filter);
12521 if (b != null && !b.received) {
12522 b.binder = service;
12523 b.requested = true;
12524 b.received = true;
12525 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012526 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012527 = r.connections.values().iterator();
12528 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012529 ArrayList<ConnectionRecord> clist = it.next();
12530 for (int i=0; i<clist.size(); i++) {
12531 ConnectionRecord c = clist.get(i);
12532 if (!filter.equals(c.binding.intent.intent)) {
12533 if (DEBUG_SERVICE) Slog.v(
12534 TAG, "Not publishing to: " + c);
12535 if (DEBUG_SERVICE) Slog.v(
12536 TAG, "Bound intent: " + c.binding.intent.intent);
12537 if (DEBUG_SERVICE) Slog.v(
12538 TAG, "Published intent: " + intent);
12539 continue;
12540 }
12541 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12542 try {
12543 c.conn.connected(r.name, service);
12544 } catch (Exception e) {
12545 Slog.w(TAG, "Failure sending service " + r.name +
12546 " to connection " + c.conn.asBinder() +
12547 " (in " + c.binding.client.processName + ")", e);
12548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012549 }
12550 }
12551 }
12552 }
12553
12554 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12555
12556 Binder.restoreCallingIdentity(origId);
12557 }
12558 }
12559 }
12560
12561 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12562 // Refuse possible leaked file descriptors
12563 if (intent != null && intent.hasFileDescriptors() == true) {
12564 throw new IllegalArgumentException("File descriptors passed in Intent");
12565 }
12566
12567 synchronized(this) {
12568 if (!(token instanceof ServiceRecord)) {
12569 throw new IllegalArgumentException("Invalid service token");
12570 }
12571 ServiceRecord r = (ServiceRecord)token;
12572
12573 final long origId = Binder.clearCallingIdentity();
12574
12575 if (r != null) {
12576 Intent.FilterComparison filter
12577 = new Intent.FilterComparison(intent);
12578 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012579 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012580 + " at " + b + ": apps="
12581 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020012582
12583 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012584 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020012585 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012586 // Applications have already bound since the last
12587 // unbind, so just rebind right here.
12588 requestServiceBindingLocked(r, b, true);
12589 } else {
12590 // Note to tell the service the next time there is
12591 // a new client.
12592 b.doRebind = true;
12593 }
12594 }
12595
Per Edelberg78f9fff2010-08-30 20:01:35 +020012596 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012597
12598 Binder.restoreCallingIdentity(origId);
12599 }
12600 }
12601 }
12602
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012603 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012604 synchronized(this) {
12605 if (!(token instanceof ServiceRecord)) {
12606 throw new IllegalArgumentException("Invalid service token");
12607 }
12608 ServiceRecord r = (ServiceRecord)token;
12609 boolean inStopping = mStoppingServices.contains(token);
12610 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012611 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012612 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012613 + " with incorrect token: given " + token
12614 + ", expected " + r);
12615 return;
12616 }
12617
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012618 if (type == 1) {
12619 // This is a call from a service start... take care of
12620 // book-keeping.
12621 r.callStart = true;
12622 switch (res) {
12623 case Service.START_STICKY_COMPATIBILITY:
12624 case Service.START_STICKY: {
12625 // We are done with the associated start arguments.
12626 r.findDeliveredStart(startId, true);
12627 // Don't stop if killed.
12628 r.stopIfKilled = false;
12629 break;
12630 }
12631 case Service.START_NOT_STICKY: {
12632 // We are done with the associated start arguments.
12633 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012634 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012635 // There is no more work, and this service
12636 // doesn't want to hang around if killed.
12637 r.stopIfKilled = true;
12638 }
12639 break;
12640 }
12641 case Service.START_REDELIVER_INTENT: {
12642 // We'll keep this item until they explicitly
12643 // call stop for it, but keep track of the fact
12644 // that it was delivered.
12645 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12646 if (si != null) {
12647 si.deliveryCount = 0;
12648 si.doneExecutingCount++;
12649 // Don't stop if killed.
12650 r.stopIfKilled = true;
12651 }
12652 break;
12653 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012654 case Service.START_TASK_REMOVED_COMPLETE: {
12655 // Special processing for onTaskRemoved(). Don't
12656 // impact normal onStartCommand() processing.
12657 r.findDeliveredStart(startId, true);
12658 break;
12659 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012660 default:
12661 throw new IllegalArgumentException(
12662 "Unknown service start result: " + res);
12663 }
12664 if (res == Service.START_STICKY_COMPATIBILITY) {
12665 r.callStart = false;
12666 }
12667 }
Amith Yamasani742a6712011-05-04 14:49:28 -070012668 if (DEBUG_MU)
12669 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12670 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012671 final long origId = Binder.clearCallingIdentity();
12672 serviceDoneExecutingLocked(r, inStopping);
12673 Binder.restoreCallingIdentity(origId);
12674 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012675 Slog.w(TAG, "Done executing unknown service from pid "
12676 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012677 }
12678 }
12679 }
12680
12681 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012682 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12683 + ": nesting=" + r.executeNesting
12684 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012685 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012686 r.executeNesting--;
12687 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012688 if (DEBUG_SERVICE) Slog.v(TAG,
12689 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012690 r.app.executingServices.remove(r);
12691 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012692 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12693 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12695 }
12696 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012697 if (DEBUG_SERVICE) Slog.v(TAG,
12698 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012699 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020012700 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012701 }
12702 updateOomAdjLocked(r.app);
12703 }
12704 }
12705
12706 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012707 String anrMessage = null;
12708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012709 synchronized(this) {
12710 if (proc.executingServices.size() == 0 || proc.thread == null) {
12711 return;
12712 }
12713 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12714 Iterator<ServiceRecord> it = proc.executingServices.iterator();
12715 ServiceRecord timeout = null;
12716 long nextTime = 0;
12717 while (it.hasNext()) {
12718 ServiceRecord sr = it.next();
12719 if (sr.executingStart < maxTime) {
12720 timeout = sr;
12721 break;
12722 }
12723 if (sr.executingStart > nextTime) {
12724 nextTime = sr.executingStart;
12725 }
12726 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012727 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012728 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012729 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012730 } else {
12731 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12732 msg.obj = proc;
12733 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12734 }
12735 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012736
12737 if (anrMessage != null) {
12738 appNotResponding(proc, null, null, anrMessage);
12739 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012740 }
12741
12742 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070012743 // BACKUP AND RESTORE
12744 // =========================================================
12745
12746 // Cause the target app to be launched if necessary and its backup agent
12747 // instantiated. The backup agent will invoke backupAgentCreated() on the
12748 // activity manager to announce its creation.
12749 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012750 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012751 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12752
12753 synchronized(this) {
12754 // !!! TODO: currently no check here that we're already bound
12755 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12756 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12757 synchronized (stats) {
12758 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12759 }
12760
Dianne Hackborne7f97212011-02-24 14:40:20 -080012761 // Backup agent is now in use, its package can't be stopped.
12762 try {
12763 AppGlobals.getPackageManager().setPackageStoppedState(
12764 app.packageName, false);
12765 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012766 } catch (IllegalArgumentException e) {
12767 Slog.w(TAG, "Failed trying to unstop package "
12768 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012769 }
12770
Christopher Tate181fafa2009-05-14 11:12:14 -070012771 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070012772 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12773 ? new ComponentName(app.packageName, app.backupAgentName)
12774 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070012775 // startProcessLocked() returns existing proc's record if it's already running
12776 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080012777 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070012778 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012779 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070012780 return false;
12781 }
12782
12783 r.app = proc;
12784 mBackupTarget = r;
12785 mBackupAppName = app.packageName;
12786
Christopher Tate6fa95972009-06-05 18:43:55 -070012787 // Try not to kill the process during backup
12788 updateOomAdjLocked(proc);
12789
Christopher Tate181fafa2009-05-14 11:12:14 -070012790 // If the process is already attached, schedule the creation of the backup agent now.
12791 // If it is not yet live, this will be done when it attaches to the framework.
12792 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012793 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070012794 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012795 proc.thread.scheduleCreateBackupAgent(app,
12796 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012797 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070012798 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070012799 }
12800 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012801 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070012802 }
12803 // Invariants: at this point, the target app process exists and the application
12804 // is either already running or in the process of coming up. mBackupTarget and
12805 // mBackupAppName describe the app, so that when it binds back to the AM we
12806 // know that it's scheduled for a backup-agent operation.
12807 }
12808
12809 return true;
12810 }
12811
12812 // A backup agent has just come up
12813 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012814 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070012815 + " = " + agent);
12816
12817 synchronized(this) {
12818 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012819 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070012820 return;
12821 }
Dianne Hackborn06740692010-09-22 22:46:21 -070012822 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012823
Dianne Hackborn06740692010-09-22 22:46:21 -070012824 long oldIdent = Binder.clearCallingIdentity();
12825 try {
12826 IBackupManager bm = IBackupManager.Stub.asInterface(
12827 ServiceManager.getService(Context.BACKUP_SERVICE));
12828 bm.agentConnected(agentPackageName, agent);
12829 } catch (RemoteException e) {
12830 // can't happen; the backup manager service is local
12831 } catch (Exception e) {
12832 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12833 e.printStackTrace();
12834 } finally {
12835 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070012836 }
12837 }
12838
12839 // done with this agent
12840 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012841 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070012842 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012843 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070012844 return;
12845 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012846
12847 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070012848 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012849 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070012850 return;
12851 }
12852
Christopher Tate181fafa2009-05-14 11:12:14 -070012853 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012854 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070012855 return;
12856 }
12857
Christopher Tate6fa95972009-06-05 18:43:55 -070012858 ProcessRecord proc = mBackupTarget.app;
12859 mBackupTarget = null;
12860 mBackupAppName = null;
12861
12862 // Not backing this app up any more; reset its OOM adjustment
12863 updateOomAdjLocked(proc);
12864
Christopher Tatec7b31e32009-06-10 15:49:30 -070012865 // If the app crashed during backup, 'thread' will be null here
12866 if (proc.thread != null) {
12867 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012868 proc.thread.scheduleDestroyBackupAgent(appInfo,
12869 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070012870 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012871 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070012872 e.printStackTrace();
12873 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012874 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012875 }
12876 }
12877 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012878 // BROADCASTS
12879 // =========================================================
12880
Josh Bartel7f208742010-02-25 11:01:44 -060012881 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012882 List cur) {
12883 final ContentResolver resolver = mContext.getContentResolver();
12884 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12885 if (list == null) {
12886 return cur;
12887 }
12888 int N = list.size();
12889 for (int i=0; i<N; i++) {
12890 Intent intent = list.get(i);
12891 if (filter.match(resolver, intent, true, TAG) >= 0) {
12892 if (cur == null) {
12893 cur = new ArrayList<Intent>();
12894 }
12895 cur.add(intent);
12896 }
12897 }
12898 return cur;
12899 }
12900
Christopher Tatef46723b2012-01-26 14:19:24 -080012901 boolean isPendingBroadcastProcessLocked(int pid) {
12902 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12903 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012905
Christopher Tatef46723b2012-01-26 14:19:24 -080012906 void skipPendingBroadcastLocked(int pid) {
12907 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12908 for (BroadcastQueue queue : mBroadcastQueues) {
12909 queue.skipPendingBroadcastLocked(pid);
12910 }
12911 }
12912
12913 // The app just attached; send any pending broadcasts that it should receive
12914 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12915 boolean didSomething = false;
12916 for (BroadcastQueue queue : mBroadcastQueues) {
12917 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012918 }
Christopher Tatef46723b2012-01-26 14:19:24 -080012919 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012920 }
12921
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012922 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012923 IIntentReceiver receiver, IntentFilter filter, String permission) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012924 enforceNotIsolatedCaller("registerReceiver");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012925 synchronized(this) {
12926 ProcessRecord callerApp = null;
12927 if (caller != null) {
12928 callerApp = getRecordForAppLocked(caller);
12929 if (callerApp == null) {
12930 throw new SecurityException(
12931 "Unable to find app for caller " + caller
12932 + " (pid=" + Binder.getCallingPid()
12933 + ") when registering receiver " + receiver);
12934 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012935 if (callerApp.info.uid != Process.SYSTEM_UID &&
12936 !callerApp.pkgList.contains(callerPackage)) {
12937 throw new SecurityException("Given caller package " + callerPackage
12938 + " is not running in process " + callerApp);
12939 }
12940 } else {
12941 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012942 }
12943
12944 List allSticky = null;
12945
12946 // Look for any matching sticky broadcasts...
12947 Iterator actions = filter.actionsIterator();
12948 if (actions != null) {
12949 while (actions.hasNext()) {
12950 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012951 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012952 }
12953 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012954 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012955 }
12956
12957 // The first sticky in the list is returned directly back to
12958 // the client.
12959 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12960
Joe Onorato8a9b2202010-02-26 18:56:32 -080012961 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012962 + ": " + sticky);
12963
12964 if (receiver == null) {
12965 return sticky;
12966 }
12967
12968 ReceiverList rl
12969 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12970 if (rl == null) {
12971 rl = new ReceiverList(this, callerApp,
12972 Binder.getCallingPid(),
12973 Binder.getCallingUid(), receiver);
12974 if (rl.app != null) {
12975 rl.app.receivers.add(rl);
12976 } else {
12977 try {
12978 receiver.asBinder().linkToDeath(rl, 0);
12979 } catch (RemoteException e) {
12980 return sticky;
12981 }
12982 rl.linkedToDeath = true;
12983 }
12984 mRegisteredReceivers.put(receiver.asBinder(), rl);
12985 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012986 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012987 rl.add(bf);
12988 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012989 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012990 }
12991 mReceiverResolver.addFilter(bf);
12992
12993 // Enqueue broadcasts for all existing stickies that match
12994 // this filter.
12995 if (allSticky != null) {
12996 ArrayList receivers = new ArrayList();
12997 receivers.add(bf);
12998
12999 int N = allSticky.size();
13000 for (int i=0; i<N; i++) {
13001 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080013002 BroadcastQueue queue = broadcastQueueForIntent(intent);
13003 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013005 false, true, true);
Christopher Tatef46723b2012-01-26 14:19:24 -080013006 queue.enqueueParallelBroadcastLocked(r);
13007 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013008 }
13009 }
13010
13011 return sticky;
13012 }
13013 }
13014
13015 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013016 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017
Christopher Tatef46723b2012-01-26 14:19:24 -080013018 final long origId = Binder.clearCallingIdentity();
13019 try {
13020 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013021
Christopher Tatef46723b2012-01-26 14:19:24 -080013022 synchronized(this) {
13023 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013024 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080013025 if (rl != null) {
13026 if (rl.curBroadcast != null) {
13027 BroadcastRecord r = rl.curBroadcast;
13028 final boolean doNext = finishReceiverLocked(
13029 receiver.asBinder(), r.resultCode, r.resultData,
13030 r.resultExtras, r.resultAbort, true);
13031 if (doNext) {
13032 doTrim = true;
13033 r.queue.processNextBroadcast(false);
13034 }
13035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013036
Christopher Tatef46723b2012-01-26 14:19:24 -080013037 if (rl.app != null) {
13038 rl.app.receivers.remove(rl);
13039 }
13040 removeReceiverLocked(rl);
13041 if (rl.linkedToDeath) {
13042 rl.linkedToDeath = false;
13043 rl.receiver.asBinder().unlinkToDeath(rl, 0);
13044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013045 }
13046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013047
Christopher Tatef46723b2012-01-26 14:19:24 -080013048 // If we actually concluded any broadcasts, we might now be able
13049 // to trim the recipients' apps from our working set
13050 if (doTrim) {
13051 trimApplications();
13052 return;
13053 }
13054
13055 } finally {
13056 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013058 }
13059
13060 void removeReceiverLocked(ReceiverList rl) {
13061 mRegisteredReceivers.remove(rl.receiver.asBinder());
13062 int N = rl.size();
13063 for (int i=0; i<N; i++) {
13064 mReceiverResolver.removeFilter(rl.get(i));
13065 }
13066 }
13067
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013068 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
13069 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13070 ProcessRecord r = mLruProcesses.get(i);
13071 if (r.thread != null) {
13072 try {
13073 r.thread.dispatchPackageBroadcast(cmd, packages);
13074 } catch (RemoteException ex) {
13075 }
13076 }
13077 }
13078 }
13079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013080 private final int broadcastIntentLocked(ProcessRecord callerApp,
13081 String callerPackage, Intent intent, String resolvedType,
13082 IIntentReceiver resultTo, int resultCode, String resultData,
13083 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013084 boolean ordered, boolean sticky, int callingPid, int callingUid,
13085 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013086 intent = new Intent(intent);
13087
Dianne Hackborne7f97212011-02-24 14:40:20 -080013088 // By default broadcasts do not go to stopped apps.
13089 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13090
Joe Onorato8a9b2202010-02-26 18:56:32 -080013091 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013092 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13093 + " ordered=" + ordered);
13094 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013095 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013096 }
13097
13098 // Handle special intents: if this broadcast is from the package
13099 // manager about a package being removed, we need to remove all of
13100 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013101 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013102 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013103 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13104 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013105 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013106 || uidRemoved) {
13107 if (checkComponentPermission(
13108 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013109 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013110 == PackageManager.PERMISSION_GRANTED) {
13111 if (uidRemoved) {
13112 final Bundle intentExtras = intent.getExtras();
13113 final int uid = intentExtras != null
13114 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13115 if (uid >= 0) {
13116 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13117 synchronized (bs) {
13118 bs.removeUidStatsLocked(uid);
13119 }
13120 }
13121 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013122 // If resources are unvailble just force stop all
13123 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013124 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013125 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13126 if (list != null && (list.length > 0)) {
13127 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070013128 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013129 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013130 sendPackageBroadcastLocked(
13131 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013132 }
13133 } else {
13134 Uri data = intent.getData();
13135 String ssp;
13136 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13137 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13138 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070013139 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070013140 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013141 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013142 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13143 new String[] {ssp});
13144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 }
13146 }
13147 }
13148 } else {
13149 String msg = "Permission Denial: " + intent.getAction()
13150 + " broadcast from " + callerPackage + " (pid=" + callingPid
13151 + ", uid=" + callingUid + ")"
13152 + " requires "
13153 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013154 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 throw new SecurityException(msg);
13156 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013157
13158 // Special case for adding a package: by default turn on compatibility
13159 // mode.
13160 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070013161 Uri data = intent.getData();
13162 String ssp;
13163 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13164 mCompatModePackages.handlePackageAddedLocked(ssp,
13165 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013167 }
13168
13169 /*
13170 * If this is the time zone changed action, queue up a message that will reset the timezone
13171 * of all currently running processes. This message will get queued up before the broadcast
13172 * happens.
13173 */
13174 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13175 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13176 }
13177
Robert Greenwalt03595d02010-11-02 14:08:23 -070013178 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13179 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
13180 }
13181
Robert Greenwalt434203a2010-10-11 16:00:27 -070013182 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13183 ProxyProperties proxy = intent.getParcelableExtra("proxy");
13184 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
13185 }
13186
Dianne Hackborn854060af2009-07-09 18:14:31 -070013187 /*
13188 * Prevent non-system code (defined here to be non-persistent
13189 * processes) from sending protected broadcasts.
13190 */
13191 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
13192 || callingUid == Process.SHELL_UID || callingUid == 0) {
13193 // Always okay.
13194 } else if (callerApp == null || !callerApp.persistent) {
13195 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013196 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070013197 intent.getAction())) {
13198 String msg = "Permission Denial: not allowed to send broadcast "
13199 + intent.getAction() + " from pid="
13200 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013201 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013202 throw new SecurityException(msg);
13203 }
13204 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013205 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013206 return BROADCAST_SUCCESS;
13207 }
13208 }
13209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013210 // Add to the sticky list if requested.
13211 if (sticky) {
13212 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13213 callingPid, callingUid)
13214 != PackageManager.PERMISSION_GRANTED) {
13215 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13216 + callingPid + ", uid=" + callingUid
13217 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013218 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013219 throw new SecurityException(msg);
13220 }
13221 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013222 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013223 + " and enforce permission " + requiredPermission);
13224 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13225 }
13226 if (intent.getComponent() != null) {
13227 throw new SecurityException(
13228 "Sticky broadcasts can't target a specific component");
13229 }
13230 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13231 if (list == null) {
13232 list = new ArrayList<Intent>();
13233 mStickyBroadcasts.put(intent.getAction(), list);
13234 }
13235 int N = list.size();
13236 int i;
13237 for (i=0; i<N; i++) {
13238 if (intent.filterEquals(list.get(i))) {
13239 // This sticky already exists, replace it.
13240 list.set(i, new Intent(intent));
13241 break;
13242 }
13243 }
13244 if (i >= N) {
13245 list.add(new Intent(intent));
13246 }
13247 }
13248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013249 // Figure out who all will receive this broadcast.
13250 List receivers = null;
13251 List<BroadcastFilter> registeredReceivers = null;
13252 try {
13253 if (intent.getComponent() != null) {
13254 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013255 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070013256 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013257 if (ai != null) {
13258 receivers = new ArrayList();
13259 ResolveInfo ri = new ResolveInfo();
Amith Yamasani742a6712011-05-04 14:49:28 -070013260 ri.activityInfo = getActivityInfoForUser(ai, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013261 receivers.add(ri);
13262 }
13263 } else {
Amith Yamasani742a6712011-05-04 14:49:28 -070013264 // TODO: Apply userId
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013265 // Need to resolve the intent to interested receivers...
13266 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13267 == 0) {
13268 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013269 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013270 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013271 }
Mihai Preda074edef2009-05-18 17:13:31 +020013272 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013273 }
13274 } catch (RemoteException ex) {
13275 // pm is in same process, this will never happen.
13276 }
13277
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013278 final boolean replacePending =
13279 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13280
Joe Onorato8a9b2202010-02-26 18:56:32 -080013281 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013282 + " replacePending=" + replacePending);
13283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013284 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13285 if (!ordered && NR > 0) {
13286 // If we are not serializing this broadcast, then send the
13287 // registered receivers separately so they don't wait for the
13288 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080013289 final BroadcastQueue queue = broadcastQueueForIntent(intent);
13290 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013291 callerPackage, callingPid, callingUid, requiredPermission,
13292 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013293 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013294 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080013295 TAG, "Enqueueing parallel broadcast " + r);
13296 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013297 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013298 queue.enqueueParallelBroadcastLocked(r);
13299 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013301 registeredReceivers = null;
13302 NR = 0;
13303 }
13304
13305 // Merge into one list.
13306 int ir = 0;
13307 if (receivers != null) {
13308 // A special case for PACKAGE_ADDED: do not allow the package
13309 // being added to see this broadcast. This prevents them from
13310 // using this as a back door to get run as soon as they are
13311 // installed. Maybe in the future we want to have a special install
13312 // broadcast or such for apps, but we'd like to deliberately make
13313 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013314 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013315 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13316 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13317 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013318 Uri data = intent.getData();
13319 if (data != null) {
13320 String pkgName = data.getSchemeSpecificPart();
13321 if (pkgName != null) {
13322 skipPackages = new String[] { pkgName };
13323 }
13324 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013325 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013326 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070013327 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013328 if (skipPackages != null && (skipPackages.length > 0)) {
13329 for (String skipPackage : skipPackages) {
13330 if (skipPackage != null) {
13331 int NT = receivers.size();
13332 for (int it=0; it<NT; it++) {
13333 ResolveInfo curt = (ResolveInfo)receivers.get(it);
13334 if (curt.activityInfo.packageName.equals(skipPackage)) {
13335 receivers.remove(it);
13336 it--;
13337 NT--;
13338 }
13339 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013340 }
13341 }
13342 }
13343
13344 int NT = receivers != null ? receivers.size() : 0;
13345 int it = 0;
13346 ResolveInfo curt = null;
13347 BroadcastFilter curr = null;
13348 while (it < NT && ir < NR) {
13349 if (curt == null) {
13350 curt = (ResolveInfo)receivers.get(it);
13351 }
13352 if (curr == null) {
13353 curr = registeredReceivers.get(ir);
13354 }
13355 if (curr.getPriority() >= curt.priority) {
13356 // Insert this broadcast record into the final list.
13357 receivers.add(it, curr);
13358 ir++;
13359 curr = null;
13360 it++;
13361 NT++;
13362 } else {
13363 // Skip to the next ResolveInfo in the final list.
13364 it++;
13365 curt = null;
13366 }
13367 }
13368 }
13369 while (ir < NR) {
13370 if (receivers == null) {
13371 receivers = new ArrayList();
13372 }
13373 receivers.add(registeredReceivers.get(ir));
13374 ir++;
13375 }
13376
13377 if ((receivers != null && receivers.size() > 0)
13378 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013379 BroadcastQueue queue = broadcastQueueForIntent(intent);
13380 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013382 receivers, resultTo, resultCode, resultData, map, ordered,
13383 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013384 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013385 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080013386 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013387 if (DEBUG_BROADCAST) {
13388 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013389 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013390 }
Christopher Tatef46723b2012-01-26 14:19:24 -080013391 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013392 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013393 queue.enqueueOrderedBroadcastLocked(r);
13394 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013396 }
13397
13398 return BROADCAST_SUCCESS;
13399 }
13400
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013401 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013402 // Refuse possible leaked file descriptors
13403 if (intent != null && intent.hasFileDescriptors() == true) {
13404 throw new IllegalArgumentException("File descriptors passed in Intent");
13405 }
13406
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013407 int flags = intent.getFlags();
13408
13409 if (!mProcessesReady) {
13410 // if the caller really truly claims to know what they're doing, go
13411 // ahead and allow the broadcast without launching any receivers
13412 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13413 intent = new Intent(intent);
13414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13415 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13416 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13417 + " before boot completion");
13418 throw new IllegalStateException("Cannot broadcast before boot completed");
13419 }
13420 }
13421
13422 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13423 throw new IllegalArgumentException(
13424 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13425 }
13426
13427 return intent;
13428 }
13429
13430 public final int broadcastIntent(IApplicationThread caller,
13431 Intent intent, String resolvedType, IIntentReceiver resultTo,
13432 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013433 String requiredPermission, boolean serialized, boolean sticky, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013434 enforceNotIsolatedCaller("broadcastIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013435 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013436 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013438 final ProcessRecord callerApp = getRecordForAppLocked(caller);
13439 final int callingPid = Binder.getCallingPid();
13440 final int callingUid = Binder.getCallingUid();
13441 final long origId = Binder.clearCallingIdentity();
13442 int res = broadcastIntentLocked(callerApp,
13443 callerApp != null ? callerApp.info.packageName : null,
13444 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070013445 resultCode, resultData, map, requiredPermission, serialized, sticky,
13446 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013447 Binder.restoreCallingIdentity(origId);
13448 return res;
13449 }
13450 }
13451
13452 int broadcastIntentInPackage(String packageName, int uid,
13453 Intent intent, String resolvedType, IIntentReceiver resultTo,
13454 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013455 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013456 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013457 intent = verifyBroadcastLocked(intent);
13458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013459 final long origId = Binder.clearCallingIdentity();
13460 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13461 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013462 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013463 Binder.restoreCallingIdentity(origId);
13464 return res;
13465 }
13466 }
13467
Amith Yamasani742a6712011-05-04 14:49:28 -070013468 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13469 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013470 // Refuse possible leaked file descriptors
13471 if (intent != null && intent.hasFileDescriptors() == true) {
13472 throw new IllegalArgumentException("File descriptors passed in Intent");
13473 }
13474
13475 synchronized(this) {
13476 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13477 != PackageManager.PERMISSION_GRANTED) {
13478 String msg = "Permission Denial: unbroadcastIntent() from pid="
13479 + Binder.getCallingPid()
13480 + ", uid=" + Binder.getCallingUid()
13481 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013482 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013483 throw new SecurityException(msg);
13484 }
13485 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13486 if (list != null) {
13487 int N = list.size();
13488 int i;
13489 for (i=0; i<N; i++) {
13490 if (intent.filterEquals(list.get(i))) {
13491 list.remove(i);
13492 break;
13493 }
13494 }
13495 }
13496 }
13497 }
13498
13499 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13500 String resultData, Bundle resultExtras, boolean resultAbort,
13501 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013502 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13503 if (r == null) {
13504 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013505 return false;
13506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013507
Christopher Tatef46723b2012-01-26 14:19:24 -080013508 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13509 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013510 }
13511
13512 public void finishReceiver(IBinder who, int resultCode, String resultData,
13513 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013514 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013515
13516 // Refuse possible leaked file descriptors
13517 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13518 throw new IllegalArgumentException("File descriptors passed in Bundle");
13519 }
13520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013521 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080013522 try {
13523 boolean doNext = false;
13524 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013525
Christopher Tatef46723b2012-01-26 14:19:24 -080013526 synchronized(this) {
13527 r = broadcastRecordForReceiverLocked(who);
13528 if (r != null) {
13529 doNext = r.queue.finishReceiverLocked(r, resultCode,
13530 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013532 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013533
Christopher Tatef46723b2012-01-26 14:19:24 -080013534 if (doNext) {
13535 r.queue.processNextBroadcast(false);
13536 }
13537 trimApplications();
13538 } finally {
13539 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070013540 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013541 }
13542
13543 private final void processCurBroadcastLocked(BroadcastRecord r,
13544 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013545 if (DEBUG_BROADCAST) Slog.v(TAG,
13546 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013547 if (app.thread == null) {
13548 throw new RemoteException();
13549 }
13550 r.receiver = app.thread.asBinder();
13551 r.curApp = app;
13552 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013553 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013554
13555 // Tell the application to launch this receiver.
13556 r.intent.setComponent(r.curComponent);
13557
13558 boolean started = false;
13559 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013560 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013561 "Delivering to component " + r.curComponent
13562 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070013563 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013564 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040013565 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013566 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013567 if (DEBUG_BROADCAST) Slog.v(TAG,
13568 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013569 started = true;
13570 } finally {
13571 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013572 if (DEBUG_BROADCAST) Slog.v(TAG,
13573 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013574 r.receiver = null;
13575 r.curApp = null;
13576 app.curReceiver = null;
13577 }
13578 }
13579
13580 }
13581
Jeff Brown4d94a762010-09-23 11:33:28 -070013582 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013583 Intent intent, int resultCode, String data, Bundle extras,
13584 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070013585 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013586 if (app != null && app.thread != null) {
13587 // If we have an app thread, do the call through that so it is
13588 // correctly ordered with other one-way calls.
13589 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013590 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013591 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013592 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013593 }
13594 }
13595
Jeff Brown4d94a762010-09-23 11:33:28 -070013596 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013597 BroadcastFilter filter, boolean ordered) {
13598 boolean skip = false;
13599 if (filter.requiredPermission != null) {
13600 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013601 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013602 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013603 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013604 + r.intent.toString()
13605 + " from " + r.callerPackage + " (pid="
13606 + r.callingPid + ", uid=" + r.callingUid + ")"
13607 + " requires " + filter.requiredPermission
13608 + " due to registered receiver " + filter);
13609 skip = true;
13610 }
13611 }
13612 if (r.requiredPermission != null) {
13613 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013614 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013615 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013616 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013617 + r.intent.toString()
13618 + " to " + filter.receiverList.app
13619 + " (pid=" + filter.receiverList.pid
13620 + ", uid=" + filter.receiverList.uid + ")"
13621 + " requires " + r.requiredPermission
13622 + " due to sender " + r.callerPackage
13623 + " (uid " + r.callingUid + ")");
13624 skip = true;
13625 }
13626 }
13627
13628 if (!skip) {
13629 // If this is not being sent as an ordered broadcast, then we
13630 // don't want to touch the fields that keep track of the current
13631 // state of ordered broadcasts.
13632 if (ordered) {
13633 r.receiver = filter.receiverList.receiver.asBinder();
13634 r.curFilter = filter;
13635 filter.receiverList.curBroadcast = r;
13636 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013637 if (filter.receiverList.app != null) {
13638 // Bump hosting application to no longer be in background
13639 // scheduling class. Note that we can't do that if there
13640 // isn't an app... but we can only be in that case for
13641 // things that directly call the IActivityManager API, which
13642 // are already core system stuff so don't matter for this.
13643 r.curApp = filter.receiverList.app;
13644 filter.receiverList.app.curReceiver = r;
13645 updateOomAdjLocked();
13646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013647 }
13648 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013649 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013650 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013651 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013652 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013653 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013654 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013655 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013656 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013657 if (ordered) {
13658 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
13659 }
13660 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013661 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013662 if (ordered) {
13663 r.receiver = null;
13664 r.curFilter = null;
13665 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013666 if (filter.receiverList.app != null) {
13667 filter.receiverList.app.curReceiver = null;
13668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013669 }
13670 }
13671 }
13672 }
13673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013674 // =========================================================
13675 // INSTRUMENTATION
13676 // =========================================================
13677
13678 public boolean startInstrumentation(ComponentName className,
13679 String profileFile, int flags, Bundle arguments,
13680 IInstrumentationWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013681 enforceNotIsolatedCaller("startInstrumentation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013682 // Refuse possible leaked file descriptors
13683 if (arguments != null && arguments.hasFileDescriptors()) {
13684 throw new IllegalArgumentException("File descriptors passed in Bundle");
13685 }
13686
13687 synchronized(this) {
13688 InstrumentationInfo ii = null;
13689 ApplicationInfo ai = null;
13690 try {
13691 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013692 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013693 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013694 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013695 } catch (PackageManager.NameNotFoundException e) {
13696 }
13697 if (ii == null) {
13698 reportStartInstrumentationFailure(watcher, className,
13699 "Unable to find instrumentation info for: " + className);
13700 return false;
13701 }
13702 if (ai == null) {
13703 reportStartInstrumentationFailure(watcher, className,
13704 "Unable to find instrumentation target package: " + ii.targetPackage);
13705 return false;
13706 }
13707
13708 int match = mContext.getPackageManager().checkSignatures(
13709 ii.targetPackage, ii.packageName);
13710 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13711 String msg = "Permission Denial: starting instrumentation "
13712 + className + " from pid="
13713 + Binder.getCallingPid()
13714 + ", uid=" + Binder.getCallingPid()
13715 + " not allowed because package " + ii.packageName
13716 + " does not have a signature matching the target "
13717 + ii.targetPackage;
13718 reportStartInstrumentationFailure(watcher, className, msg);
13719 throw new SecurityException(msg);
13720 }
13721
13722 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013723 // Instrumentation can kill and relaunch even persistent processes
13724 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013725 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013726 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013727 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013728 app.instrumentationProfileFile = profileFile;
13729 app.instrumentationArguments = arguments;
13730 app.instrumentationWatcher = watcher;
13731 app.instrumentationResultClass = className;
13732 Binder.restoreCallingIdentity(origId);
13733 }
13734
13735 return true;
13736 }
13737
13738 /**
13739 * Report errors that occur while attempting to start Instrumentation. Always writes the
13740 * error to the logs, but if somebody is watching, send the report there too. This enables
13741 * the "am" command to report errors with more information.
13742 *
13743 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13744 * @param cn The component name of the instrumentation.
13745 * @param report The error report.
13746 */
13747 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13748 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013749 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013750 try {
13751 if (watcher != null) {
13752 Bundle results = new Bundle();
13753 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13754 results.putString("Error", report);
13755 watcher.instrumentationStatus(cn, -1, results);
13756 }
13757 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013758 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013759 }
13760 }
13761
13762 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13763 if (app.instrumentationWatcher != null) {
13764 try {
13765 // NOTE: IInstrumentationWatcher *must* be oneway here
13766 app.instrumentationWatcher.instrumentationFinished(
13767 app.instrumentationClass,
13768 resultCode,
13769 results);
13770 } catch (RemoteException e) {
13771 }
13772 }
13773 app.instrumentationWatcher = null;
13774 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013775 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013776 app.instrumentationProfileFile = null;
13777 app.instrumentationArguments = null;
13778
Christopher Tate3dacd842011-08-19 14:56:15 -070013779 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013780 }
13781
13782 public void finishInstrumentation(IApplicationThread target,
13783 int resultCode, Bundle results) {
13784 // Refuse possible leaked file descriptors
13785 if (results != null && results.hasFileDescriptors()) {
13786 throw new IllegalArgumentException("File descriptors passed in Intent");
13787 }
13788
13789 synchronized(this) {
13790 ProcessRecord app = getRecordForAppLocked(target);
13791 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013792 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013793 return;
13794 }
13795 final long origId = Binder.clearCallingIdentity();
13796 finishInstrumentationLocked(app, resultCode, results);
13797 Binder.restoreCallingIdentity(origId);
13798 }
13799 }
13800
13801 // =========================================================
13802 // CONFIGURATION
13803 // =========================================================
13804
13805 public ConfigurationInfo getDeviceConfigurationInfo() {
13806 ConfigurationInfo config = new ConfigurationInfo();
13807 synchronized (this) {
13808 config.reqTouchScreen = mConfiguration.touchscreen;
13809 config.reqKeyboardType = mConfiguration.keyboard;
13810 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013811 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13812 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013813 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13814 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013815 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13816 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013817 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13818 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013819 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013820 }
13821 return config;
13822 }
13823
13824 public Configuration getConfiguration() {
13825 Configuration ci;
13826 synchronized(this) {
13827 ci = new Configuration(mConfiguration);
13828 }
13829 return ci;
13830 }
13831
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013832 public void updatePersistentConfiguration(Configuration values) {
13833 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13834 "updateConfiguration()");
13835 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13836 "updateConfiguration()");
13837 if (values == null) {
13838 throw new NullPointerException("Configuration must not be null");
13839 }
13840
13841 synchronized(this) {
13842 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013843 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013844 Binder.restoreCallingIdentity(origId);
13845 }
13846 }
13847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013848 public void updateConfiguration(Configuration values) {
13849 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13850 "updateConfiguration()");
13851
13852 synchronized(this) {
13853 if (values == null && mWindowManager != null) {
13854 // sentinel: fetch the current configuration from the window manager
13855 values = mWindowManager.computeNewConfiguration();
13856 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013857
13858 if (mWindowManager != null) {
13859 mProcessList.applyDisplaySize(mWindowManager);
13860 }
13861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013862 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013863 if (values != null) {
13864 Settings.System.clearConfiguration(values);
13865 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013866 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013867 Binder.restoreCallingIdentity(origId);
13868 }
13869 }
13870
13871 /**
13872 * Do either or both things: (1) change the current configuration, and (2)
13873 * make sure the given activity is running with the (now) current
13874 * configuration. Returns true if the activity has been left running, or
13875 * false if <var>starting</var> is being destroyed to match the new
13876 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013877 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013878 */
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013879 boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013880 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013881 int changes = 0;
13882
13883 boolean kept = true;
13884
13885 if (values != null) {
13886 Configuration newConfig = new Configuration(mConfiguration);
13887 changes = newConfig.updateFrom(values);
13888 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013889 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013890 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013891 }
13892
Doug Zongker2bec3d42009-12-04 12:52:44 -080013893 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013894
Dianne Hackborn813075a62011-11-14 17:45:19 -080013895 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013896 saveLocaleLocked(values.locale,
13897 !values.locale.equals(mConfiguration.locale),
13898 values.userSetLocale);
13899 }
13900
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013901 mConfigurationSeq++;
13902 if (mConfigurationSeq <= 0) {
13903 mConfigurationSeq = 1;
13904 }
13905 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013906 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013907 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013908
13909 final Configuration configCopy = new Configuration(mConfiguration);
13910
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013911 AttributeCache ac = AttributeCache.instance();
13912 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013913 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013915
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013916 // Make sure all resources in our process are updated
13917 // right now, so that anyone who is going to retrieve
13918 // resource values after we return will be sure to get
13919 // the new ones. This is especially important during
13920 // boot, where the first config change needs to guarantee
13921 // all resources have that config before following boot
13922 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013923 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013924
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013925 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013926 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013927 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013928 mHandler.sendMessage(msg);
13929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013930
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013931 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13932 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013933 try {
13934 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013935 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013936 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013937 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013938 }
13939 } catch (Exception e) {
13940 }
13941 }
13942 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013943 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13944 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013945 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013946 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013947 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13948 broadcastIntentLocked(null, null,
13949 new Intent(Intent.ACTION_LOCALE_CHANGED),
13950 null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013951 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013953 }
13954 }
13955
13956 if (changes != 0 && starting == null) {
13957 // If the configuration changed, and the caller is not already
13958 // in the process of starting an activity, then find the top
13959 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013960 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013961 }
13962
13963 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013964 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013965 // And we need to make sure at this point that all other activities
13966 // are made visible with the correct configuration.
13967 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013968 }
13969
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013970 if (values != null && mWindowManager != null) {
13971 mWindowManager.setNewConfiguration(mConfiguration);
13972 }
13973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013974 return kept;
13975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013976
13977 /**
13978 * Save the locale. You must be inside a synchronized (this) block.
13979 */
13980 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13981 if(isDiff) {
13982 SystemProperties.set("user.language", l.getLanguage());
13983 SystemProperties.set("user.region", l.getCountry());
13984 }
13985
13986 if(isPersist) {
13987 SystemProperties.set("persist.sys.language", l.getLanguage());
13988 SystemProperties.set("persist.sys.country", l.getCountry());
13989 SystemProperties.set("persist.sys.localevar", l.getVariant());
13990 }
13991 }
13992
13993 // =========================================================
13994 // LIFETIME MANAGEMENT
13995 // =========================================================
13996
Christopher Tatef46723b2012-01-26 14:19:24 -080013997 // Returns which broadcast queue the app is the current [or imminent] receiver
13998 // on, or 'null' if the app is not an active broadcast recipient.
13999 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14000 BroadcastRecord r = app.curReceiver;
14001 if (r != null) {
14002 return r.queue;
14003 }
14004
14005 // It's not the current receiver, but it might be starting up to become one
14006 synchronized (this) {
14007 for (BroadcastQueue queue : mBroadcastQueues) {
14008 r = queue.mPendingBroadcast;
14009 if (r != null && r.curApp == app) {
14010 // found it; report which queue it's in
14011 return queue;
14012 }
14013 }
14014 }
14015
14016 return null;
14017 }
14018
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014019 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014020 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014021 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014022 // This adjustment has already been computed. If we are calling
14023 // from the top, we may have already computed our adjustment with
14024 // an earlier hidden adjustment that isn't really for us... if
14025 // so, use the new hidden adjustment.
14026 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014027 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014028 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014029 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014030 }
14031
14032 if (app.thread == null) {
14033 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014034 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014035 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014036 }
14037
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014038 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14039 app.adjSource = null;
14040 app.adjTarget = null;
14041 app.empty = false;
14042 app.hidden = false;
14043
14044 final int activitiesSize = app.activities.size();
14045
Dianne Hackborn7d608422011-08-07 16:24:18 -070014046 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014047 // The max adjustment doesn't allow this app to be anything
14048 // below foreground, so it is not worth doing work for it.
14049 app.adjType = "fixed";
14050 app.adjSeq = mAdjSeq;
14051 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014052 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014053 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014054 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014055 // System process can do UI, and when they do we want to have
14056 // them trim their memory after the user leaves the UI. To
14057 // facilitate this, here we need to determine whether or not it
14058 // is currently showing UI.
14059 app.systemNoUi = true;
14060 if (app == TOP_APP) {
14061 app.systemNoUi = false;
14062 } else if (activitiesSize > 0) {
14063 for (int j = 0; j < activitiesSize; j++) {
14064 final ActivityRecord r = app.activities.get(j);
14065 if (r.visible) {
14066 app.systemNoUi = false;
14067 break;
14068 }
14069 }
14070 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014071 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014072 }
14073
14074 final boolean hadForegroundActivities = app.foregroundActivities;
14075
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014076 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014077 app.keeping = false;
14078 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014079
The Android Open Source Project4df24232009-03-05 14:34:35 -080014080 // Determine the importance of the process, starting with most
14081 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014082 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014083 int schedGroup;
Christopher Tatef46723b2012-01-26 14:19:24 -080014084 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014085 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014086 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014087 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014088 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014089 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014090 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014091 } else if (app.instrumentationClass != null) {
14092 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014093 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014094 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014095 app.adjType = "instrumentation";
Christopher Tatef46723b2012-01-26 14:19:24 -080014096 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014097 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080014098 // counts as being in the foreground for OOM killer purposes.
14099 // It's placed in a sched group based on the nature of the
14100 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014101 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080014102 schedGroup = (queue == mFgBroadcastQueue)
14103 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014104 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014105 } else if (app.executingServices.size() > 0) {
14106 // An app that is currently executing a service callback also
14107 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014108 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014109 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014110 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014111 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014112 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014113 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014114 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014115 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014116 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014117 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014118 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014119 // A very not-needed process. If this is lower in the lru list,
14120 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014121 adj = hiddenAdj;
14122 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014123 app.hidden = true;
14124 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014125 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014126 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014127
14128 // Examine all activities if not already foreground.
14129 if (!app.foregroundActivities && activitiesSize > 0) {
14130 for (int j = 0; j < activitiesSize; j++) {
14131 final ActivityRecord r = app.activities.get(j);
14132 if (r.visible) {
14133 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014134 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14135 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014136 app.adjType = "visible";
14137 }
14138 schedGroup = Process.THREAD_GROUP_DEFAULT;
14139 app.hidden = false;
14140 app.foregroundActivities = true;
14141 break;
14142 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
14143 || r.state == ActivityState.STOPPING) {
14144 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014145 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14146 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014147 app.adjType = "stopping";
14148 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080014149 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014150 app.foregroundActivities = true;
14151 }
14152 }
14153 }
14154
Dianne Hackborn7d608422011-08-07 16:24:18 -070014155 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014156 if (app.foregroundServices) {
14157 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014158 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014159 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014160 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014161 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014162 } else if (app.forcingToForeground != null) {
14163 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014164 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014165 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014166 app.adjType = "force-foreground";
14167 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014168 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014169 }
14170 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014171
Dianne Hackborn7d608422011-08-07 16:24:18 -070014172 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014173 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014174 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014175 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014176 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014177 app.adjType = "heavy";
14178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014179
Dianne Hackborn7d608422011-08-07 16:24:18 -070014180 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014181 // This process is hosting what we currently consider to be the
14182 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014183 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014184 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014185 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014186 app.adjType = "home";
14187 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014188
Dianne Hackbornf35fe232011-11-01 19:25:20 -070014189 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
14190 && app.activities.size() > 0) {
14191 // This was the previous process that showed UI to the user.
14192 // We want to try to keep it around more aggressively, to give
14193 // a good experience around switching between two apps.
14194 adj = ProcessList.PREVIOUS_APP_ADJ;
14195 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14196 app.hidden = false;
14197 app.adjType = "previous";
14198 }
14199
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014200 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14201 + " reason=" + app.adjType);
14202
The Android Open Source Project4df24232009-03-05 14:34:35 -080014203 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014204 // there are applications dependent on our services or providers, but
14205 // this gives us a baseline and makes sure we don't get into an
14206 // infinite recursion.
14207 app.adjSeq = mAdjSeq;
14208 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014209
Christopher Tate6fa95972009-06-05 18:43:55 -070014210 if (mBackupTarget != null && app == mBackupTarget.app) {
14211 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070014212 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014213 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014214 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014215 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014216 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070014217 }
14218 }
14219
Dianne Hackborn7d608422011-08-07 16:24:18 -070014220 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014221 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014222 final long now = SystemClock.uptimeMillis();
14223 // This process is more important if the top activity is
14224 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070014225 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014226 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014227 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014228 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014229 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014230 // If this process has shown some UI, let it immediately
14231 // go to the LRU list because it may be pretty heavy with
14232 // UI stuff. We'll tag it with a label just to help
14233 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014234 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014235 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014236 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014237 } else {
14238 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14239 // This service has seen some activity within
14240 // recent memory, so we will keep its process ahead
14241 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014242 if (adj > ProcessList.SERVICE_ADJ) {
14243 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014244 app.adjType = "started-services";
14245 app.hidden = false;
14246 }
14247 }
14248 // If we have let the service slide into the background
14249 // state, still have some text describing what it is doing
14250 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014251 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014252 app.adjType = "started-bg-services";
14253 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014254 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014255 // Don't kill this process because it is doing work; it
14256 // has said it is doing work.
14257 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014258 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014259 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014260 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014261 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014262 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014263 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014264 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014265 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014266 // XXX should compute this based on the max of
14267 // all connected clients.
14268 ConnectionRecord cr = clist.get(i);
14269 if (cr.binding.client == app) {
14270 // Binding to ourself is not interesting.
14271 continue;
14272 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014273 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014274 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014275 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014276 int myHiddenAdj = hiddenAdj;
14277 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014278 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014279 myHiddenAdj = client.hiddenAdj;
14280 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014281 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014282 }
14283 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014284 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014285 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014286 String adjType = null;
14287 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14288 // Not doing bind OOM management, so treat
14289 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014290 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014291 // If this process has shown some UI, let it immediately
14292 // go to the LRU list because it may be pretty heavy with
14293 // UI stuff. We'll tag it with a label just to help
14294 // debug and understand what is going on.
14295 if (adj > clientAdj) {
14296 adjType = "bound-bg-ui-services";
14297 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014298 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014299 clientAdj = adj;
14300 } else {
14301 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14302 // This service has not seen activity within
14303 // recent memory, so allow it to drop to the
14304 // LRU list if there is no other reason to keep
14305 // it around. We'll also tag it with a label just
14306 // to help debug and undertand what is going on.
14307 if (adj > clientAdj) {
14308 adjType = "bound-bg-services";
14309 }
14310 clientAdj = adj;
14311 }
14312 }
14313 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014314 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014315 // If this process has recently shown UI, and
14316 // the process that is binding to it is less
14317 // important than being visible, then we don't
14318 // care about the binding as much as we care
14319 // about letting this process get into the LRU
14320 // list to be killed and restarted if needed for
14321 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014322 if (app.hasShownUi && app != mHomeProcess
14323 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014324 adjType = "bound-bg-ui-services";
14325 } else {
14326 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14327 |Context.BIND_IMPORTANT)) != 0) {
14328 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014329 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14330 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14331 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14332 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14333 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014334 adj = clientAdj;
14335 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014336 app.pendingUiClean = true;
14337 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14338 adj = ProcessList.VISIBLE_APP_ADJ;
14339 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014340 }
14341 if (!client.hidden) {
14342 app.hidden = false;
14343 }
14344 if (client.keeping) {
14345 app.keeping = true;
14346 }
14347 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014348 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014349 }
14350 if (adjType != null) {
14351 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014352 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14353 .REASON_SERVICE_IN_USE;
14354 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014355 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014356 app.adjTarget = s.name;
14357 }
14358 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14359 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14360 schedGroup = Process.THREAD_GROUP_DEFAULT;
14361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014362 }
14363 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014364 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14365 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014366 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014367 (a.visible || a.state == ActivityState.RESUMED
14368 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014369 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014370 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14371 schedGroup = Process.THREAD_GROUP_DEFAULT;
14372 }
14373 app.hidden = false;
14374 app.adjType = "service";
14375 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14376 .REASON_SERVICE_IN_USE;
14377 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014378 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014379 app.adjTarget = s.name;
14380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014382 }
14383 }
14384 }
14385 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014386
Dianne Hackborn287952c2010-09-22 22:34:31 -070014387 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014388 // would like to avoid killing it unless it would prevent the current
14389 // application from running. By default we put the process in
14390 // with the rest of the background processes; as we scan through
14391 // its services we may bump it up from there.
14392 if (adj > hiddenAdj) {
14393 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014394 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014395 app.adjType = "bg-services";
14396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014397 }
14398
Dianne Hackborn7d608422011-08-07 16:24:18 -070014399 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014400 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014401 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014402 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014403 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014404 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014405 if (cpr.clients.size() != 0) {
14406 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014407 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014408 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070014409 if (client == app) {
14410 // Being our own client is not interesting.
14411 continue;
14412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014413 int myHiddenAdj = hiddenAdj;
14414 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014415 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014416 myHiddenAdj = client.hiddenAdj;
14417 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014418 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014419 }
14420 }
14421 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014422 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014423 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014424 if (app.hasShownUi && app != mHomeProcess
14425 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014426 app.adjType = "bg-ui-provider";
14427 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014428 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14429 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014430 app.adjType = "provider";
14431 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014432 if (!client.hidden) {
14433 app.hidden = false;
14434 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014435 if (client.keeping) {
14436 app.keeping = true;
14437 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070014438 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14439 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014440 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014441 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014442 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014443 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014444 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14445 schedGroup = Process.THREAD_GROUP_DEFAULT;
14446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014447 }
14448 }
14449 // If the provider has external (non-framework) process
14450 // dependencies, ensure that its adjustment is at least
14451 // FOREGROUND_APP_ADJ.
14452 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014453 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14454 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014455 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014456 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014457 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014458 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014459 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014460 }
14461 }
14462 }
14463 }
14464
14465 app.curRawAdj = adj;
14466
Joe Onorato8a9b2202010-02-26 18:56:32 -080014467 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014468 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14469 if (adj > app.maxAdj) {
14470 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014471 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014472 schedGroup = Process.THREAD_GROUP_DEFAULT;
14473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014474 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014475 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014476 app.keeping = true;
14477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014478
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014479 if (app.hasAboveClient) {
14480 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14481 // then we need to drop its adjustment to be lower than the service's
14482 // in order to honor the request. We want to drop it by one adjustment
14483 // level... but there is special meaning applied to various levels so
14484 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014485 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014486 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014487 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14488 adj = ProcessList.VISIBLE_APP_ADJ;
14489 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14490 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14491 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14492 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014493 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014494 adj++;
14495 }
14496 }
14497
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014498 if (adj == ProcessList.SERVICE_ADJ) {
14499 if (doingAll) {
14500 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14501 mNewNumServiceProcs++;
14502 }
14503 if (app.serviceb) {
14504 adj = ProcessList.SERVICE_B_ADJ;
14505 }
14506 } else {
14507 app.serviceb = false;
14508 }
14509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014510 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014511 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014512
14513 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014514 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14515 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014516 }
14517
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014518 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014519 }
14520
14521 /**
14522 * Ask a given process to GC right now.
14523 */
14524 final void performAppGcLocked(ProcessRecord app) {
14525 try {
14526 app.lastRequestedGc = SystemClock.uptimeMillis();
14527 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014528 if (app.reportLowMemory) {
14529 app.reportLowMemory = false;
14530 app.thread.scheduleLowMemory();
14531 } else {
14532 app.thread.processInBackground();
14533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014534 }
14535 } catch (Exception e) {
14536 // whatever.
14537 }
14538 }
14539
14540 /**
14541 * Returns true if things are idle enough to perform GCs.
14542 */
Josh Bartel7f208742010-02-25 11:01:44 -060014543 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080014544 boolean processingBroadcasts = false;
14545 for (BroadcastQueue q : mBroadcastQueues) {
14546 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14547 processingBroadcasts = true;
14548 }
14549 }
14550 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014551 && (mSleeping || (mMainStack.mResumedActivity != null &&
14552 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014553 }
14554
14555 /**
14556 * Perform GCs on all processes that are waiting for it, but only
14557 * if things are idle.
14558 */
14559 final void performAppGcsLocked() {
14560 final int N = mProcessesToGc.size();
14561 if (N <= 0) {
14562 return;
14563 }
Josh Bartel7f208742010-02-25 11:01:44 -060014564 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014565 while (mProcessesToGc.size() > 0) {
14566 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014567 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014568 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14569 <= SystemClock.uptimeMillis()) {
14570 // To avoid spamming the system, we will GC processes one
14571 // at a time, waiting a few seconds between each.
14572 performAppGcLocked(proc);
14573 scheduleAppGcsLocked();
14574 return;
14575 } else {
14576 // It hasn't been long enough since we last GCed this
14577 // process... put it in the list to wait for its time.
14578 addProcessToGcListLocked(proc);
14579 break;
14580 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014581 }
14582 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014583
14584 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014585 }
14586 }
14587
14588 /**
14589 * If all looks good, perform GCs on all processes waiting for them.
14590 */
14591 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014592 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014593 performAppGcsLocked();
14594 return;
14595 }
14596 // Still not idle, wait some more.
14597 scheduleAppGcsLocked();
14598 }
14599
14600 /**
14601 * Schedule the execution of all pending app GCs.
14602 */
14603 final void scheduleAppGcsLocked() {
14604 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014605
14606 if (mProcessesToGc.size() > 0) {
14607 // Schedule a GC for the time to the next process.
14608 ProcessRecord proc = mProcessesToGc.get(0);
14609 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14610
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014611 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014612 long now = SystemClock.uptimeMillis();
14613 if (when < (now+GC_TIMEOUT)) {
14614 when = now + GC_TIMEOUT;
14615 }
14616 mHandler.sendMessageAtTime(msg, when);
14617 }
14618 }
14619
14620 /**
14621 * Add a process to the array of processes waiting to be GCed. Keeps the
14622 * list in sorted order by the last GC time. The process can't already be
14623 * on the list.
14624 */
14625 final void addProcessToGcListLocked(ProcessRecord proc) {
14626 boolean added = false;
14627 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14628 if (mProcessesToGc.get(i).lastRequestedGc <
14629 proc.lastRequestedGc) {
14630 added = true;
14631 mProcessesToGc.add(i+1, proc);
14632 break;
14633 }
14634 }
14635 if (!added) {
14636 mProcessesToGc.add(0, proc);
14637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014638 }
14639
14640 /**
14641 * Set up to ask a process to GC itself. This will either do it
14642 * immediately, or put it on the list of processes to gc the next
14643 * time things are idle.
14644 */
14645 final void scheduleAppGcLocked(ProcessRecord app) {
14646 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014647 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014648 return;
14649 }
14650 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014651 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014652 scheduleAppGcsLocked();
14653 }
14654 }
14655
Dianne Hackborn287952c2010-09-22 22:34:31 -070014656 final void checkExcessivePowerUsageLocked(boolean doKills) {
14657 updateCpuStatsNow();
14658
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014659 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014660 boolean doWakeKills = doKills;
14661 boolean doCpuKills = doKills;
14662 if (mLastPowerCheckRealtime == 0) {
14663 doWakeKills = false;
14664 }
14665 if (mLastPowerCheckUptime == 0) {
14666 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014667 }
14668 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014669 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014670 }
14671 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014672 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14673 final long curUptime = SystemClock.uptimeMillis();
14674 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14675 mLastPowerCheckRealtime = curRealtime;
14676 mLastPowerCheckUptime = curUptime;
14677 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14678 doWakeKills = false;
14679 }
14680 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14681 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014682 }
14683 int i = mLruProcesses.size();
14684 while (i > 0) {
14685 i--;
14686 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014687 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014688 long wtime;
14689 synchronized (stats) {
14690 wtime = stats.getProcessWakeTime(app.info.uid,
14691 app.pid, curRealtime);
14692 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014693 long wtimeUsed = wtime - app.lastWakeTime;
14694 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14695 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014696 StringBuilder sb = new StringBuilder(128);
14697 sb.append("Wake for ");
14698 app.toShortString(sb);
14699 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014700 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014701 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014702 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014703 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014704 sb.append((wtimeUsed*100)/realtimeSince);
14705 sb.append("%)");
14706 Slog.i(TAG, sb.toString());
14707 sb.setLength(0);
14708 sb.append("CPU for ");
14709 app.toShortString(sb);
14710 sb.append(": over ");
14711 TimeUtils.formatDuration(uptimeSince, sb);
14712 sb.append(" used ");
14713 TimeUtils.formatDuration(cputimeUsed, sb);
14714 sb.append(" (");
14715 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014716 sb.append("%)");
14717 Slog.i(TAG, sb.toString());
14718 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014719 // If a process has held a wake lock for more
14720 // than 50% of the time during this period,
14721 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014722 if (doWakeKills && realtimeSince > 0
14723 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14724 synchronized (stats) {
14725 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14726 realtimeSince, wtimeUsed);
14727 }
14728 Slog.w(TAG, "Excessive wake lock in " + app.processName
14729 + " (pid " + app.pid + "): held " + wtimeUsed
14730 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014731 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14732 app.processName, app.setAdj, "excessive wake lock");
14733 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014734 } else if (doCpuKills && uptimeSince > 0
14735 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14736 synchronized (stats) {
14737 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14738 uptimeSince, cputimeUsed);
14739 }
14740 Slog.w(TAG, "Excessive CPU in " + app.processName
14741 + " (pid " + app.pid + "): used " + cputimeUsed
14742 + " during " + uptimeSince);
14743 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14744 app.processName, app.setAdj, "excessive cpu");
14745 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014746 } else {
14747 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014748 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014749 }
14750 }
14751 }
14752 }
14753
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014754 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014755 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014756 app.hiddenAdj = hiddenAdj;
14757
14758 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014759 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014760 }
14761
Dianne Hackborn287952c2010-09-22 22:34:31 -070014762 final boolean wasKeeping = app.keeping;
14763
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014764 boolean success = true;
14765
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014766 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014767
Jeff Brown10e89712011-07-08 18:52:57 -070014768 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014769 if (false) {
14770 // Removing for now. Forcing GCs is not so useful anymore
14771 // with Dalvik, and the new memory level hint facility is
14772 // better for what we need to do these days.
14773 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14774 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14775 // If this app is transitioning from foreground to
14776 // non-foreground, have it do a gc.
14777 scheduleAppGcLocked(app);
14778 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14779 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14780 // Likewise do a gc when an app is moving in to the
14781 // background (such as a service stopping).
14782 scheduleAppGcLocked(app);
14783 }
Jeff Brown10e89712011-07-08 18:52:57 -070014784 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014785
Jeff Brown10e89712011-07-08 18:52:57 -070014786 if (wasKeeping && !app.keeping) {
14787 // This app is no longer something we want to keep. Note
14788 // its current wake lock time to later know to kill it if
14789 // it is not behaving well.
14790 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14791 synchronized (stats) {
14792 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14793 app.pid, SystemClock.elapsedRealtime());
14794 }
14795 app.lastCpuTime = app.curCpuTime;
14796 }
14797
14798 app.setRawAdj = app.curRawAdj;
14799 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014800
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014801 if (app.curAdj != app.setAdj) {
14802 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014803 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014804 TAG, "Set " + app.pid + " " + app.processName +
14805 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014806 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014807 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014808 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014809 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014810 }
14811 }
14812 if (app.setSchedGroup != app.curSchedGroup) {
14813 app.setSchedGroup = app.curSchedGroup;
14814 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14815 "Setting process group of " + app.processName
14816 + " to " + app.curSchedGroup);
14817 if (app.waitingToKill != null &&
14818 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14819 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14820 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14821 app.processName, app.setAdj, app.waitingToKill);
14822 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014823 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014824 } else {
14825 if (true) {
14826 long oldId = Binder.clearCallingIdentity();
14827 try {
14828 Process.setProcessGroup(app.pid, app.curSchedGroup);
14829 } catch (Exception e) {
14830 Slog.w(TAG, "Failed setting process group of " + app.pid
14831 + " to " + app.curSchedGroup);
14832 e.printStackTrace();
14833 } finally {
14834 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014835 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014836 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014837 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014838 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014839 app.thread.setSchedulingGroup(app.curSchedGroup);
14840 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014841 }
14842 }
14843 }
14844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014845 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014846 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014847 }
14848
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014849 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014850 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014851 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborncbb722e2012-02-07 18:33:49 -080014852 for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) {
14853 ActivityRecord r = mMainStack.mPausingActivities.get(i);
14854 if (r.app != null) {
14855 resumedActivity = r;
14856 break;
14857 }
14858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014859 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014860 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014861 }
14862 }
14863 return resumedActivity;
14864 }
14865
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014866 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014867 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014868 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14869 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014870 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14871 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014872
14873 mAdjSeq++;
14874
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014875 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014876 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14877 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014878 if (nowHidden != wasHidden) {
14879 // Changed to/from hidden state, so apps after it in the LRU
14880 // list may also be changed.
14881 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014882 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014883 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014884 }
14885
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014886 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014887 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014888 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14889
14890 if (false) {
14891 RuntimeException e = new RuntimeException();
14892 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014893 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014894 }
14895
14896 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014897 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014898
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014899 // Let's determine how many processes we have running vs.
14900 // how many slots we have for background processes; we may want
14901 // to put multiple processes in a slot of there are enough of
14902 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014903 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014904 int factor = (mLruProcesses.size()-4)/numSlots;
14905 if (factor < 1) factor = 1;
14906 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014907 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014908
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014909 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014910 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014911 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014912 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014913 while (i > 0) {
14914 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014915 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014916 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014917 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14918 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014919 && app.curAdj == curHiddenAdj) {
14920 step++;
14921 if (step >= factor) {
14922 step = 0;
14923 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014924 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014925 }
14926 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014927 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014928 numHidden++;
14929 if (numHidden > mProcessLimit) {
14930 Slog.i(TAG, "No longer want " + app.processName
14931 + " (pid " + app.pid + "): hidden #" + numHidden);
14932 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14933 app.processName, app.setAdj, "too many background");
14934 app.killedBackground = true;
14935 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014936 }
14937 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080014938 if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14939 // If this is an isolated process, and there are no
14940 // services running in it, then the process is no longer
14941 // needed. We agressively kill these because we can by
14942 // definition not re-use the same process again, and it is
14943 // good to avoid having whatever code was running in them
14944 // left sitting around after no longer needed.
14945 Slog.i(TAG, "Isolated process " + app.processName
14946 + " (pid " + app.pid + ") no longer needed");
14947 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14948 app.processName, app.setAdj, "isolated not needed");
14949 app.killedBackground = true;
14950 Process.killProcessQuiet(app.pid);
14951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014952 }
14953 }
14954
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014955 mNumServiceProcs = mNewNumServiceProcs;
14956
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014957 // Now determine the memory trimming level of background processes.
14958 // Unfortunately we need to start at the back of the list to do this
14959 // properly. We only do this if the number of background apps we
14960 // are managing to keep around is less than half the maximum we desire;
14961 // if we are keeping a good number around, we'll let them use whatever
14962 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014963 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014964 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014965 factor = numHidden/3;
14966 int minFactor = 2;
14967 if (mHomeProcess != null) minFactor++;
14968 if (mPreviousProcess != null) minFactor++;
14969 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014970 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014971 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014972 for (i=0; i<N; i++) {
14973 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014974 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14975 && app.curAdj != ProcessList.SERVICE_B_ADJ
14976 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014977 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14978 try {
14979 app.thread.scheduleTrimMemory(curLevel);
14980 } catch (RemoteException e) {
14981 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014982 if (false) {
14983 // For now we won't do this; our memory trimming seems
14984 // to be good enough at this point that destroying
14985 // activities causes more harm than good.
14986 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14987 && app != mHomeProcess && app != mPreviousProcess) {
14988 // For these apps we will also finish their activities
14989 // to help them free memory.
14990 mMainStack.destroyActivitiesLocked(app, false, "trim");
14991 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014992 }
14993 }
14994 app.trimMemoryLevel = curLevel;
14995 step++;
14996 if (step >= factor) {
14997 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014998 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14999 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015000 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015001 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15002 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015003 break;
15004 }
15005 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070015006 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015007 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015008 && app.thread != null) {
15009 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015010 app.thread.scheduleTrimMemory(
15011 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015012 } catch (RemoteException e) {
15013 }
15014 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015015 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070015016 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015017 && app.pendingUiClean) {
15018 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15019 && app.thread != null) {
15020 try {
15021 app.thread.scheduleTrimMemory(
15022 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15023 } catch (RemoteException e) {
15024 }
15025 }
15026 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15027 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015028 } else {
15029 app.trimMemoryLevel = 0;
15030 }
15031 }
15032 } else {
15033 final int N = mLruProcesses.size();
15034 for (i=0; i<N; i++) {
15035 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070015036 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015037 && app.pendingUiClean) {
15038 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15039 && app.thread != null) {
15040 try {
15041 app.thread.scheduleTrimMemory(
15042 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15043 } catch (RemoteException e) {
15044 }
15045 }
15046 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15047 app.pendingUiClean = false;
15048 } else {
15049 app.trimMemoryLevel = 0;
15050 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015051 }
15052 }
15053
15054 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070015055 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015057 }
15058
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070015059 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015060 synchronized (this) {
15061 int i;
15062
15063 // First remove any unused application processes whose package
15064 // has been removed.
15065 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15066 final ProcessRecord app = mRemovedProcesses.get(i);
15067 if (app.activities.size() == 0
15068 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080015069 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015070 TAG, "Exiting empty application process "
15071 + app.processName + " ("
15072 + (app.thread != null ? app.thread.asBinder() : null)
15073 + ")\n");
15074 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070015075 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
15076 app.processName, app.setAdj, "empty");
15077 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015078 } else {
15079 try {
15080 app.thread.scheduleExit();
15081 } catch (Exception e) {
15082 // Ignore exceptions.
15083 }
15084 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070015085 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015086 mRemovedProcesses.remove(i);
15087
15088 if (app.persistent) {
15089 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080015090 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015091 }
15092 }
15093 }
15094 }
15095
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015096 // Now update the oom adj for all processes.
15097 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015098 }
15099 }
15100
15101 /** This method sends the specified signal to each of the persistent apps */
15102 public void signalPersistentProcesses(int sig) throws RemoteException {
15103 if (sig != Process.SIGNAL_USR1) {
15104 throw new SecurityException("Only SIGNAL_USR1 is allowed");
15105 }
15106
15107 synchronized (this) {
15108 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15109 != PackageManager.PERMISSION_GRANTED) {
15110 throw new SecurityException("Requires permission "
15111 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15112 }
15113
Dianne Hackborndd71fc82009-12-16 19:24:32 -080015114 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15115 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015116 if (r.thread != null && r.persistent) {
15117 Process.sendSignal(r.pid, sig);
15118 }
15119 }
15120 }
15121 }
15122
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015123 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15124 if (proc == null || proc == mProfileProc) {
15125 proc = mProfileProc;
15126 path = mProfileFile;
15127 profileType = mProfileType;
15128 clearProfilerLocked();
15129 }
15130 if (proc == null) {
15131 return;
15132 }
15133 try {
15134 proc.thread.profilerControl(false, path, null, profileType);
15135 } catch (RemoteException e) {
15136 throw new IllegalStateException("Process disappeared");
15137 }
15138 }
15139
15140 private void clearProfilerLocked() {
15141 if (mProfileFd != null) {
15142 try {
15143 mProfileFd.close();
15144 } catch (IOException e) {
15145 }
15146 }
15147 mProfileApp = null;
15148 mProfileProc = null;
15149 mProfileFile = null;
15150 mProfileType = 0;
15151 mAutoStopProfiler = false;
15152 }
15153
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015154 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070015155 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015156
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015157 try {
15158 synchronized (this) {
15159 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15160 // its own permission.
15161 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15162 != PackageManager.PERMISSION_GRANTED) {
15163 throw new SecurityException("Requires permission "
15164 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015165 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015166
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015167 if (start && fd == null) {
15168 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015169 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015170
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015171 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015172 if (process != null) {
15173 try {
15174 int pid = Integer.parseInt(process);
15175 synchronized (mPidsSelfLocked) {
15176 proc = mPidsSelfLocked.get(pid);
15177 }
15178 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015179 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015180
15181 if (proc == null) {
15182 HashMap<String, SparseArray<ProcessRecord>> all
15183 = mProcessNames.getMap();
15184 SparseArray<ProcessRecord> procs = all.get(process);
15185 if (procs != null && procs.size() > 0) {
15186 proc = procs.valueAt(0);
15187 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015188 }
15189 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015190
15191 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015192 throw new IllegalArgumentException("Unknown process: " + process);
15193 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015194
15195 if (start) {
15196 stopProfilerLocked(null, null, 0);
15197 setProfileApp(proc.info, proc.processName, path, fd, false);
15198 mProfileProc = proc;
15199 mProfileType = profileType;
15200 try {
15201 fd = fd.dup();
15202 } catch (IOException e) {
15203 fd = null;
15204 }
15205 proc.thread.profilerControl(start, path, fd, profileType);
15206 fd = null;
15207 mProfileFd = null;
15208 } else {
15209 stopProfilerLocked(proc, path, profileType);
15210 if (fd != null) {
15211 try {
15212 fd.close();
15213 } catch (IOException e) {
15214 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015215 }
15216 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015217
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015218 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015219 }
15220 } catch (RemoteException e) {
15221 throw new IllegalStateException("Process disappeared");
15222 } finally {
15223 if (fd != null) {
15224 try {
15225 fd.close();
15226 } catch (IOException e) {
15227 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015228 }
15229 }
15230 }
Andy McFadden824c5102010-07-09 16:26:57 -070015231
15232 public boolean dumpHeap(String process, boolean managed,
15233 String path, ParcelFileDescriptor fd) throws RemoteException {
15234
15235 try {
15236 synchronized (this) {
15237 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15238 // its own permission (same as profileControl).
15239 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15240 != PackageManager.PERMISSION_GRANTED) {
15241 throw new SecurityException("Requires permission "
15242 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15243 }
15244
15245 if (fd == null) {
15246 throw new IllegalArgumentException("null fd");
15247 }
15248
15249 ProcessRecord proc = null;
15250 try {
15251 int pid = Integer.parseInt(process);
15252 synchronized (mPidsSelfLocked) {
15253 proc = mPidsSelfLocked.get(pid);
15254 }
15255 } catch (NumberFormatException e) {
15256 }
15257
15258 if (proc == null) {
15259 HashMap<String, SparseArray<ProcessRecord>> all
15260 = mProcessNames.getMap();
15261 SparseArray<ProcessRecord> procs = all.get(process);
15262 if (procs != null && procs.size() > 0) {
15263 proc = procs.valueAt(0);
15264 }
15265 }
15266
15267 if (proc == null || proc.thread == null) {
15268 throw new IllegalArgumentException("Unknown process: " + process);
15269 }
15270
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080015271 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15272 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070015273 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15274 throw new SecurityException("Process not debuggable: " + proc);
15275 }
15276 }
15277
15278 proc.thread.dumpHeap(managed, path, fd);
15279 fd = null;
15280 return true;
15281 }
15282 } catch (RemoteException e) {
15283 throw new IllegalStateException("Process disappeared");
15284 } finally {
15285 if (fd != null) {
15286 try {
15287 fd.close();
15288 } catch (IOException e) {
15289 }
15290 }
15291 }
15292 }
15293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015294 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15295 public void monitor() {
15296 synchronized (this) { }
15297 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015298
Dianne Hackborna573f6a2012-02-09 16:12:18 -080015299 void onCoreSettingsChange(Bundle settings) {
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015300 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15301 ProcessRecord processRecord = mLruProcesses.get(i);
15302 try {
15303 if (processRecord.thread != null) {
15304 processRecord.thread.setCoreSettings(settings);
15305 }
15306 } catch (RemoteException re) {
15307 /* ignore */
15308 }
15309 }
15310 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015311
15312 // Multi-user methods
15313
Amith Yamasani742a6712011-05-04 14:49:28 -070015314 private int mCurrentUserId;
15315 private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15316
15317 public boolean switchUser(int userId) {
15318 final int callingUid = Binder.getCallingUid();
15319 if (callingUid != 0 && callingUid != Process.myUid()) {
15320 Slog.e(TAG, "Trying to switch user from unauthorized app");
15321 return false;
15322 }
15323 if (mCurrentUserId == userId)
15324 return true;
15325
15326 synchronized (this) {
15327 // Check if user is already logged in, otherwise check if user exists first before
15328 // adding to the list of logged in users.
15329 if (mLoggedInUsers.indexOfKey(userId) < 0) {
15330 if (!userExists(userId)) {
15331 return false;
15332 }
15333 mLoggedInUsers.append(userId, userId);
15334 }
15335
15336 mCurrentUserId = userId;
15337 boolean haveActivities = mMainStack.switchUser(userId);
15338 if (!haveActivities) {
15339 startHomeActivityLocked(userId);
15340 }
15341 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015342 return true;
15343 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015344
15345 private boolean userExists(int userId) {
15346 try {
15347 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
15348 for (UserInfo user : users) {
15349 if (user.id == userId) {
15350 return true;
15351 }
15352 }
15353 } catch (RemoteException re) {
15354 // Won't happen, in same process
15355 }
15356
15357 return false;
15358 }
15359
15360
15361 private int applyUserId(int uid, int userId) {
15362 return UserId.getUid(userId, uid);
15363 }
15364
15365 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015366 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070015367 ApplicationInfo newInfo = new ApplicationInfo(info);
15368 newInfo.uid = applyUserId(info.uid, userId);
15369 if (newInfo.uid >= Process.FIRST_APPLICATION_UID) {
15370 newInfo.dataDir = USER_DATA_DIR + userId + "/"
15371 + info.packageName;
15372 }
15373 return newInfo;
15374 }
15375
15376 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015377 if (aInfo == null || aInfo.applicationInfo.uid < Process.FIRST_APPLICATION_UID
Amith Yamasani742a6712011-05-04 14:49:28 -070015378 || userId < 1) {
15379 return aInfo;
15380 }
15381
15382 ActivityInfo info = new ActivityInfo(aInfo);
15383 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15384 return info;
15385 }
15386
15387 static class ServiceMap {
15388
15389 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15390 = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15391 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15392 mServicesByIntentPerUser = new SparseArray<
15393 HashMap<Intent.FilterComparison, ServiceRecord>>();
15394
15395 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15396 // TODO: Deal with global services
15397 if (DEBUG_MU)
15398 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15399 return getServices(callingUser).get(name);
15400 }
15401
15402 ServiceRecord getServiceByName(ComponentName name) {
15403 return getServiceByName(name, -1);
15404 }
15405
15406 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15407 // TODO: Deal with global services
15408 if (DEBUG_MU)
15409 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15410 return getServicesByIntent(callingUser).get(filter);
15411 }
15412
15413 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15414 return getServiceByIntent(filter, -1);
15415 }
15416
15417 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15418 // TODO: Deal with global services
15419 getServices(callingUser).put(name, value);
15420 }
15421
15422 void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15423 ServiceRecord value) {
15424 // TODO: Deal with global services
15425 getServicesByIntent(callingUser).put(filter, value);
15426 }
15427
15428 void removeServiceByName(ComponentName name, int callingUser) {
15429 // TODO: Deal with global services
15430 ServiceRecord removed = getServices(callingUser).remove(name);
15431 if (DEBUG_MU)
15432 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15433 + " removed=" + removed);
15434 }
15435
15436 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15437 // TODO: Deal with global services
15438 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15439 if (DEBUG_MU)
15440 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15441 + " removed=" + removed);
15442 }
15443
15444 Collection<ServiceRecord> getAllServices(int callingUser) {
15445 // TODO: Deal with global services
15446 return getServices(callingUser).values();
15447 }
15448
15449 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15450 HashMap map = mServicesByNamePerUser.get(callingUser);
15451 if (map == null) {
15452 map = new HashMap<ComponentName, ServiceRecord>();
15453 mServicesByNamePerUser.put(callingUser, map);
15454 }
15455 return map;
15456 }
15457
15458 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15459 int callingUser) {
15460 HashMap map = mServicesByIntentPerUser.get(callingUser);
15461 if (map == null) {
15462 map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15463 mServicesByIntentPerUser.put(callingUser, map);
15464 }
15465 return map;
15466 }
15467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015468}