blob: 10a0efef37e3d5b0ffd43c8b11ff3559a0149905 [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
2096 ServiceManager.addService("activity", m);
2097 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07002098 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08002099 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100 if (MONITOR_CPU_USAGE) {
2101 ServiceManager.addService("cpuinfo", new CpuBinder(m));
2102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 ServiceManager.addService("permission", new PermissionController(m));
2104
2105 ApplicationInfo info =
2106 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07002107 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07002108 mSystemThread.installSystemApplicationInfo(info);
2109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002110 synchronized (mSelf) {
2111 ProcessRecord app = mSelf.newProcessRecordLocked(
2112 mSystemThread.getApplicationThread(), info,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002113 info.processName, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002115 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07002116 app.maxAdj = ProcessList.SYSTEM_ADJ;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002117 mSelf.mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 synchronized (mSelf.mPidsSelfLocked) {
2119 mSelf.mPidsSelfLocked.put(app.pid, app);
2120 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002121 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 }
2123 } catch (PackageManager.NameNotFoundException e) {
2124 throw new RuntimeException(
2125 "Unable to find android system package", e);
2126 }
2127 }
2128
2129 public void setWindowManager(WindowManagerService wm) {
2130 mWindowManager = wm;
2131 }
2132
2133 public static final Context main(int factoryTest) {
2134 AThread thr = new AThread();
2135 thr.start();
2136
2137 synchronized (thr) {
2138 while (thr.mService == null) {
2139 try {
2140 thr.wait();
2141 } catch (InterruptedException e) {
2142 }
2143 }
2144 }
2145
2146 ActivityManagerService m = thr.mService;
2147 mSelf = m;
2148 ActivityThread at = ActivityThread.systemMain();
2149 mSystemThread = at;
2150 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08002151 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 m.mContext = context;
2153 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002154 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155
2156 m.mBatteryStatsService.publish(context);
2157 m.mUsageStatsService.publish(context);
2158
2159 synchronized (thr) {
2160 thr.mReady = true;
2161 thr.notifyAll();
2162 }
2163
2164 m.startRunning(null, null, null, null);
2165
2166 return context;
2167 }
2168
2169 public static ActivityManagerService self() {
2170 return mSelf;
2171 }
2172
2173 static class AThread extends Thread {
2174 ActivityManagerService mService;
2175 boolean mReady = false;
2176
2177 public AThread() {
2178 super("ActivityManager");
2179 }
2180
2181 public void run() {
2182 Looper.prepare();
2183
2184 android.os.Process.setThreadPriority(
2185 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07002186 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187
2188 ActivityManagerService m = new ActivityManagerService();
2189
2190 synchronized (this) {
2191 mService = m;
2192 notifyAll();
2193 }
2194
2195 synchronized (this) {
2196 while (!mReady) {
2197 try {
2198 wait();
2199 } catch (InterruptedException e) {
2200 }
2201 }
2202 }
2203
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07002204 // For debug builds, log event loop stalls to dropbox for analysis.
2205 if (StrictMode.conditionallyEnableDebugLogging()) {
2206 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
2207 }
2208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 Looper.loop();
2210 }
2211 }
2212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 static class MemBinder extends Binder {
2214 ActivityManagerService mActivityManagerService;
2215 MemBinder(ActivityManagerService activityManagerService) {
2216 mActivityManagerService = activityManagerService;
2217 }
2218
2219 @Override
2220 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002221 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2222 != PackageManager.PERMISSION_GRANTED) {
2223 pw.println("Permission Denial: can't dump meminfo from from pid="
2224 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2225 + " without permission " + android.Manifest.permission.DUMP);
2226 return;
2227 }
2228
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08002229 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08002230 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 }
2232 }
2233
Chet Haase9c1e23b2011-03-24 10:51:31 -07002234 static class GraphicsBinder extends Binder {
2235 ActivityManagerService mActivityManagerService;
2236 GraphicsBinder(ActivityManagerService activityManagerService) {
2237 mActivityManagerService = activityManagerService;
2238 }
2239
2240 @Override
2241 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002242 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2243 != PackageManager.PERMISSION_GRANTED) {
2244 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2245 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2246 + " without permission " + android.Manifest.permission.DUMP);
2247 return;
2248 }
2249
Dianne Hackborne17aeb32011-04-07 15:11:57 -07002250 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07002251 }
2252 }
2253
Jeff Brown6754ba22011-12-14 20:20:01 -08002254 static class DbBinder extends Binder {
2255 ActivityManagerService mActivityManagerService;
2256 DbBinder(ActivityManagerService activityManagerService) {
2257 mActivityManagerService = activityManagerService;
2258 }
2259
2260 @Override
2261 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2262 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2263 != PackageManager.PERMISSION_GRANTED) {
2264 pw.println("Permission Denial: can't dump dbinfo from from pid="
2265 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2266 + " without permission " + android.Manifest.permission.DUMP);
2267 return;
2268 }
2269
2270 mActivityManagerService.dumpDbInfo(fd, pw, args);
2271 }
2272 }
2273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 static class CpuBinder extends Binder {
2275 ActivityManagerService mActivityManagerService;
2276 CpuBinder(ActivityManagerService activityManagerService) {
2277 mActivityManagerService = activityManagerService;
2278 }
2279
2280 @Override
2281 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07002282 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2283 != PackageManager.PERMISSION_GRANTED) {
2284 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2285 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2286 + " without permission " + android.Manifest.permission.DUMP);
2287 return;
2288 }
2289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002291 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
2292 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
2293 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 }
2295 }
2296 }
2297
2298 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002299 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07002300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 File dataDir = Environment.getDataDirectory();
2302 File systemDir = new File(dataDir, "system");
2303 systemDir.mkdirs();
2304 mBatteryStatsService = new BatteryStatsService(new File(
2305 systemDir, "batterystats.bin").toString());
2306 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002307 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07002308 mOnBattery = DEBUG_POWER ? true
2309 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002310 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002312 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07002313 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314
Jack Palevichb90d28c2009-07-22 15:35:24 -07002315 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2316 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08002318 mConfiguration.setToDefaults();
2319 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08002320 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 mProcessStats.init();
2322
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002323 mCompatModePackages = new CompatModePackages(this, systemDir);
2324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 // Add ourself to the Watchdog monitors.
2326 Watchdog.getInstance().addMonitor(this);
2327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 mProcessStatsThread = new Thread("ProcessStats") {
2329 public void run() {
2330 while (true) {
2331 try {
2332 try {
2333 synchronized(this) {
2334 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002335 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002337 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 // + ", write delay=" + nextWriteDelay);
2339 if (nextWriteDelay < nextCpuDelay) {
2340 nextCpuDelay = nextWriteDelay;
2341 }
2342 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002343 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 this.wait(nextCpuDelay);
2345 }
2346 }
2347 } catch (InterruptedException e) {
2348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 updateCpuStatsNow();
2350 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002351 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 }
2353 }
2354 }
2355 };
2356 mProcessStatsThread.start();
2357 }
2358
2359 @Override
2360 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2361 throws RemoteException {
2362 try {
2363 return super.onTransact(code, data, reply, flags);
2364 } catch (RuntimeException e) {
2365 // The activity manager only throws security exceptions, so let's
2366 // log all others.
2367 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002368 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 }
2370 throw e;
2371 }
2372 }
2373
2374 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002375 final long now = SystemClock.uptimeMillis();
2376 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2377 return;
2378 }
2379 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
2380 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 mProcessStatsThread.notify();
2382 }
2383 }
2384 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 void updateCpuStatsNow() {
2387 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002388 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 final long now = SystemClock.uptimeMillis();
2390 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07002393 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2394 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 haveNewCpuStats = true;
2396 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002397 //Slog.i(TAG, mProcessStats.printCurrentState());
2398 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 // + mProcessStats.getTotalCpuPercent() + "%");
2400
Joe Onorato8a9b2202010-02-26 18:56:32 -08002401 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 if ("true".equals(SystemProperties.get("events.cpu"))) {
2403 int user = mProcessStats.getLastUserTime();
2404 int system = mProcessStats.getLastSystemTime();
2405 int iowait = mProcessStats.getLastIoWaitTime();
2406 int irq = mProcessStats.getLastIrqTime();
2407 int softIrq = mProcessStats.getLastSoftIrqTime();
2408 int idle = mProcessStats.getLastIdleTime();
2409
2410 int total = user + system + iowait + irq + softIrq + idle;
2411 if (total == 0) total = 1;
2412
Doug Zongker2bec3d42009-12-04 12:52:44 -08002413 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 ((user+system+iowait+irq+softIrq) * 100) / total,
2415 (user * 100) / total,
2416 (system * 100) / total,
2417 (iowait * 100) / total,
2418 (irq * 100) / total,
2419 (softIrq * 100) / total);
2420 }
2421 }
2422
Amith Yamasanie43530a2009-08-21 13:11:37 -07002423 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07002424 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002425 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 synchronized(mPidsSelfLocked) {
2427 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002428 if (mOnBattery) {
2429 int perc = bstats.startAddingCpuLocked();
2430 int totalUTime = 0;
2431 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07002432 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002434 ProcessStats.Stats st = mProcessStats.getStats(i);
2435 if (!st.working) {
2436 continue;
2437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002439 int otherUTime = (st.rel_utime*perc)/100;
2440 int otherSTime = (st.rel_stime*perc)/100;
2441 totalUTime += otherUTime;
2442 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 if (pr != null) {
2444 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002445 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2446 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002447 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07002448 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002449 } else {
2450 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07002451 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002452 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002453 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2454 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002455 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 }
2458 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002459 bstats.finishAddingCpuLocked(perc, totalUTime,
2460 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 }
2462 }
2463 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2466 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002467 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 }
2469 }
2470 }
2471 }
2472
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002473 @Override
2474 public void batteryNeedsCpuUpdate() {
2475 updateCpuStatsNow();
2476 }
2477
2478 @Override
2479 public void batteryPowerChanged(boolean onBattery) {
2480 // When plugging in, update the CPU stats first before changing
2481 // the plug state.
2482 updateCpuStatsNow();
2483 synchronized (this) {
2484 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002485 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002486 }
2487 }
2488 }
2489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 /**
2491 * Initialize the application bind args. These are passed to each
2492 * process when the bindApplication() IPC is sent to the process. They're
2493 * lazily setup to make sure the services are running when they're asked for.
2494 */
2495 private HashMap<String, IBinder> getCommonServicesLocked() {
2496 if (mAppBindArgs == null) {
2497 mAppBindArgs = new HashMap<String, IBinder>();
2498
2499 // Setup the application init args
2500 mAppBindArgs.put("package", ServiceManager.getService("package"));
2501 mAppBindArgs.put("window", ServiceManager.getService("window"));
2502 mAppBindArgs.put(Context.ALARM_SERVICE,
2503 ServiceManager.getService(Context.ALARM_SERVICE));
2504 }
2505 return mAppBindArgs;
2506 }
2507
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002508 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 if (mFocusedActivity != r) {
2510 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08002511 if (r != null) {
2512 mWindowManager.setFocusedApp(r.appToken, true);
2513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 }
2515 }
2516
Dianne Hackborn906497c2010-05-10 15:57:38 -07002517 private final void updateLruProcessInternalLocked(ProcessRecord app,
2518 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002520 int lrui = mLruProcesses.indexOf(app);
2521 if (lrui >= 0) mLruProcesses.remove(lrui);
2522
2523 int i = mLruProcesses.size()-1;
2524 int skipTop = 0;
2525
Dianne Hackborn906497c2010-05-10 15:57:38 -07002526 app.lruSeq = mLruSeq;
2527
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002528 // compute the new weight for this process.
2529 if (updateActivityTime) {
2530 app.lastActivityTime = SystemClock.uptimeMillis();
2531 }
2532 if (app.activities.size() > 0) {
2533 // If this process has activities, we more strongly want to keep
2534 // it around.
2535 app.lruWeight = app.lastActivityTime;
2536 } else if (app.pubProviders.size() > 0) {
2537 // If this process contains content providers, we want to keep
2538 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002539 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002540 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002541 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002542 } else {
2543 // If this process doesn't have activities, we less strongly
2544 // want to keep it around, and generally want to avoid getting
2545 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002546 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002547 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002548 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002549 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07002550
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002551 while (i >= 0) {
2552 ProcessRecord p = mLruProcesses.get(i);
2553 // If this app shouldn't be in front of the first N background
2554 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002555 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002556 skipTop--;
2557 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07002558 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002559 mLruProcesses.add(i+1, app);
2560 break;
2561 }
2562 i--;
2563 }
2564 if (i < 0) {
2565 mLruProcesses.add(0, app);
2566 }
2567
Dianne Hackborn906497c2010-05-10 15:57:38 -07002568 // If the app is currently using a content provider or service,
2569 // bump those processes as well.
2570 if (app.connections.size() > 0) {
2571 for (ConnectionRecord cr : app.connections) {
2572 if (cr.binding != null && cr.binding.service != null
2573 && cr.binding.service.app != null
2574 && cr.binding.service.app.lruSeq != mLruSeq) {
2575 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
2576 updateActivityTime, i+1);
2577 }
2578 }
2579 }
2580 if (app.conProviders.size() > 0) {
2581 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07002582 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
2583 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07002584 updateActivityTime, i+1);
2585 }
2586 }
2587 }
2588
Joe Onorato8a9b2202010-02-26 18:56:32 -08002589 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 if (oomAdj) {
2591 updateOomAdjLocked();
2592 }
2593 }
2594
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002595 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07002596 boolean oomAdj, boolean updateActivityTime) {
2597 mLruSeq++;
2598 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
2599 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002600
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002601 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 String processName, int uid) {
2603 if (uid == Process.SYSTEM_UID) {
2604 // The system gets to run in any process. If there are multiple
2605 // processes with the same uid, just pick the first (this
2606 // should never happen).
2607 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
2608 processName);
2609 return procs != null ? procs.valueAt(0) : null;
2610 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002611 // uid = applyUserId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 ProcessRecord proc = mProcessNames.get(processName, uid);
2613 return proc;
2614 }
2615
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002616 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002617 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07002618 try {
2619 if (pm.performDexOpt(packageName)) {
2620 mDidDexOpt = true;
2621 }
2622 } catch (RemoteException e) {
2623 }
2624 }
2625
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002626 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 int transit = mWindowManager.getPendingAppTransition();
2628 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2629 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
2630 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
2631 }
2632
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002633 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002635 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2636 boolean isolated) {
2637 ProcessRecord app;
2638 if (!isolated) {
2639 app = getProcessRecordLocked(processName, info.uid);
2640 } else {
2641 // If this is an isolated process, it can't re-use an existing process.
2642 app = null;
2643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 // We don't have to do anything more if:
2645 // (1) There is an existing application record; and
2646 // (2) The caller doesn't think it is dead, OR there is no thread
2647 // object attached to it so we know it couldn't have crashed; and
2648 // (3) There is a pid assigned to it, so it is either starting or
2649 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002650 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 + " app=" + app + " knownToBeDead=" + knownToBeDead
2652 + " thread=" + (app != null ? app.thread : null)
2653 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01002654 if (app != null && app.pid > 0) {
2655 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08002656 // We already have the app running, or are waiting for it to
2657 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002658 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002659 // If this is a new package in the process, add the package to the list
2660 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002661 return app;
2662 } else {
2663 // An application record is attached to a previous process,
2664 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002665 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002666 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 String hostingNameStr = hostingName != null
2671 ? hostingName.flattenToShortString() : null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002672
2673 if (!isolated) {
2674 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2675 // If we are in the background, then check to see if this process
2676 // is bad. If so, we will just silently fail.
2677 if (mBadProcesses.get(info.processName, info.uid) != null) {
2678 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2679 + "/" + info.processName);
2680 return null;
2681 }
2682 } else {
2683 // When the user is explicitly starting a process, then clear its
2684 // crash count so that we won't make it bad until they see at
2685 // least one crash dialog again, and make the process good again
2686 // if it had been bad.
2687 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002688 + "/" + info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002689 mProcessCrashTimes.remove(info.processName, info.uid);
2690 if (mBadProcesses.get(info.processName, info.uid) != null) {
2691 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
2692 info.processName);
2693 mBadProcesses.remove(info.processName, info.uid);
2694 if (app != null) {
2695 app.bad = false;
2696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 }
2698 }
2699 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002702 app = newProcessRecordLocked(null, info, processName, isolated);
2703 if (app == null) {
2704 Slog.w(TAG, "Failed making new process record for "
2705 + processName + "/" + info.uid + " isolated=" + isolated);
2706 return null;
2707 }
2708 mProcessNames.put(processName, app.uid, app);
2709 if (isolated) {
2710 mIsolatedProcesses.put(app.uid, app);
2711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 } else {
2713 // If this is a new package in the process, add the package to the list
2714 app.addPackage(info.packageName);
2715 }
2716
2717 // If the system is not ready yet, then hold off on starting this
2718 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002719 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002720 && !isAllowedWhileBooting(info)
2721 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 if (!mProcessesOnHold.contains(app)) {
2723 mProcessesOnHold.add(app);
2724 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002725 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 return app;
2727 }
2728
2729 startProcessLocked(app, hostingType, hostingNameStr);
2730 return (app.pid != 0) ? app : null;
2731 }
2732
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002733 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2734 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2735 }
2736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 private final void startProcessLocked(ProcessRecord app,
2738 String hostingType, String hostingNameStr) {
2739 if (app.pid > 0 && app.pid != MY_PID) {
2740 synchronized (mPidsSelfLocked) {
2741 mPidsSelfLocked.remove(app.pid);
2742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2743 }
2744 app.pid = 0;
2745 }
2746
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002747 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2748 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 mProcessesOnHold.remove(app);
2750
2751 updateCpuStats();
2752
2753 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2754 mProcDeaths[0] = 0;
2755
2756 try {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002757 int uid = app.uid;
Amith Yamasani742a6712011-05-04 14:49:28 -07002758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 int[] gids = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002760 if (!app.isolated) {
2761 try {
2762 gids = mContext.getPackageManager().getPackageGids(
2763 app.info.packageName);
2764 } catch (PackageManager.NameNotFoundException e) {
2765 Slog.w(TAG, "Unable to retrieve gids", e);
2766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 }
2768 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2769 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2770 && mTopComponent != null
2771 && app.processName.equals(mTopComponent.getPackageName())) {
2772 uid = 0;
2773 }
2774 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2775 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2776 uid = 0;
2777 }
2778 }
2779 int debugFlags = 0;
2780 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2781 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07002782 // Also turn on CheckJNI for debuggable apps. It's quite
2783 // awkward to turn on otherwise.
2784 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08002786 // Run the app in safe mode if its manifest requests so or the
2787 // system is booted in safe mode.
2788 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2789 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08002790 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2793 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2794 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07002795 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2796 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 if ("1".equals(SystemProperties.get("debug.assert"))) {
2799 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2800 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07002801
2802 // Start the process. It will either succeed and return a result containing
2803 // the PID of the new process, or else throw a RuntimeException.
2804 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07002805 app.processName, uid, uid, gids, debugFlags,
2806 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2809 synchronized (bs) {
2810 if (bs.isOnBattery()) {
2811 app.batteryStats.incStartsLocked();
2812 }
2813 }
2814
Jeff Brown3f9dd282011-07-08 20:02:19 -07002815 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 app.processName, hostingType,
2817 hostingNameStr != null ? hostingNameStr : "");
2818
2819 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002820 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 }
2822
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002823 StringBuilder buf = mStringBuilder;
2824 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 buf.append("Start proc ");
2826 buf.append(app.processName);
2827 buf.append(" for ");
2828 buf.append(hostingType);
2829 if (hostingNameStr != null) {
2830 buf.append(" ");
2831 buf.append(hostingNameStr);
2832 }
2833 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002834 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 buf.append(" uid=");
2836 buf.append(uid);
2837 buf.append(" gids={");
2838 if (gids != null) {
2839 for (int gi=0; gi<gids.length; gi++) {
2840 if (gi != 0) buf.append(", ");
2841 buf.append(gids[gi]);
2842
2843 }
2844 }
2845 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002846 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002847 app.pid = startResult.pid;
2848 app.usingWrapper = startResult.usingWrapper;
2849 app.removed = false;
2850 synchronized (mPidsSelfLocked) {
2851 this.mPidsSelfLocked.put(startResult.pid, app);
2852 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2853 msg.obj = app;
2854 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2855 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 }
2857 } catch (RuntimeException e) {
2858 // XXX do better error recovery.
2859 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002860 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002861 }
2862 }
2863
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002864 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 if (resumed) {
2866 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2867 } else {
2868 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2869 }
2870 }
2871
Amith Yamasani742a6712011-05-04 14:49:28 -07002872 boolean startHomeActivityLocked(int userId) {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002873 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2874 && mTopAction == null) {
2875 // We are running in factory test mode, but unable to find
2876 // the factory test app, so just sit around displaying the
2877 // error message and don't try to start anything.
2878 return false;
2879 }
2880 Intent intent = new Intent(
2881 mTopAction,
2882 mTopData != null ? Uri.parse(mTopData) : null);
2883 intent.setComponent(mTopComponent);
2884 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2885 intent.addCategory(Intent.CATEGORY_HOME);
2886 }
2887 ActivityInfo aInfo =
2888 intent.resolveActivityInfo(mContext.getPackageManager(),
2889 STOCK_PM_FLAGS);
2890 if (aInfo != null) {
2891 intent.setComponent(new ComponentName(
2892 aInfo.applicationInfo.packageName, aInfo.name));
2893 // Don't do this if the home app is currently being
2894 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002895 aInfo = new ActivityInfo(aInfo);
2896 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002897 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2898 aInfo.applicationInfo.uid);
2899 if (app == null || app.instrumentationClass == null) {
2900 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002901 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002902 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002903 }
2904 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002905
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002906 return true;
2907 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002908
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002909 /**
2910 * Starts the "new version setup screen" if appropriate.
2911 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002912 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002913 // Only do this once per boot.
2914 if (mCheckedForSetup) {
2915 return;
2916 }
2917
2918 // We will show this screen if the current one is a different
2919 // version than the last one shown, and we are not running in
2920 // low-level factory test mode.
2921 final ContentResolver resolver = mContext.getContentResolver();
2922 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2923 Settings.Secure.getInt(resolver,
2924 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2925 mCheckedForSetup = true;
2926
2927 // See if we should be showing the platform update setup UI.
2928 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2929 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2930 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2931
2932 // We don't allow third party apps to replace this.
2933 ResolveInfo ri = null;
2934 for (int i=0; ris != null && i<ris.size(); i++) {
2935 if ((ris.get(i).activityInfo.applicationInfo.flags
2936 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2937 ri = ris.get(i);
2938 break;
2939 }
2940 }
2941
2942 if (ri != null) {
2943 String vers = ri.activityInfo.metaData != null
2944 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2945 : null;
2946 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2947 vers = ri.activityInfo.applicationInfo.metaData.getString(
2948 Intent.METADATA_SETUP_VERSION);
2949 }
2950 String lastVers = Settings.Secure.getString(
2951 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2952 if (vers != null && !vers.equals(lastVers)) {
2953 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2954 intent.setComponent(new ComponentName(
2955 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002956 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002957 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002958 }
2959 }
2960 }
2961 }
2962
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002963 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002964 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002965 }
2966
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002967 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002968 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002969 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2970 }
2971 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002972
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002973 public void setFrontActivityScreenCompatMode(int mode) {
2974 synchronized (this) {
2975 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2976 }
2977 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002978
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002979 public int getPackageScreenCompatMode(String packageName) {
2980 synchronized (this) {
2981 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2982 }
2983 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002984
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002985 public void setPackageScreenCompatMode(String packageName, int mode) {
2986 synchronized (this) {
2987 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002988 }
2989 }
2990
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002991 public boolean getPackageAskScreenCompat(String packageName) {
2992 synchronized (this) {
2993 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2994 }
2995 }
2996
2997 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2998 synchronized (this) {
2999 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3000 }
3001 }
3002
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003003 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003004 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003005
3006 final int identHash = System.identityHashCode(r);
3007 updateUsageStats(r, true);
3008
3009 int i = mWatchers.beginBroadcast();
3010 while (i > 0) {
3011 i--;
3012 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3013 if (w != null) {
3014 try {
3015 w.activityResuming(identHash);
3016 } catch (RemoteException e) {
3017 }
3018 }
3019 }
3020 mWatchers.finishBroadcast();
3021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022
Jeff Sharkeya4620792011-05-20 15:29:23 -07003023 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
3024 int i = mProcessObservers.beginBroadcast();
3025 while (i > 0) {
3026 i--;
3027 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3028 if (observer != null) {
3029 try {
3030 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
3031 } catch (RemoteException e) {
3032 }
3033 }
3034 }
3035 mProcessObservers.finishBroadcast();
3036 }
3037
3038 private void dispatchProcessDied(int pid, int uid) {
3039 int i = mProcessObservers.beginBroadcast();
3040 while (i > 0) {
3041 i--;
3042 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3043 if (observer != null) {
3044 try {
3045 observer.onProcessDied(pid, uid);
3046 } catch (RemoteException e) {
3047 }
3048 }
3049 }
3050 mProcessObservers.finishBroadcast();
3051 }
3052
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003053 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003054 final int N = mPendingActivityLaunches.size();
3055 if (N <= 0) {
3056 return;
3057 }
3058 for (int i=0; i<N; i++) {
3059 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003060 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003061 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3062 doResume && i == (N-1));
3063 }
3064 mPendingActivityLaunches.clear();
3065 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003066
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003067 public final int startActivity(IApplicationThread caller,
3068 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3069 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003070 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3071 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Amith Yamasani742a6712011-05-04 14:49:28 -07003072 int userId = 0;
3073 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
3074 // Requesting home, set the identity to the current user
3075 // HACK!
3076 userId = mCurrentUserId;
3077 } else {
3078 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
3079 // the current user's userId
3080 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
3081 userId = 0;
3082 } else {
3083 userId = Binder.getOrigCallingUser();
3084 }
3085 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003086 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -07003087 grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded,
3088 debug, profileFile, profileFd, autoStopProfiler, null, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003089 }
3090
3091 public final WaitResult startActivityAndWait(IApplicationThread caller,
3092 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3093 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003094 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
3095 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003096 WaitResult res = new WaitResult();
Amith Yamasani742a6712011-05-04 14:49:28 -07003097 int userId = Binder.getOrigCallingUser();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003098 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003099 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003100 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
Amith Yamasani742a6712011-05-04 14:49:28 -07003101 res, null, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08003102 return res;
3103 }
3104
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003105 public final int startActivityWithConfig(IApplicationThread caller,
3106 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3107 int grantedMode, IBinder resultTo,
3108 String resultWho, int requestCode, boolean onlyIfNeeded,
3109 boolean debug, Configuration config) {
Amith Yamasani742a6712011-05-04 14:49:28 -07003110 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003111 grantedUriPermissions, grantedMode, resultTo, resultWho,
Amith Yamasani742a6712011-05-04 14:49:28 -07003112 requestCode, onlyIfNeeded,
3113 debug, null, null, false, null, config, Binder.getOrigCallingUser());
3114 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07003115 }
3116
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003117 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003118 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003119 IBinder resultTo, String resultWho, int requestCode,
3120 int flagsMask, int flagsValues) {
3121 // Refuse possible leaked file descriptors
3122 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3123 throw new IllegalArgumentException("File descriptors passed in Intent");
3124 }
3125
3126 IIntentSender sender = intent.getTarget();
3127 if (!(sender instanceof PendingIntentRecord)) {
3128 throw new IllegalArgumentException("Bad PendingIntent object");
3129 }
3130
3131 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003132
3133 synchronized (this) {
3134 // If this is coming from the currently resumed activity, it is
3135 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003136 if (mMainStack.mResumedActivity != null
3137 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07003138 Binder.getCallingUid()) {
3139 mAppSwitchesAllowedTime = 0;
3140 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003141 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003142 int ret = pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003143 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
Amith Yamasani742a6712011-05-04 14:49:28 -07003144 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07003145 }
3146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003147 public boolean startNextMatchingActivity(IBinder callingActivity,
3148 Intent intent) {
3149 // Refuse possible leaked file descriptors
3150 if (intent != null && intent.hasFileDescriptors() == true) {
3151 throw new IllegalArgumentException("File descriptors passed in Intent");
3152 }
3153
3154 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003155 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
3156 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 return false;
3158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 if (r.app == null || r.app.thread == null) {
3160 // The caller is not running... d'oh!
3161 return false;
3162 }
3163 intent = new Intent(intent);
3164 // The caller is not allowed to change the data.
3165 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3166 // And we are resetting to find the next component...
3167 intent.setComponent(null);
3168
3169 ActivityInfo aInfo = null;
3170 try {
3171 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003172 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07003174 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003175
3176 // Look for the original activity in the list...
3177 final int N = resolves != null ? resolves.size() : 0;
3178 for (int i=0; i<N; i++) {
3179 ResolveInfo rInfo = resolves.get(i);
3180 if (rInfo.activityInfo.packageName.equals(r.packageName)
3181 && rInfo.activityInfo.name.equals(r.info.name)) {
3182 // We found the current one... the next matching is
3183 // after it.
3184 i++;
3185 if (i<N) {
3186 aInfo = resolves.get(i).activityInfo;
3187 }
3188 break;
3189 }
3190 }
3191 } catch (RemoteException e) {
3192 }
3193
3194 if (aInfo == null) {
3195 // Nobody who is next!
3196 return false;
3197 }
3198
3199 intent.setComponent(new ComponentName(
3200 aInfo.applicationInfo.packageName, aInfo.name));
3201 intent.setFlags(intent.getFlags()&~(
3202 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3203 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3204 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3205 Intent.FLAG_ACTIVITY_NEW_TASK));
3206
3207 // Okay now we need to start the new activity, replacing the
3208 // currently running activity. This is a little tricky because
3209 // we want to start the new one as if the current one is finished,
3210 // but not finish the current one first so that there is no flicker.
3211 // And thus...
3212 final boolean wasFinishing = r.finishing;
3213 r.finishing = true;
3214
3215 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003216 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003217 final String resultWho = r.resultWho;
3218 final int requestCode = r.requestCode;
3219 r.resultTo = null;
3220 if (resultTo != null) {
3221 resultTo.removeResultsLocked(r, resultWho, requestCode);
3222 }
3223
3224 final long origId = Binder.clearCallingIdentity();
3225 // XXX we are not dealing with propagating grantedUriPermissions...
3226 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003227 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003228 r.resolvedType, null, 0, aInfo,
3229 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003230 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003231 Binder.restoreCallingIdentity(origId);
3232
3233 r.finishing = wasFinishing;
3234 if (res != START_SUCCESS) {
3235 return false;
3236 }
3237 return true;
3238 }
3239 }
3240
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003241 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003242 Intent intent, String resolvedType, IBinder resultTo,
3243 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003244
3245 // This is so super not safe, that only the system (or okay root)
3246 // can do it.
Amith Yamasani742a6712011-05-04 14:49:28 -07003247 int userId = Binder.getOrigCallingUser();
Dianne Hackborn2d91af02009-07-16 13:34:33 -07003248 final int callingUid = Binder.getCallingUid();
3249 if (callingUid != 0 && callingUid != Process.myUid()) {
3250 throw new SecurityException(
3251 "startActivityInPackage only available to the system");
3252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253
Amith Yamasani742a6712011-05-04 14:49:28 -07003254 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003255 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
Amith Yamasani742a6712011-05-04 14:49:28 -07003256 null, null, false, null, null, userId);
3257 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003258 }
3259
3260 public final int startActivities(IApplicationThread caller,
3261 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
Amith Yamasani742a6712011-05-04 14:49:28 -07003262 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
3263 Binder.getOrigCallingUser());
3264 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003265 }
3266
3267 public final int startActivitiesInPackage(int uid,
3268 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
3269
3270 // This is so super not safe, that only the system (or okay root)
3271 // can do it.
3272 final int callingUid = Binder.getCallingUid();
3273 if (callingUid != 0 && callingUid != Process.myUid()) {
3274 throw new SecurityException(
3275 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003276 }
Amith Yamasani742a6712011-05-04 14:49:28 -07003277 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
3278 UserId.getUserId(uid));
3279 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 }
3281
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003282 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003283 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08003284 // Quick case: check if the top-most recent task is the same.
3285 if (N > 0 && mRecentTasks.get(0) == task) {
3286 return;
3287 }
3288 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003289 for (int i=0; i<N; i++) {
3290 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07003291 if (task.userId == tr.userId
3292 && ((task.affinity != null && task.affinity.equals(tr.affinity))
3293 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003294 mRecentTasks.remove(i);
3295 i--;
3296 N--;
3297 if (task.intent == null) {
3298 // If the new recent task we are adding is not fully
3299 // specified, then replace it with the existing recent task.
3300 task = tr;
3301 }
3302 }
3303 }
3304 if (N >= MAX_RECENT_TASKS) {
3305 mRecentTasks.remove(N-1);
3306 }
3307 mRecentTasks.add(0, task);
3308 }
3309
3310 public void setRequestedOrientation(IBinder token,
3311 int requestedOrientation) {
3312 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003313 ActivityRecord r = mMainStack.isInStackLocked(token);
3314 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 return;
3316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003317 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003318 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003320 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08003321 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 if (config != null) {
3323 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08003324 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003325 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 }
3327 }
3328 Binder.restoreCallingIdentity(origId);
3329 }
3330 }
3331
3332 public int getRequestedOrientation(IBinder token) {
3333 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003334 ActivityRecord r = mMainStack.isInStackLocked(token);
3335 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3337 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08003338 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 }
3340 }
3341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003342 /**
3343 * This is the internal entry point for handling Activity.finish().
3344 *
3345 * @param token The Binder token referencing the Activity we want to finish.
3346 * @param resultCode Result code, if any, from this Activity.
3347 * @param resultData Result data (Intent), if any, from this Activity.
3348 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11003349 * @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 -08003350 */
3351 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3352 // Refuse possible leaked file descriptors
3353 if (resultData != null && resultData.hasFileDescriptors() == true) {
3354 throw new IllegalArgumentException("File descriptors passed in Intent");
3355 }
3356
3357 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003358 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003359 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003360 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 if (next != null) {
3362 // ask watcher if this is allowed
3363 boolean resumeOK = true;
3364 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003365 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003367 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003368 }
3369
3370 if (!resumeOK) {
3371 return false;
3372 }
3373 }
3374 }
3375 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003376 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 resultData, "app-request");
3378 Binder.restoreCallingIdentity(origId);
3379 return res;
3380 }
3381 }
3382
Dianne Hackborn860755f2010-06-03 18:47:52 -07003383 public final void finishHeavyWeightApp() {
3384 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3385 != PackageManager.PERMISSION_GRANTED) {
3386 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3387 + Binder.getCallingPid()
3388 + ", uid=" + Binder.getCallingUid()
3389 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3390 Slog.w(TAG, msg);
3391 throw new SecurityException(msg);
3392 }
3393
3394 synchronized(this) {
3395 if (mHeavyWeightProcess == null) {
3396 return;
3397 }
3398
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003399 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07003400 mHeavyWeightProcess.activities);
3401 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003402 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003403 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003404 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003405 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003406 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07003407 null, "finish-heavy");
3408 }
3409 }
3410 }
3411
3412 mHeavyWeightProcess = null;
3413 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3414 }
3415 }
3416
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003417 public void crashApplication(int uid, int initialPid, String packageName,
3418 String message) {
3419 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3420 != PackageManager.PERMISSION_GRANTED) {
3421 String msg = "Permission Denial: crashApplication() from pid="
3422 + Binder.getCallingPid()
3423 + ", uid=" + Binder.getCallingUid()
3424 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3425 Slog.w(TAG, msg);
3426 throw new SecurityException(msg);
3427 }
3428
3429 synchronized(this) {
3430 ProcessRecord proc = null;
3431
3432 // Figure out which process to kill. We don't trust that initialPid
3433 // still has any relation to current pids, so must scan through the
3434 // list.
3435 synchronized (mPidsSelfLocked) {
3436 for (int i=0; i<mPidsSelfLocked.size(); i++) {
3437 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003438 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003439 continue;
3440 }
3441 if (p.pid == initialPid) {
3442 proc = p;
3443 break;
3444 }
3445 for (String str : p.pkgList) {
3446 if (str.equals(packageName)) {
3447 proc = p;
3448 }
3449 }
3450 }
3451 }
3452
3453 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07003454 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003455 + " initialPid=" + initialPid
3456 + " packageName=" + packageName);
3457 return;
3458 }
3459
3460 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07003461 if (proc.pid == Process.myPid()) {
3462 Log.w(TAG, "crashApplication: trying to crash self!");
3463 return;
3464 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07003465 long ident = Binder.clearCallingIdentity();
3466 try {
3467 proc.thread.scheduleCrash(message);
3468 } catch (RemoteException e) {
3469 }
3470 Binder.restoreCallingIdentity(ident);
3471 }
3472 }
3473 }
3474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 public final void finishSubActivity(IBinder token, String resultWho,
3476 int requestCode) {
3477 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003478 ActivityRecord self = mMainStack.isInStackLocked(token);
3479 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480 return;
3481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482
3483 final long origId = Binder.clearCallingIdentity();
3484
3485 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003486 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3487 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 if (r.resultTo == self && r.requestCode == requestCode) {
3489 if ((r.resultWho == null && resultWho == null) ||
3490 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003491 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 Activity.RESULT_CANCELED, null, "request-sub");
3493 }
3494 }
3495 }
3496
3497 Binder.restoreCallingIdentity(origId);
3498 }
3499 }
3500
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003501 public boolean willActivityBeVisible(IBinder token) {
3502 synchronized(this) {
3503 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003504 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3505 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08003506 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08003507 return true;
3508 }
3509 if (r.fullscreen && !r.finishing) {
3510 return false;
3511 }
3512 }
3513 return true;
3514 }
3515 }
3516
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003517 public void overridePendingTransition(IBinder token, String packageName,
3518 int enterAnim, int exitAnim) {
3519 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003520 ActivityRecord self = mMainStack.isInStackLocked(token);
3521 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003522 return;
3523 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003524
3525 final long origId = Binder.clearCallingIdentity();
3526
3527 if (self.state == ActivityState.RESUMED
3528 || self.state == ActivityState.PAUSING) {
3529 mWindowManager.overridePendingAppTransition(packageName,
3530 enterAnim, exitAnim);
3531 }
3532
3533 Binder.restoreCallingIdentity(origId);
3534 }
3535 }
3536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 * Main function for removing an existing process from the activity manager
3539 * as a result of that process going away. Clears out all connections
3540 * to the process.
3541 */
3542 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003543 boolean restarting, boolean allowRestart) {
3544 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003546 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547 }
3548
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003549 if (mProfileProc == app) {
3550 clearProfilerLocked();
3551 }
3552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 // Just in case...
Dianne Hackborncbb722e2012-02-07 18:33:49 -08003554 mMainStack.appDiedLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003555
3556 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003557 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558
3559 boolean atTop = true;
3560 boolean hasVisibleActivities = false;
3561
3562 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003563 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003564 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 TAG, "Removing app " + app + " from history with " + i + " entries");
3566 while (i > 0) {
3567 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003568 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003569 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003570 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3571 if (r.app == app) {
3572 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003573 if (ActivityStack.DEBUG_ADD_REMOVE) {
3574 RuntimeException here = new RuntimeException("here");
3575 here.fillInStackTrace();
3576 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
3577 + ": haveState=" + r.haveState
3578 + " stateNotNeeded=" + r.stateNotNeeded
3579 + " finishing=" + r.finishing
3580 + " state=" + r.state, here);
3581 }
3582 if (!r.finishing) {
3583 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08003584 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3585 System.identityHashCode(r),
3586 r.task.taskId, r.shortComponentName,
3587 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003588 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003589 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003590 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003591 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08003592 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08003594 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003596 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597
3598 } else {
3599 // We have the current state for this activity, so
3600 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 TAG, "Keeping entry, setting app to null");
3603 if (r.visible) {
3604 hasVisibleActivities = true;
3605 }
3606 r.app = null;
3607 r.nowVisible = false;
3608 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07003609 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
3610 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 r.icicle = null;
3612 }
3613 }
3614
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003615 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616 }
3617 atTop = false;
3618 }
3619
3620 app.activities.clear();
3621
3622 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003623 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624 + " running instrumentation " + app.instrumentationClass);
3625 Bundle info = new Bundle();
3626 info.putString("shortMsg", "Process crashed.");
3627 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3628 }
3629
3630 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003631 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 // If there was nothing to resume, and we are not already
3633 // restarting this process, but there is a visible activity that
3634 // is hosted by the process... then make sure all visible
3635 // activities are running, taking care of restarting this
3636 // process.
3637 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003638 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 }
3640 }
3641 }
3642 }
3643
3644 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3645 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003647 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3648 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3650 return i;
3651 }
3652 }
3653 return -1;
3654 }
3655
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003656 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 IApplicationThread thread) {
3658 if (thread == null) {
3659 return null;
3660 }
3661
3662 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003663 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 }
3665
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003666 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 IApplicationThread thread) {
3668
3669 mProcDeaths[0]++;
3670
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003671 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3672 synchronized (stats) {
3673 stats.noteProcessDiedLocked(app.info.uid, pid);
3674 }
3675
Magnus Edlund7bb25812010-02-24 15:45:06 +01003676 // Clean up already done if the process has been re-started.
3677 if (app.pid == pid && app.thread != null &&
3678 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07003679 if (!app.killedBackground) {
3680 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3681 + ") has died.");
3682 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08003683 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003684 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 TAG, "Dying app: " + app + ", pid: " + pid
3686 + ", thread: " + thread.asBinder());
3687 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003688 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003689
3690 if (doLowMem) {
3691 // If there are no longer any background processes running,
3692 // and the app that died was not running instrumentation,
3693 // then tell everyone we are now low on memory.
3694 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003695 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3696 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07003697 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003698 haveBg = true;
3699 break;
3700 }
3701 }
3702
3703 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003704 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003705 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003706 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3707 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07003708 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003709 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3710 // The low memory report is overriding any current
3711 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003712 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07003713 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003714 rec.lastRequestedGc = 0;
3715 } else {
3716 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003718 rec.reportLowMemory = true;
3719 rec.lastLowMemory = now;
3720 mProcessesToGc.remove(rec);
3721 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 }
3723 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003724 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003725 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 }
3727 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003728 } else if (app.pid != pid) {
3729 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003730 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003731 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08003732 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003733 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003734 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 + thread.asBinder());
3736 }
3737 }
3738
Dan Egnor42471dd2010-01-07 17:25:22 -08003739 /**
3740 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003741 * @param clearTraces causes the dump file to be erased prior to the new
3742 * traces being written, if true; when false, the new traces will be
3743 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003744 * @param firstPids of dalvik VM processes to dump stack traces for first
3745 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08003746 * @return file containing stack traces, or null if no dump file is configured
3747 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003748 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3749 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003750 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3751 if (tracesPath == null || tracesPath.length() == 0) {
3752 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003754
3755 File tracesFile = new File(tracesPath);
3756 try {
3757 File tracesDir = tracesFile.getParentFile();
3758 if (!tracesDir.exists()) tracesFile.mkdirs();
3759 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3760
Christopher Tate6ee412d2010-05-28 12:01:56 -07003761 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003762 tracesFile.createNewFile();
3763 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3764 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003765 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003766 return null;
3767 }
3768
3769 // Use a FileObserver to detect when traces finish writing.
3770 // The order of traces is considered important to maintain for legibility.
3771 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3772 public synchronized void onEvent(int event, String path) { notify(); }
3773 };
3774
3775 try {
3776 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003777
3778 // First collect all of the stacks of the most important pids.
3779 try {
3780 int num = firstPids.size();
3781 for (int i = 0; i < num; i++) {
3782 synchronized (observer) {
3783 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3784 observer.wait(200); // Wait for write-close, give up after 200msec
3785 }
3786 }
3787 } catch (InterruptedException e) {
3788 Log.wtf(TAG, e);
3789 }
3790
3791 // Next measure CPU usage.
3792 if (processStats != null) {
3793 processStats.init();
3794 System.gc();
3795 processStats.update();
3796 try {
3797 synchronized (processStats) {
3798 processStats.wait(500); // measure over 1/2 second.
3799 }
3800 } catch (InterruptedException e) {
3801 }
3802 processStats.update();
3803
3804 // We'll take the stack crawls of just the top apps using CPU.
3805 final int N = processStats.countWorkingStats();
3806 int numProcs = 0;
3807 for (int i=0; i<N && numProcs<5; i++) {
3808 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3809 if (lastPids.indexOfKey(stats.pid) >= 0) {
3810 numProcs++;
3811 try {
3812 synchronized (observer) {
3813 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3814 observer.wait(200); // Wait for write-close, give up after 200msec
3815 }
3816 } catch (InterruptedException e) {
3817 Log.wtf(TAG, e);
3818 }
3819
3820 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003821 }
3822 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003823
3824 return tracesFile;
3825
Dan Egnor42471dd2010-01-07 17:25:22 -08003826 } finally {
3827 observer.stopWatching();
3828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 }
3830
Jeff Brown4d94a762010-09-23 11:33:28 -07003831 private final class AppNotResponding implements Runnable {
3832 private final ProcessRecord mApp;
3833 private final String mAnnotation;
3834
3835 public AppNotResponding(ProcessRecord app, String annotation) {
3836 mApp = app;
3837 mAnnotation = annotation;
3838 }
3839
3840 @Override
3841 public void run() {
3842 appNotResponding(mApp, null, null, mAnnotation);
3843 }
3844 }
3845
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003846 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3847 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003848 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3849 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3850
Dianne Hackborn287952c2010-09-22 22:34:31 -07003851 if (mController != null) {
3852 try {
3853 // 0 == continue, -1 = kill process immediately
3854 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3855 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3856 } catch (RemoteException e) {
3857 mController = null;
3858 }
3859 }
3860
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003861 long anrTime = SystemClock.uptimeMillis();
3862 if (MONITOR_CPU_USAGE) {
3863 updateCpuStatsNow();
3864 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003865
3866 synchronized (this) {
3867 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3868 if (mShuttingDown) {
3869 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3870 return;
3871 } else if (app.notResponding) {
3872 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3873 return;
3874 } else if (app.crashing) {
3875 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3876 return;
3877 }
3878
3879 // In case we come through here for the same app before completing
3880 // this one, mark as anring now so we will bail out.
3881 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003882
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003883 // Log the ANR to the event log.
3884 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3885 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003886
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003887 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003888 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003889
3890 int parentPid = app.pid;
3891 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003892 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003893
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003894 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003895
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003896 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3897 ProcessRecord r = mLruProcesses.get(i);
3898 if (r != null && r.thread != null) {
3899 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003900 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3901 if (r.persistent) {
3902 firstPids.add(pid);
3903 } else {
3904 lastPids.put(pid, Boolean.TRUE);
3905 }
3906 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003908 }
3909 }
3910
Dan Egnor42471dd2010-01-07 17:25:22 -08003911 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003912 StringBuilder info = mStringBuilder;
3913 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003914 info.append("ANR in ").append(app.processName);
3915 if (activity != null && activity.shortComponentName != null) {
3916 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003917 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003918 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003920 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003922 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003923 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925
Dianne Hackborn287952c2010-09-22 22:34:31 -07003926 final ProcessStats processStats = new ProcessStats(true);
3927
3928 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3929
Dan Egnor42471dd2010-01-07 17:25:22 -08003930 String cpuInfo = null;
3931 if (MONITOR_CPU_USAGE) {
3932 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003933 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003934 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003935 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003936 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003937 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 }
3939
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003940 info.append(processStats.printCurrentState(anrTime));
3941
Joe Onorato8a9b2202010-02-26 18:56:32 -08003942 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003943 if (tracesFile == null) {
3944 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3945 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3946 }
3947
Jeff Sharkeya353d262011-10-28 11:12:06 -07003948 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3949 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003950
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003951 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003953 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3954 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003955 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003956 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3957 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003960 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 }
3962 }
3963
Dan Egnor42471dd2010-01-07 17:25:22 -08003964 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3965 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3966 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003967
3968 synchronized (this) {
3969 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003970 Slog.w(TAG, "Killing " + app + ": background ANR");
3971 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3972 app.processName, app.setAdj, "background ANR");
3973 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003974 return;
3975 }
3976
3977 // Set the app's notResponding state, and look up the errorReportReceiver
3978 makeAppNotRespondingLocked(app,
3979 activity != null ? activity.shortComponentName : null,
3980 annotation != null ? "ANR " + annotation : "ANR",
3981 info.toString());
3982
3983 // Bring up the infamous App Not Responding dialog
3984 Message msg = Message.obtain();
3985 HashMap map = new HashMap();
3986 msg.what = SHOW_NOT_RESPONDING_MSG;
3987 msg.obj = map;
3988 map.put("app", app);
3989 if (activity != null) {
3990 map.put("activity", activity);
3991 }
3992
3993 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 }
3996
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003997 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3998 if (!mLaunchWarningShown) {
3999 mLaunchWarningShown = true;
4000 mHandler.post(new Runnable() {
4001 @Override
4002 public void run() {
4003 synchronized (ActivityManagerService.this) {
4004 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4005 d.show();
4006 mHandler.postDelayed(new Runnable() {
4007 @Override
4008 public void run() {
4009 synchronized (ActivityManagerService.this) {
4010 d.dismiss();
4011 mLaunchWarningShown = false;
4012 }
4013 }
4014 }, 4000);
4015 }
4016 }
4017 });
4018 }
4019 }
4020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 public boolean clearApplicationUserData(final String packageName,
Amith Yamasani742a6712011-05-04 14:49:28 -07004022 final IPackageDataObserver observer, final int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 int uid = Binder.getCallingUid();
4024 int pid = Binder.getCallingPid();
4025 long callingId = Binder.clearCallingIdentity();
4026 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004027 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 int pkgUid = -1;
4029 synchronized(this) {
4030 try {
4031 pkgUid = pm.getPackageUid(packageName);
4032 } catch (RemoteException e) {
4033 }
4034 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004035 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 return false;
4037 }
4038 if (uid == pkgUid || checkComponentPermission(
4039 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004040 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004042 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004043 } else {
4044 throw new SecurityException(pid+" does not have permission:"+
4045 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4046 "for process:"+packageName);
4047 }
4048 }
4049
4050 try {
4051 //clear application user data
4052 pm.clearApplicationUserData(packageName, observer);
4053 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4054 Uri.fromParts("package", packageName, null));
4055 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004056 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07004057 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 } catch (RemoteException e) {
4059 }
4060 } finally {
4061 Binder.restoreCallingIdentity(callingId);
4062 }
4063 return true;
4064 }
4065
Dianne Hackborn03abb812010-01-04 18:43:19 -08004066 public void killBackgroundProcesses(final String packageName) {
4067 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4068 != PackageManager.PERMISSION_GRANTED &&
4069 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4070 != PackageManager.PERMISSION_GRANTED) {
4071 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072 + Binder.getCallingPid()
4073 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08004074 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004075 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 throw new SecurityException(msg);
4077 }
4078
4079 long callingId = Binder.clearCallingIdentity();
4080 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004081 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 int pkgUid = -1;
4083 synchronized(this) {
4084 try {
4085 pkgUid = pm.getPackageUid(packageName);
4086 } catch (RemoteException e) {
4087 }
4088 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004089 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004090 return;
4091 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004092 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004093 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4094 }
4095 } finally {
4096 Binder.restoreCallingIdentity(callingId);
4097 }
4098 }
4099
4100 public void killAllBackgroundProcesses() {
4101 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4102 != PackageManager.PERMISSION_GRANTED) {
4103 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4104 + Binder.getCallingPid()
4105 + ", uid=" + Binder.getCallingUid()
4106 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4107 Slog.w(TAG, msg);
4108 throw new SecurityException(msg);
4109 }
4110
4111 long callingId = Binder.clearCallingIdentity();
4112 try {
4113 synchronized(this) {
4114 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4115 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4116 final int NA = apps.size();
4117 for (int ia=0; ia<NA; ia++) {
4118 ProcessRecord app = apps.valueAt(ia);
4119 if (app.persistent) {
4120 // we don't kill persistent processes
4121 continue;
4122 }
4123 if (app.removed) {
4124 procs.add(app);
4125 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
4126 app.removed = true;
4127 procs.add(app);
4128 }
4129 }
4130 }
4131
4132 int N = procs.size();
4133 for (int i=0; i<N; i++) {
4134 removeProcessLocked(procs.get(i), false, true, "kill all background");
4135 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004136 }
4137 } finally {
4138 Binder.restoreCallingIdentity(callingId);
4139 }
4140 }
4141
4142 public void forceStopPackage(final String packageName) {
4143 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4144 != PackageManager.PERMISSION_GRANTED) {
4145 String msg = "Permission Denial: forceStopPackage() from pid="
4146 + Binder.getCallingPid()
4147 + ", uid=" + Binder.getCallingUid()
4148 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004149 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004150 throw new SecurityException(msg);
4151 }
Amith Yamasani742a6712011-05-04 14:49:28 -07004152 final int userId = Binder.getOrigCallingUser();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004153 long callingId = Binder.clearCallingIdentity();
4154 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004155 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08004156 int pkgUid = -1;
4157 synchronized(this) {
4158 try {
4159 pkgUid = pm.getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07004160 // Convert the uid to the one for the calling user
4161 pkgUid = UserId.getUid(userId, pkgUid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004162 } catch (RemoteException e) {
4163 }
4164 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004166 return;
4167 }
4168 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004169 try {
4170 pm.setPackageStoppedState(packageName, true);
4171 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08004172 } catch (IllegalArgumentException e) {
4173 Slog.w(TAG, "Failed trying to unstop package "
4174 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08004175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 }
4177 } finally {
4178 Binder.restoreCallingIdentity(callingId);
4179 }
4180 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004181
4182 /*
4183 * The pkg name and uid have to be specified.
4184 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4185 */
4186 public void killApplicationWithUid(String pkg, int uid) {
4187 if (pkg == null) {
4188 return;
4189 }
4190 // Make sure the uid is valid.
4191 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004192 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004193 return;
4194 }
4195 int callerUid = Binder.getCallingUid();
4196 // Only the system server can kill an application
4197 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07004198 // Post an aysnc message to kill the application
4199 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4200 msg.arg1 = uid;
4201 msg.arg2 = 0;
4202 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07004203 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07004204 } else {
4205 throw new SecurityException(callerUid + " cannot kill pkg: " +
4206 pkg);
4207 }
4208 }
4209
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004210 public void closeSystemDialogs(String reason) {
4211 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004212 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004213 if (reason != null) {
4214 intent.putExtra("reason", reason);
4215 }
4216
4217 final int uid = Binder.getCallingUid();
4218 final long origId = Binder.clearCallingIdentity();
4219 synchronized (this) {
4220 int i = mWatchers.beginBroadcast();
4221 while (i > 0) {
4222 i--;
4223 IActivityWatcher w = mWatchers.getBroadcastItem(i);
4224 if (w != null) {
4225 try {
4226 w.closingSystemDialogs(reason);
4227 } catch (RemoteException e) {
4228 }
4229 }
4230 }
4231 mWatchers.finishBroadcast();
4232
Dianne Hackbornffa42482009-09-23 22:20:11 -07004233 mWindowManager.closeSystemDialogs(reason);
4234
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004235 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
4236 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004237 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004238 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07004239 Activity.RESULT_CANCELED, null, "close-sys");
4240 }
4241 }
4242
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004243 broadcastIntentLocked(null, null, intent, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004244 null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07004245 }
4246 Binder.restoreCallingIdentity(origId);
4247 }
4248
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004249 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004250 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004251 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4252 for (int i=pids.length-1; i>=0; i--) {
4253 infos[i] = new Debug.MemoryInfo();
4254 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004255 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07004256 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07004257 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07004258
Dianne Hackbornb437e092011-08-05 17:50:29 -07004259 public long[] getProcessPss(int[] pids) throws RemoteException {
4260 long[] pss = new long[pids.length];
4261 for (int i=pids.length-1; i>=0; i--) {
4262 pss[i] = Debug.getPss(pids[i]);
4263 }
4264 return pss;
4265 }
4266
Christopher Tate5e1ab332009-09-01 20:32:49 -07004267 public void killApplicationProcess(String processName, int uid) {
4268 if (processName == null) {
4269 return;
4270 }
4271
4272 int callerUid = Binder.getCallingUid();
4273 // Only the system server can kill an application
4274 if (callerUid == Process.SYSTEM_UID) {
4275 synchronized (this) {
4276 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07004277 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07004278 try {
4279 app.thread.scheduleSuicide();
4280 } catch (RemoteException e) {
4281 // If the other end already died, then our work here is done.
4282 }
4283 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004284 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07004285 + processName + " / " + uid);
4286 }
4287 }
4288 } else {
4289 throw new SecurityException(callerUid + " cannot kill app process: " +
4290 processName);
4291 }
4292 }
4293
Dianne Hackborn03abb812010-01-04 18:43:19 -08004294 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004295 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4297 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004298 if (!mProcessesReady) {
4299 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 intent.putExtra(Intent.EXTRA_UID, uid);
4302 broadcastIntentLocked(null, null, intent,
4303 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07004304 false, false,
4305 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 }
4307
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004308 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004309 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004310 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08004311 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312
Dianne Hackborn03abb812010-01-04 18:43:19 -08004313 // Remove all processes this package may have touched: all with the
4314 // same UID (except for the system or root user), and all whose name
4315 // matches the package name.
4316 final String procNamePrefix = packageName + ":";
4317 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4318 final int NA = apps.size();
4319 for (int ia=0; ia<NA; ia++) {
4320 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07004321 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07004322 // we don't kill persistent processes
4323 continue;
4324 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004325 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004326 if (doit) {
4327 procs.add(app);
4328 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004329 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
4330 || app.processName.equals(packageName)
4331 || app.processName.startsWith(procNamePrefix)) {
4332 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004333 if (!doit) {
4334 return true;
4335 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08004336 app.removed = true;
4337 procs.add(app);
4338 }
4339 }
4340 }
4341 }
4342
4343 int N = procs.size();
4344 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004345 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004346 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004347 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08004348 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004349
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004350 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07004351 boolean callerWillRestart, boolean purgeCache, boolean doit,
4352 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004353 int i;
4354 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 if (uid < 0) {
4357 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004358 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 } catch (RemoteException e) {
4360 }
4361 }
4362
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004363 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004364 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08004365
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004366 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
4367 while (badApps.hasNext()) {
4368 SparseArray<Long> ba = badApps.next();
4369 if (ba.get(uid) != null) {
4370 badApps.remove();
4371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004372 }
4373 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004374
4375 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004376 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004378 TaskRecord lastTask = null;
4379 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004380 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004381 final boolean samePackage = r.packageName.equals(name);
4382 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07004383 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004384 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07004385 if (r.finishing) {
4386 // If this activity is just finishing, then it is not
4387 // interesting as far as something to stop.
4388 continue;
4389 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004390 return true;
4391 }
4392 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004393 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004394 if (samePackage) {
4395 if (r.app != null) {
4396 r.app.removed = true;
4397 }
4398 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07004400 lastTask = r.task;
4401 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
4402 null, "force-stop")) {
4403 i--;
4404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 }
4406 }
4407
4408 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07004409 int userId = UserId.getUserId(uid);
4410 for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
Christopher Tate064d8422011-07-26 15:38:07 -07004411 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07004412 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004413 if (!doit) {
4414 return true;
4415 }
4416 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004417 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004418 if (service.app != null) {
4419 service.app.removed = true;
4420 }
4421 service.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004422 service.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 services.add(service);
4424 }
4425 }
4426
4427 N = services.size();
4428 for (i=0; i<N; i++) {
4429 bringDownServiceLocked(services.get(i), true);
4430 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07004431
4432 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4433 for (ContentProviderRecord provider : mProvidersByClass.values()) {
4434 if (provider.info.packageName.equals(name)
4435 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
4436 if (!doit) {
4437 return true;
4438 }
4439 didSomething = true;
4440 providers.add(provider);
4441 }
4442 }
4443
4444 N = providers.size();
4445 for (i=0; i<N; i++) {
4446 removeDyingProviderLocked(null, providers.get(i));
4447 }
4448
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004449 if (doit) {
4450 if (purgeCache) {
4451 AttributeCache ac = AttributeCache.instance();
4452 if (ac != null) {
4453 ac.removePackage(name);
4454 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004455 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004456 if (mBooted) {
4457 mMainStack.resumeTopActivityLocked(null);
4458 mMainStack.scheduleIdleLocked();
4459 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004460 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004461
4462 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 }
4464
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004465 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004466 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004468 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004469 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004470 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004471 + "/" + uid + ")");
4472
4473 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004474 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004475 if (mHeavyWeightProcess == app) {
4476 mHeavyWeightProcess = null;
4477 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 boolean needRestart = false;
4480 if (app.pid > 0 && app.pid != MY_PID) {
4481 int pid = app.pid;
4482 synchronized (mPidsSelfLocked) {
4483 mPidsSelfLocked.remove(pid);
4484 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4485 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004486 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004487 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004488 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004489 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004491 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004493 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 } else {
4495 needRestart = true;
4496 }
4497 }
4498 } else {
4499 mRemovedProcesses.add(app);
4500 }
4501
4502 return needRestart;
4503 }
4504
4505 private final void processStartTimedOutLocked(ProcessRecord app) {
4506 final int pid = app.pid;
4507 boolean gone = false;
4508 synchronized (mPidsSelfLocked) {
4509 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4510 if (knownApp != null && knownApp.thread == null) {
4511 mPidsSelfLocked.remove(pid);
4512 gone = true;
4513 }
4514 }
4515
4516 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004517 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004518 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004519 app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004520 mProcessNames.remove(app.processName, app.uid);
4521 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004522 if (mHeavyWeightProcess == app) {
4523 mHeavyWeightProcess = null;
4524 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
4525 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004526 // Take care of any launching providers waiting for this process.
4527 checkAppInLaunchingProvidersLocked(app, true);
4528 // Take care of any services that are waiting for the process.
4529 for (int i=0; i<mPendingServices.size(); i++) {
4530 ServiceRecord sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004531 if ((app.uid == sr.appInfo.uid
4532 && app.processName.equals(sr.processName))
4533 || sr.isolatedProc == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004534 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004535 sr.isolatedProc = null;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004536 mPendingServices.remove(i);
4537 i--;
4538 bringDownServiceLocked(sr, true);
4539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004541 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4542 app.processName, app.setAdj, "start timeout");
4543 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07004544 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004545 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07004546 try {
4547 IBackupManager bm = IBackupManager.Stub.asInterface(
4548 ServiceManager.getService(Context.BACKUP_SERVICE));
4549 bm.agentDisconnected(app.info.packageName);
4550 } catch (RemoteException e) {
4551 // Can't happen; the backup manager is local
4552 }
4553 }
Christopher Tatef46723b2012-01-26 14:19:24 -08004554 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004555 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08004556 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004558 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004559 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004560 }
4561 }
4562
4563 private final boolean attachApplicationLocked(IApplicationThread thread,
4564 int pid) {
4565
4566 // Find the application record that is being attached... either via
4567 // the pid if we are running in multiple processes, or just pull the
4568 // next app record if we are emulating process with anonymous threads.
4569 ProcessRecord app;
4570 if (pid != MY_PID && pid >= 0) {
4571 synchronized (mPidsSelfLocked) {
4572 app = mPidsSelfLocked.get(pid);
4573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 } else {
4575 app = null;
4576 }
4577
4578 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004579 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08004581 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004583 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 } else {
4585 try {
4586 thread.scheduleExit();
4587 } catch (Exception e) {
4588 // Ignore exceptions.
4589 }
4590 }
4591 return false;
4592 }
4593
4594 // If this application record is still attached to a previous
4595 // process, clean it up now.
4596 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004597 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 }
4599
4600 // Tell the process all about itself.
4601
Joe Onorato8a9b2202010-02-26 18:56:32 -08004602 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 TAG, "Binding process pid " + pid + " to record " + app);
4604
4605 String processName = app.processName;
4606 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004607 AppDeathRecipient adr = new AppDeathRecipient(
4608 app, pid, thread);
4609 thread.asBinder().linkToDeath(adr, 0);
4610 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 } catch (RemoteException e) {
4612 app.resetPackageList();
4613 startProcessLocked(app, "link fail", processName);
4614 return false;
4615 }
4616
Doug Zongker2bec3d42009-12-04 12:52:44 -08004617 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618
4619 app.thread = thread;
4620 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08004621 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4622 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 app.forcingToForeground = null;
4624 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07004625 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 app.debugging = false;
4627
4628 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4629
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004630 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004631 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004632
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004633 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004634 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004635 }
4636
Joe Onorato8a9b2202010-02-26 18:56:32 -08004637 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 TAG, "New app record " + app
4639 + " thread=" + thread.asBinder() + " pid=" + pid);
4640 try {
4641 int testMode = IApplicationThread.DEBUG_OFF;
4642 if (mDebugApp != null && mDebugApp.equals(processName)) {
4643 testMode = mWaitForDebugger
4644 ? IApplicationThread.DEBUG_WAIT
4645 : IApplicationThread.DEBUG_ON;
4646 app.debugging = true;
4647 if (mDebugTransient) {
4648 mDebugApp = mOrigDebugApp;
4649 mWaitForDebugger = mOrigWaitForDebugger;
4650 }
4651 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004652 String profileFile = app.instrumentationProfileFile;
4653 ParcelFileDescriptor profileFd = null;
4654 boolean profileAutoStop = false;
4655 if (mProfileApp != null && mProfileApp.equals(processName)) {
4656 mProfileProc = app;
4657 profileFile = mProfileFile;
4658 profileFd = mProfileFd;
4659 profileAutoStop = mAutoStopProfiler;
4660 }
4661
Christopher Tate181fafa2009-05-14 11:12:14 -07004662 // If the app is being launched for restore or full backup, set it up specially
4663 boolean isRestrictedBackupMode = false;
4664 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4665 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004666 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004667 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4668 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004669
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004670 ensurePackageDexOpt(app.instrumentationInfo != null
4671 ? app.instrumentationInfo.packageName
4672 : app.info.packageName);
4673 if (app.instrumentationClass != null) {
4674 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004675 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004676 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004677 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004678 ApplicationInfo appInfo = app.instrumentationInfo != null
4679 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004680 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004681 if (profileFd != null) {
4682 profileFd = profileFd.dup();
4683 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004684 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004685 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004687 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004688 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004689 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004690 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004691 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004692 } catch (Exception e) {
4693 // todo: Yikes! What should we do? For now we will try to
4694 // start another process, but that could easily get us in
4695 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004696 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697
4698 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004699 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004700 startProcessLocked(app, "bind fail", processName);
4701 return false;
4702 }
4703
4704 // Remove this record from the list of starting applications.
4705 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004706 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4707 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 mProcessesOnHold.remove(app);
4709
4710 boolean badApp = false;
4711 boolean didSomething = false;
4712
4713 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004714 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004715 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004716 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004717 && processName.equals(hr.processName)) {
4718 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004719 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004720 didSomething = true;
4721 }
4722 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004723 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004724 + hr.intent.getComponent().flattenToShortString(), e);
4725 badApp = true;
4726 }
4727 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004728 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 }
4730 }
4731
4732 // Find any services that should be running in this process...
4733 if (!badApp && mPendingServices.size() > 0) {
4734 ServiceRecord sr = null;
4735 try {
4736 for (int i=0; i<mPendingServices.size(); i++) {
4737 sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004738 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4739 || !processName.equals(sr.processName))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 continue;
4741 }
4742
4743 mPendingServices.remove(i);
4744 i--;
4745 realStartServiceLocked(sr, app);
4746 didSomething = true;
4747 }
4748 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004749 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750 + sr.shortName, e);
4751 badApp = true;
4752 }
4753 }
4754
Christopher Tatef46723b2012-01-26 14:19:24 -08004755 // Check if a next-broadcast receiver is in this process...
4756 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004757 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004758 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004760 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004761 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 }
4763 }
4764
Christopher Tate181fafa2009-05-14 11:12:14 -07004765 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004766 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004767 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004768 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004769 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004770 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4771 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4772 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004773 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004774 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004775 e.printStackTrace();
4776 }
4777 }
4778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004779 if (badApp) {
4780 // todo: Also need to kill application to deal with all
4781 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004782 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 return false;
4784 }
4785
4786 if (!didSomething) {
4787 updateOomAdjLocked();
4788 }
4789
4790 return true;
4791 }
4792
4793 public final void attachApplication(IApplicationThread thread) {
4794 synchronized (this) {
4795 int callingPid = Binder.getCallingPid();
4796 final long origId = Binder.clearCallingIdentity();
4797 attachApplicationLocked(thread, callingPid);
4798 Binder.restoreCallingIdentity(origId);
4799 }
4800 }
4801
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004802 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004804 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4805 if (stopProfiling) {
4806 synchronized (this) {
4807 if (mProfileProc == r.app) {
4808 if (mProfileFd != null) {
4809 try {
4810 mProfileFd.close();
4811 } catch (IOException e) {
4812 }
4813 clearProfilerLocked();
4814 }
4815 }
4816 }
4817 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004818 Binder.restoreCallingIdentity(origId);
4819 }
4820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004822 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004823 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 mWindowManager.enableScreenAfterBoot();
4825 }
4826
Dianne Hackborn661cd522011-08-22 00:26:20 -07004827 public void showBootMessage(final CharSequence msg, final boolean always) {
4828 mWindowManager.showBootMessage(msg, always);
4829 }
4830
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004831 public void dismissKeyguardOnNextActivity() {
4832 synchronized (this) {
4833 mMainStack.dismissKeyguardOnNextActivityLocked();
4834 }
4835 }
4836
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004837 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004838 IntentFilter pkgFilter = new IntentFilter();
4839 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4840 pkgFilter.addDataScheme("package");
4841 mContext.registerReceiver(new BroadcastReceiver() {
4842 @Override
4843 public void onReceive(Context context, Intent intent) {
4844 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4845 if (pkgs != null) {
4846 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004847 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004848 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004849 setResultCode(Activity.RESULT_OK);
4850 return;
4851 }
4852 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004853 }
4854 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004855 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004856 }, pkgFilter);
4857
4858 synchronized (this) {
4859 // Ensure that any processes we had put on hold are now started
4860 // up.
4861 final int NP = mProcessesOnHold.size();
4862 if (NP > 0) {
4863 ArrayList<ProcessRecord> procs =
4864 new ArrayList<ProcessRecord>(mProcessesOnHold);
4865 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004866 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4867 + procs.get(ip));
4868 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004869 }
4870 }
4871
4872 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004873 // Start looking for apps that are abusing wake locks.
4874 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004875 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004876 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004877 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004878 SystemProperties.set("dev.bootcomplete", "1");
Amith Yamasani742a6712011-05-04 14:49:28 -07004879 /* TODO: Send this to all users that are to be logged in on startup */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004880 broadcastIntentLocked(null, null,
4881 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4882 null, null, 0, null, null,
4883 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Amith Yamasani742a6712011-05-04 14:49:28 -07004884 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004885 }
4886 }
4887 }
4888
4889 final void ensureBootCompleted() {
4890 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004891 boolean enableScreen;
4892 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004893 booting = mBooting;
4894 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004895 enableScreen = !mBooted;
4896 mBooted = true;
4897 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004898
4899 if (booting) {
4900 finishBooting();
4901 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004902
4903 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004904 enableScreenAfterBoot();
4905 }
4906 }
4907
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004908 public final void activityPaused(IBinder token) {
4909 final long origId = Binder.clearCallingIdentity();
4910 mMainStack.activityPaused(token, false);
4911 Binder.restoreCallingIdentity(origId);
4912 }
4913
4914 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4915 CharSequence description) {
4916 if (localLOGV) Slog.v(
4917 TAG, "Activity stopped: token=" + token);
4918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 // Refuse possible leaked file descriptors
4920 if (icicle != null && icicle.hasFileDescriptors()) {
4921 throw new IllegalArgumentException("File descriptors passed in Bundle");
4922 }
4923
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004924 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925
4926 final long origId = Binder.clearCallingIdentity();
4927
4928 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004929 r = mMainStack.isInStackLocked(token);
4930 if (r != null) {
4931 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 }
4933 }
4934
4935 if (r != null) {
4936 sendPendingThumbnail(r, null, null, null, false);
4937 }
4938
4939 trimApplications();
4940
4941 Binder.restoreCallingIdentity(origId);
4942 }
4943
4944 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004945 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004946 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004947 }
4948
4949 public String getCallingPackage(IBinder token) {
4950 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004951 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004952 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 }
4954 }
4955
4956 public ComponentName getCallingActivity(IBinder token) {
4957 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004958 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 return r != null ? r.intent.getComponent() : null;
4960 }
4961 }
4962
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004963 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004964 ActivityRecord r = mMainStack.isInStackLocked(token);
4965 if (r == null) {
4966 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004967 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004968 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 }
4970
4971 public ComponentName getActivityClassForToken(IBinder token) {
4972 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004973 ActivityRecord r = mMainStack.isInStackLocked(token);
4974 if (r == null) {
4975 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004977 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978 }
4979 }
4980
4981 public String getPackageForToken(IBinder token) {
4982 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004983 ActivityRecord r = mMainStack.isInStackLocked(token);
4984 if (r == null) {
4985 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004987 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004988 }
4989 }
4990
4991 public IIntentSender getIntentSender(int type,
4992 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004993 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004995 if (intents != null) {
4996 if (intents.length < 1) {
4997 throw new IllegalArgumentException("Intents array length must be >= 1");
4998 }
4999 for (int i=0; i<intents.length; i++) {
5000 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07005001 if (intent != null) {
5002 if (intent.hasFileDescriptors()) {
5003 throw new IllegalArgumentException("File descriptors passed in Intent");
5004 }
5005 if (type == INTENT_SENDER_BROADCAST &&
5006 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5007 throw new IllegalArgumentException(
5008 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5009 }
5010 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005011 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005012 }
5013 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005014 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005015 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005016 }
5017 }
5018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005019 synchronized(this) {
5020 int callingUid = Binder.getCallingUid();
5021 try {
Jeff Brown10e89712011-07-08 18:52:57 -07005022 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005023 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 .getPackageUid(packageName);
Amith Yamasani742a6712011-05-04 14:49:28 -07005025 if (UserId.getAppId(callingUid) != uid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 String msg = "Permission Denial: getIntentSender() from pid="
5027 + Binder.getCallingPid()
5028 + ", uid=" + Binder.getCallingUid()
5029 + ", (need uid=" + uid + ")"
5030 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005031 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005032 throw new SecurityException(msg);
5033 }
5034 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005035
Amith Yamasani742a6712011-05-04 14:49:28 -07005036 if (DEBUG_MU)
5037 Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
5038 + Binder.getOrigCallingUid());
5039 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005040 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005042 } catch (RemoteException e) {
5043 throw new SecurityException(e);
5044 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005045 }
5046 }
5047
5048 IIntentSender getIntentSenderLocked(int type,
5049 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005050 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07005051 if (DEBUG_MU)
5052 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005053 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07005054 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005055 activity = mMainStack.isInStackLocked(token);
5056 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005057 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005059 if (activity.finishing) {
5060 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005061 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005062 }
5063
5064 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5065 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5066 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5067 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5068 |PendingIntent.FLAG_UPDATE_CURRENT);
5069
5070 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5071 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005072 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005073 WeakReference<PendingIntentRecord> ref;
5074 ref = mIntentSenderRecords.get(key);
5075 PendingIntentRecord rec = ref != null ? ref.get() : null;
5076 if (rec != null) {
5077 if (!cancelCurrent) {
5078 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005079 if (rec.key.requestIntent != null) {
5080 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
5081 }
5082 if (intents != null) {
5083 intents[intents.length-1] = rec.key.requestIntent;
5084 rec.key.allIntents = intents;
5085 rec.key.allResolvedTypes = resolvedTypes;
5086 } else {
5087 rec.key.allIntents = null;
5088 rec.key.allResolvedTypes = null;
5089 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 return rec;
5092 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005093 rec.canceled = true;
5094 mIntentSenderRecords.remove(key);
5095 }
5096 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005097 return rec;
5098 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005099 rec = new PendingIntentRecord(this, key, callingUid);
5100 mIntentSenderRecords.put(key, rec.ref);
5101 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5102 if (activity.pendingResults == null) {
5103 activity.pendingResults
5104 = new HashSet<WeakReference<PendingIntentRecord>>();
5105 }
5106 activity.pendingResults.add(rec.ref);
5107 }
5108 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005109 }
5110
5111 public void cancelIntentSender(IIntentSender sender) {
5112 if (!(sender instanceof PendingIntentRecord)) {
5113 return;
5114 }
5115 synchronized(this) {
5116 PendingIntentRecord rec = (PendingIntentRecord)sender;
5117 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005118 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005119 .getPackageUid(rec.key.packageName);
5120 if (uid != Binder.getCallingUid()) {
5121 String msg = "Permission Denial: cancelIntentSender() from pid="
5122 + Binder.getCallingPid()
5123 + ", uid=" + Binder.getCallingUid()
5124 + " is not allowed to cancel packges "
5125 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005126 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005127 throw new SecurityException(msg);
5128 }
5129 } catch (RemoteException e) {
5130 throw new SecurityException(e);
5131 }
5132 cancelIntentSenderLocked(rec, true);
5133 }
5134 }
5135
5136 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5137 rec.canceled = true;
5138 mIntentSenderRecords.remove(rec.key);
5139 if (cleanActivity && rec.key.activity != null) {
5140 rec.key.activity.pendingResults.remove(rec.ref);
5141 }
5142 }
5143
5144 public String getPackageForIntentSender(IIntentSender pendingResult) {
5145 if (!(pendingResult instanceof PendingIntentRecord)) {
5146 return null;
5147 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07005148 try {
5149 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5150 return res.key.packageName;
5151 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005152 }
5153 return null;
5154 }
5155
Dianne Hackborn6c418d52011-06-29 14:05:33 -07005156 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5157 if (!(pendingResult instanceof PendingIntentRecord)) {
5158 return false;
5159 }
5160 try {
5161 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5162 if (res.key.allIntents == null) {
5163 return false;
5164 }
5165 for (int i=0; i<res.key.allIntents.length; i++) {
5166 Intent intent = res.key.allIntents[i];
5167 if (intent.getPackage() != null && intent.getComponent() != null) {
5168 return false;
5169 }
5170 }
5171 return true;
5172 } catch (ClassCastException e) {
5173 }
5174 return false;
5175 }
5176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005177 public void setProcessLimit(int max) {
5178 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5179 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005180 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005181 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005182 mProcessLimitOverride = max;
5183 }
5184 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 }
5186
5187 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005188 synchronized (this) {
5189 return mProcessLimitOverride;
5190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005191 }
5192
5193 void foregroundTokenDied(ForegroundToken token) {
5194 synchronized (ActivityManagerService.this) {
5195 synchronized (mPidsSelfLocked) {
5196 ForegroundToken cur
5197 = mForegroundProcesses.get(token.pid);
5198 if (cur != token) {
5199 return;
5200 }
5201 mForegroundProcesses.remove(token.pid);
5202 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5203 if (pr == null) {
5204 return;
5205 }
5206 pr.forcingToForeground = null;
5207 pr.foregroundServices = false;
5208 }
5209 updateOomAdjLocked();
5210 }
5211 }
5212
5213 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5214 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5215 "setProcessForeground()");
5216 synchronized(this) {
5217 boolean changed = false;
5218
5219 synchronized (mPidsSelfLocked) {
5220 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005221 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005222 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005223 return;
5224 }
5225 ForegroundToken oldToken = mForegroundProcesses.get(pid);
5226 if (oldToken != null) {
5227 oldToken.token.unlinkToDeath(oldToken, 0);
5228 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005229 if (pr != null) {
5230 pr.forcingToForeground = null;
5231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 changed = true;
5233 }
5234 if (isForeground && token != null) {
5235 ForegroundToken newToken = new ForegroundToken() {
5236 public void binderDied() {
5237 foregroundTokenDied(this);
5238 }
5239 };
5240 newToken.pid = pid;
5241 newToken.token = token;
5242 try {
5243 token.linkToDeath(newToken, 0);
5244 mForegroundProcesses.put(pid, newToken);
5245 pr.forcingToForeground = token;
5246 changed = true;
5247 } catch (RemoteException e) {
5248 // If the process died while doing this, we will later
5249 // do the cleanup with the process death link.
5250 }
5251 }
5252 }
5253
5254 if (changed) {
5255 updateOomAdjLocked();
5256 }
5257 }
5258 }
5259
5260 // =========================================================
5261 // PERMISSIONS
5262 // =========================================================
5263
5264 static class PermissionController extends IPermissionController.Stub {
5265 ActivityManagerService mActivityManagerService;
5266 PermissionController(ActivityManagerService activityManagerService) {
5267 mActivityManagerService = activityManagerService;
5268 }
5269
5270 public boolean checkPermission(String permission, int pid, int uid) {
5271 return mActivityManagerService.checkPermission(permission, pid,
5272 uid) == PackageManager.PERMISSION_GRANTED;
5273 }
5274 }
5275
5276 /**
5277 * This can be called with or without the global lock held.
5278 */
5279 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005280 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005281 // We might be performing an operation on behalf of an indirect binder
5282 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
5283 // client identity accordingly before proceeding.
5284 Identity tlsIdentity = sCallerIdentity.get();
5285 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005286 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5288 uid = tlsIdentity.uid;
5289 pid = tlsIdentity.pid;
5290 }
5291
5292 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005293 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 return PackageManager.PERMISSION_GRANTED;
5295 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005296 // If there is a uid that owns whatever is being accessed, it has
5297 // blanket access to it regardless of the permissions it requires.
Amith Yamasani742a6712011-05-04 14:49:28 -07005298 if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005299 return PackageManager.PERMISSION_GRANTED;
5300 }
5301 // If the target is not exported, then nobody else can get to it.
5302 if (!exported) {
5303 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 return PackageManager.PERMISSION_DENIED;
5305 }
5306 if (permission == null) {
5307 return PackageManager.PERMISSION_GRANTED;
5308 }
5309 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005310 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 .checkUidPermission(permission, uid);
5312 } catch (RemoteException e) {
5313 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08005314 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 }
5316 return PackageManager.PERMISSION_DENIED;
5317 }
5318
5319 /**
5320 * As the only public entry point for permissions checking, this method
5321 * can enforce the semantic that requesting a check on a null global
5322 * permission is automatically denied. (Internally a null permission
5323 * string is used when calling {@link #checkComponentPermission} in cases
5324 * when only uid-based security is needed.)
5325 *
5326 * This can be called with or without the global lock held.
5327 */
5328 public int checkPermission(String permission, int pid, int uid) {
5329 if (permission == null) {
5330 return PackageManager.PERMISSION_DENIED;
5331 }
Amith Yamasani742a6712011-05-04 14:49:28 -07005332 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 }
5334
5335 /**
5336 * Binder IPC calls go through the public entry point.
5337 * This can be called with or without the global lock held.
5338 */
5339 int checkCallingPermission(String permission) {
5340 return checkPermission(permission,
5341 Binder.getCallingPid(),
Amith Yamasani742a6712011-05-04 14:49:28 -07005342 UserId.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005343 }
5344
5345 /**
5346 * This can be called with or without the global lock held.
5347 */
5348 void enforceCallingPermission(String permission, String func) {
5349 if (checkCallingPermission(permission)
5350 == PackageManager.PERMISSION_GRANTED) {
5351 return;
5352 }
5353
5354 String msg = "Permission Denial: " + func + " from pid="
5355 + Binder.getCallingPid()
5356 + ", uid=" + Binder.getCallingUid()
5357 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005358 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005359 throw new SecurityException(msg);
5360 }
5361
5362 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07005363 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5364 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5365 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5366 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5367 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005368 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07005369 // Is the component private from the target uid?
5370 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
5371
5372 // Acceptable if the there is no read permission needed from the
5373 // target or the target is holding the read permission.
5374 if (!readPerm) {
5375 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005377 == PackageManager.PERMISSION_GRANTED)) {
5378 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005379 }
5380 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005381
5382 // Acceptable if the there is no write permission needed from the
5383 // target or the target is holding the read permission.
5384 if (!writePerm) {
5385 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005386 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07005387 == PackageManager.PERMISSION_GRANTED)) {
5388 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005389 }
5390 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005391
5392 // Acceptable if there is a path permission matching the URI that
5393 // the target holds the permission on.
5394 PathPermission[] pps = pi.pathPermissions;
5395 if (pps != null && (!readPerm || !writePerm)) {
5396 final String path = uri.getPath();
5397 int i = pps.length;
5398 while (i > 0 && (!readPerm || !writePerm)) {
5399 i--;
5400 PathPermission pp = pps[i];
5401 if (!readPerm) {
5402 final String pprperm = pp.getReadPermission();
5403 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5404 + pprperm + " for " + pp.getPath()
5405 + ": match=" + pp.match(path)
5406 + " check=" + pm.checkUidPermission(pprperm, uid));
5407 if (pprperm != null && pp.match(path) &&
5408 (pm.checkUidPermission(pprperm, uid)
5409 == PackageManager.PERMISSION_GRANTED)) {
5410 readPerm = true;
5411 }
5412 }
5413 if (!writePerm) {
5414 final String ppwperm = pp.getWritePermission();
5415 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5416 + ppwperm + " for " + pp.getPath()
5417 + ": match=" + pp.match(path)
5418 + " check=" + pm.checkUidPermission(ppwperm, uid));
5419 if (ppwperm != null && pp.match(path) &&
5420 (pm.checkUidPermission(ppwperm, uid)
5421 == PackageManager.PERMISSION_GRANTED)) {
5422 writePerm = true;
5423 }
5424 }
5425 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 } catch (RemoteException e) {
5428 return false;
5429 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005430
5431 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 }
5433
5434 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5435 int modeFlags) {
5436 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005437 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005438 return true;
5439 }
5440 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5441 if (perms == null) return false;
5442 UriPermission perm = perms.get(uri);
5443 if (perm == null) return false;
5444 return (modeFlags&perm.modeFlags) == modeFlags;
5445 }
5446
5447 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5448 // Another redirected-binder-call permissions check as in
5449 // {@link checkComponentPermission}.
5450 Identity tlsIdentity = sCallerIdentity.get();
5451 if (tlsIdentity != null) {
5452 uid = tlsIdentity.uid;
5453 pid = tlsIdentity.pid;
5454 }
5455
Amith Yamasani742a6712011-05-04 14:49:28 -07005456 uid = UserId.getAppId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005457 // Our own process gets to do everything.
5458 if (pid == MY_PID) {
5459 return PackageManager.PERMISSION_GRANTED;
5460 }
5461 synchronized(this) {
5462 return checkUriPermissionLocked(uri, uid, modeFlags)
5463 ? PackageManager.PERMISSION_GRANTED
5464 : PackageManager.PERMISSION_DENIED;
5465 }
5466 }
5467
Dianne Hackborn39792d22010-08-19 18:01:52 -07005468 /**
5469 * Check if the targetPkg can be granted permission to access uri by
5470 * the callingUid using the given modeFlags. Throws a security exception
5471 * if callingUid is not allowed to do this. Returns the uid of the target
5472 * if the URI permission grant should be performed; returns -1 if it is not
5473 * needed (for example targetPkg already has permission to access the URI).
5474 */
5475 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5476 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5478 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5479 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005480 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005481 }
5482
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005483 if (targetPkg != null) {
5484 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5485 "Checking grant " + targetPkg + " permission to " + uri);
5486 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005487
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005488 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489
5490 // If this is not a content: uri, we can't do anything with it.
5491 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005492 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005493 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005494 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 }
5496
5497 String name = uri.getAuthority();
5498 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005499 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5500 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005501 if (cpr != null) {
5502 pi = cpr.info;
5503 } else {
5504 try {
5505 pi = pm.resolveContentProvider(name,
5506 PackageManager.GET_URI_PERMISSION_PATTERNS);
5507 } catch (RemoteException ex) {
5508 }
5509 }
5510 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005511 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07005512 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005513 }
5514
5515 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005516 if (targetPkg != null) {
5517 try {
5518 targetUid = pm.getPackageUid(targetPkg);
5519 if (targetUid < 0) {
5520 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5521 "Can't grant URI permission no uid for: " + targetPkg);
5522 return -1;
5523 }
5524 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005525 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005526 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005527 } else {
5528 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 }
5530
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005531 if (targetUid >= 0) {
5532 // First... does the target actually need this permission?
5533 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5534 // No need to grant the target this permission.
5535 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5536 "Target " + targetPkg + " already has full permission to " + uri);
5537 return -1;
5538 }
5539 } else {
5540 // First... there is no target package, so can anyone access it?
5541 boolean allowed = pi.exported;
5542 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5543 if (pi.readPermission != null) {
5544 allowed = false;
5545 }
5546 }
5547 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5548 if (pi.writePermission != null) {
5549 allowed = false;
5550 }
5551 }
5552 if (allowed) {
5553 return -1;
5554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 }
5556
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005557 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558 if (!pi.grantUriPermissions) {
5559 throw new SecurityException("Provider " + pi.packageName
5560 + "/" + pi.name
5561 + " does not allow granting of Uri permissions (uri "
5562 + uri + ")");
5563 }
5564 if (pi.uriPermissionPatterns != null) {
5565 final int N = pi.uriPermissionPatterns.length;
5566 boolean allowed = false;
5567 for (int i=0; i<N; i++) {
5568 if (pi.uriPermissionPatterns[i] != null
5569 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5570 allowed = true;
5571 break;
5572 }
5573 }
5574 if (!allowed) {
5575 throw new SecurityException("Provider " + pi.packageName
5576 + "/" + pi.name
5577 + " does not allow granting of permission to path of Uri "
5578 + uri);
5579 }
5580 }
5581
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005582 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005583 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005584 if (callingUid != Process.myUid()) {
5585 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5586 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5587 throw new SecurityException("Uid " + callingUid
5588 + " does not have permission to uri " + uri);
5589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 }
5591 }
5592
Dianne Hackborn39792d22010-08-19 18:01:52 -07005593 return targetUid;
5594 }
5595
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005596 public int checkGrantUriPermission(int callingUid, String targetPkg,
5597 Uri uri, int modeFlags) {
5598 synchronized(this) {
5599 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5600 }
5601 }
5602
Dianne Hackborn39792d22010-08-19 18:01:52 -07005603 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5604 Uri uri, int modeFlags, UriPermissionOwner owner) {
5605 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5606 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5607 if (modeFlags == 0) {
5608 return;
5609 }
5610
5611 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 // to the uri, and the target doesn't. Let's now give this to
5613 // the target.
5614
Joe Onorato8a9b2202010-02-26 18:56:32 -08005615 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005616 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618 HashMap<Uri, UriPermission> targetUris
5619 = mGrantedUriPermissions.get(targetUid);
5620 if (targetUris == null) {
5621 targetUris = new HashMap<Uri, UriPermission>();
5622 mGrantedUriPermissions.put(targetUid, targetUris);
5623 }
5624
5625 UriPermission perm = targetUris.get(uri);
5626 if (perm == null) {
5627 perm = new UriPermission(targetUid, uri);
5628 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005629 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005632 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005633 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005634 } else {
5635 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5636 perm.readOwners.add(owner);
5637 owner.addReadPermission(perm);
5638 }
5639 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5640 perm.writeOwners.add(owner);
5641 owner.addWritePermission(perm);
5642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 }
5644 }
5645
Dianne Hackborn39792d22010-08-19 18:01:52 -07005646 void grantUriPermissionLocked(int callingUid,
5647 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005648 if (targetPkg == null) {
5649 throw new NullPointerException("targetPkg");
5650 }
5651
Dianne Hackborn39792d22010-08-19 18:01:52 -07005652 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
5653 if (targetUid < 0) {
5654 return;
5655 }
5656
5657 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5658 }
5659
5660 /**
5661 * Like checkGrantUriPermissionLocked, but takes an Intent.
5662 */
5663 int checkGrantUriPermissionFromIntentLocked(int callingUid,
5664 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005665 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005666 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005667 + " from " + intent + "; flags=0x"
5668 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5669
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005670 if (targetPkg == null) {
5671 throw new NullPointerException("targetPkg");
5672 }
5673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005675 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 }
5677 Uri data = intent.getData();
5678 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005679 return -1;
5680 }
5681 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5682 intent.getFlags());
5683 }
5684
5685 /**
5686 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5687 */
5688 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
5689 String targetPkg, Intent intent, UriPermissionOwner owner) {
5690 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
5691 intent.getFlags(), owner);
5692 }
5693
5694 void grantUriPermissionFromIntentLocked(int callingUid,
5695 String targetPkg, Intent intent, UriPermissionOwner owner) {
5696 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
5697 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005698 return;
5699 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005700
5701 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 }
5703
5704 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5705 Uri uri, int modeFlags) {
5706 synchronized(this) {
5707 final ProcessRecord r = getRecordForAppLocked(caller);
5708 if (r == null) {
5709 throw new SecurityException("Unable to find app for caller "
5710 + caller
5711 + " when granting permission to uri " + uri);
5712 }
5713 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005714 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005715 }
5716 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005717 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 }
5719
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005720 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 null);
5722 }
5723 }
5724
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005725 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5727 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5728 HashMap<Uri, UriPermission> perms
5729 = mGrantedUriPermissions.get(perm.uid);
5730 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005731 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005732 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005733 perms.remove(perm.uri);
5734 if (perms.size() == 0) {
5735 mGrantedUriPermissions.remove(perm.uid);
5736 }
5737 }
5738 }
5739 }
5740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5742 int modeFlags) {
5743 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5744 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5745 if (modeFlags == 0) {
5746 return;
5747 }
5748
Joe Onorato8a9b2202010-02-26 18:56:32 -08005749 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005750 "Revoking all granted permissions to " + uri);
5751
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005752 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753
5754 final String authority = uri.getAuthority();
5755 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005756 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority,
5757 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758 if (cpr != null) {
5759 pi = cpr.info;
5760 } else {
5761 try {
5762 pi = pm.resolveContentProvider(authority,
5763 PackageManager.GET_URI_PERMISSION_PATTERNS);
5764 } catch (RemoteException ex) {
5765 }
5766 }
5767 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005768 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005769 return;
5770 }
5771
5772 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005773 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 // Right now, if you are not the original owner of the permission,
5775 // you are not allowed to revoke it.
5776 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5777 throw new SecurityException("Uid " + callingUid
5778 + " does not have permission to uri " + uri);
5779 //}
5780 }
5781
5782 // Go through all of the permissions and remove any that match.
5783 final List<String> SEGMENTS = uri.getPathSegments();
5784 if (SEGMENTS != null) {
5785 final int NS = SEGMENTS.size();
5786 int N = mGrantedUriPermissions.size();
5787 for (int i=0; i<N; i++) {
5788 HashMap<Uri, UriPermission> perms
5789 = mGrantedUriPermissions.valueAt(i);
5790 Iterator<UriPermission> it = perms.values().iterator();
5791 toploop:
5792 while (it.hasNext()) {
5793 UriPermission perm = it.next();
5794 Uri targetUri = perm.uri;
5795 if (!authority.equals(targetUri.getAuthority())) {
5796 continue;
5797 }
5798 List<String> targetSegments = targetUri.getPathSegments();
5799 if (targetSegments == null) {
5800 continue;
5801 }
5802 if (targetSegments.size() < NS) {
5803 continue;
5804 }
5805 for (int j=0; j<NS; j++) {
5806 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5807 continue toploop;
5808 }
5809 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005810 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005811 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 perm.clearModes(modeFlags);
5813 if (perm.modeFlags == 0) {
5814 it.remove();
5815 }
5816 }
5817 if (perms.size() == 0) {
5818 mGrantedUriPermissions.remove(
5819 mGrantedUriPermissions.keyAt(i));
5820 N--;
5821 i--;
5822 }
5823 }
5824 }
5825 }
5826
5827 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5828 int modeFlags) {
5829 synchronized(this) {
5830 final ProcessRecord r = getRecordForAppLocked(caller);
5831 if (r == null) {
5832 throw new SecurityException("Unable to find app for caller "
5833 + caller
5834 + " when revoking permission to uri " + uri);
5835 }
5836 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005837 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005838 return;
5839 }
5840
5841 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5842 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5843 if (modeFlags == 0) {
5844 return;
5845 }
5846
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005847 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848
5849 final String authority = uri.getAuthority();
5850 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005851 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 if (cpr != null) {
5853 pi = cpr.info;
5854 } else {
5855 try {
5856 pi = pm.resolveContentProvider(authority,
5857 PackageManager.GET_URI_PERMISSION_PATTERNS);
5858 } catch (RemoteException ex) {
5859 }
5860 }
5861 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005862 Slog.w(TAG, "No content provider found for permission revoke: "
5863 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005864 return;
5865 }
5866
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005867 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005868 }
5869 }
5870
Dianne Hackborn7e269642010-08-25 19:50:20 -07005871 @Override
5872 public IBinder newUriPermissionOwner(String name) {
5873 synchronized(this) {
5874 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5875 return owner.getExternalTokenLocked();
5876 }
5877 }
5878
5879 @Override
5880 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5881 Uri uri, int modeFlags) {
5882 synchronized(this) {
5883 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5884 if (owner == null) {
5885 throw new IllegalArgumentException("Unknown owner: " + token);
5886 }
5887 if (fromUid != Binder.getCallingUid()) {
5888 if (Binder.getCallingUid() != Process.myUid()) {
5889 // Only system code can grant URI permissions on behalf
5890 // of other users.
5891 throw new SecurityException("nice try");
5892 }
5893 }
5894 if (targetPkg == null) {
5895 throw new IllegalArgumentException("null target");
5896 }
5897 if (uri == null) {
5898 throw new IllegalArgumentException("null uri");
5899 }
5900
5901 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5902 }
5903 }
5904
5905 @Override
5906 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5907 synchronized(this) {
5908 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5909 if (owner == null) {
5910 throw new IllegalArgumentException("Unknown owner: " + token);
5911 }
5912
5913 if (uri == null) {
5914 owner.removeUriPermissionsLocked(mode);
5915 } else {
5916 owner.removeUriPermissionLocked(uri, mode);
5917 }
5918 }
5919 }
5920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5922 synchronized (this) {
5923 ProcessRecord app =
5924 who != null ? getRecordForAppLocked(who) : null;
5925 if (app == null) return;
5926
5927 Message msg = Message.obtain();
5928 msg.what = WAIT_FOR_DEBUGGER_MSG;
5929 msg.obj = app;
5930 msg.arg1 = waiting ? 1 : 0;
5931 mHandler.sendMessage(msg);
5932 }
5933 }
5934
5935 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005936 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5937 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005939 outInfo.threshold = homeAppMem;
5940 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5941 outInfo.hiddenAppThreshold = hiddenAppMem;
5942 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005943 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005944 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5945 ProcessList.VISIBLE_APP_ADJ);
5946 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5947 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005948 }
5949
5950 // =========================================================
5951 // TASK MANAGEMENT
5952 // =========================================================
5953
5954 public List getTasks(int maxNum, int flags,
5955 IThumbnailReceiver receiver) {
5956 ArrayList list = new ArrayList();
5957
5958 PendingThumbnailsRecord pending = null;
5959 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005960 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005961
5962 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005963 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5965 + ", receiver=" + receiver);
5966
5967 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5968 != PackageManager.PERMISSION_GRANTED) {
5969 if (receiver != null) {
5970 // If the caller wants to wait for pending thumbnails,
5971 // it ain't gonna get them.
5972 try {
5973 receiver.finished();
5974 } catch (RemoteException ex) {
5975 }
5976 }
5977 String msg = "Permission Denial: getTasks() from pid="
5978 + Binder.getCallingPid()
5979 + ", uid=" + Binder.getCallingUid()
5980 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005981 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 throw new SecurityException(msg);
5983 }
5984
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005985 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005986 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005987 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005988 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005989 TaskRecord curTask = null;
5990 int numActivities = 0;
5991 int numRunning = 0;
5992 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005993 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005995 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996
5997 // Initialize state for next task if needed.
5998 if (top == null ||
5999 (top.state == ActivityState.INITIALIZING
6000 && top.task == r.task)) {
6001 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006002 curTask = r.task;
6003 numActivities = numRunning = 0;
6004 }
6005
6006 // Add 'r' into the current task.
6007 numActivities++;
6008 if (r.app != null && r.app.thread != null) {
6009 numRunning++;
6010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006011
Joe Onorato8a9b2202010-02-26 18:56:32 -08006012 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006013 TAG, r.intent.getComponent().flattenToShortString()
6014 + ": task=" + r.task);
6015
6016 // If the next one is a different task, generate a new
6017 // TaskInfo entry for what we have.
6018 if (next == null || next.task != curTask) {
6019 ActivityManager.RunningTaskInfo ci
6020 = new ActivityManager.RunningTaskInfo();
6021 ci.id = curTask.taskId;
6022 ci.baseActivity = r.intent.getComponent();
6023 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006024 if (top.thumbHolder != null) {
6025 ci.description = top.thumbHolder.lastDescription;
6026 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006027 ci.numActivities = numActivities;
6028 ci.numRunning = numRunning;
6029 //System.out.println(
6030 // "#" + maxNum + ": " + " descr=" + ci.description);
6031 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006032 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033 TAG, "State=" + top.state + "Idle=" + top.idle
6034 + " app=" + top.app
6035 + " thr=" + (top.app != null ? top.app.thread : null));
6036 if (top.state == ActivityState.RESUMED
6037 || top.state == ActivityState.PAUSING) {
6038 if (top.idle && top.app != null
6039 && top.app.thread != null) {
6040 topRecord = top;
6041 topThumbnail = top.app.thread;
6042 } else {
6043 top.thumbnailNeeded = true;
6044 }
6045 }
6046 if (pending == null) {
6047 pending = new PendingThumbnailsRecord(receiver);
6048 }
6049 pending.pendingRecords.add(top);
6050 }
6051 list.add(ci);
6052 maxNum--;
6053 top = null;
6054 }
6055 }
6056
6057 if (pending != null) {
6058 mPendingThumbnails.add(pending);
6059 }
6060 }
6061
Joe Onorato8a9b2202010-02-26 18:56:32 -08006062 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006063
6064 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006065 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08006067 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006069 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006070 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006071 }
6072 }
6073
6074 if (pending == null && receiver != null) {
6075 // In this case all thumbnails were available and the client
6076 // is being asked to be told when the remaining ones come in...
6077 // which is unusually, since the top-most currently running
6078 // activity should never have a canned thumbnail! Oh well.
6079 try {
6080 receiver.finished();
6081 } catch (RemoteException ex) {
6082 }
6083 }
6084
6085 return list;
6086 }
6087
6088 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6089 int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006090 final int callingUid = Binder.getCallingUid();
6091 // If it's the system uid asking, then use the current user id.
6092 // TODO: Make sure that there aren't any other legitimate calls from the system uid that
6093 // require the entire list.
6094 final int callingUserId = callingUid == Process.SYSTEM_UID
6095 ? mCurrentUserId : UserId.getUserId(callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006096 synchronized (this) {
6097 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6098 "getRecentTasks()");
6099
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006100 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 final int N = mRecentTasks.size();
6103 ArrayList<ActivityManager.RecentTaskInfo> res
6104 = new ArrayList<ActivityManager.RecentTaskInfo>(
6105 maxNum < N ? maxNum : N);
6106 for (int i=0; i<N && maxNum > 0; i++) {
6107 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006108 // Only add calling user's recent tasks
6109 if (tr.userId != callingUserId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07006110 // Return the entry if desired by the caller. We always return
6111 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07006112 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07006113 // not supplied RECENT_WITH_EXCLUDED and there is some reason
6114 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07006115
Dianne Hackborn905577f2011-09-07 18:31:28 -07006116 if (i == 0
6117 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006118 || (tr.intent == null)
6119 || ((tr.intent.getFlags()
6120 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6121 ActivityManager.RecentTaskInfo rti
6122 = new ActivityManager.RecentTaskInfo();
6123 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006124 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006125 rti.baseIntent = new Intent(
6126 tr.intent != null ? tr.intent : tr.affinityIntent);
6127 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08006128 rti.description = tr.lastDescription;
6129
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07006130 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6131 // Check whether this activity is currently available.
6132 try {
6133 if (rti.origActivity != null) {
6134 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
6135 continue;
6136 }
6137 } else if (rti.baseIntent != null) {
6138 if (pm.queryIntentActivities(rti.baseIntent,
6139 null, 0) == null) {
6140 continue;
6141 }
6142 }
6143 } catch (RemoteException e) {
6144 // Will never happen.
6145 }
6146 }
6147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006148 res.add(rti);
6149 maxNum--;
6150 }
6151 }
6152 return res;
6153 }
6154 }
6155
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006156 private TaskRecord taskForIdLocked(int id) {
6157 final int N = mRecentTasks.size();
6158 for (int i=0; i<N; i++) {
6159 TaskRecord tr = mRecentTasks.get(i);
6160 if (tr.taskId == id) {
6161 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08006162 }
6163 }
6164 return null;
6165 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006166
6167 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6168 synchronized (this) {
6169 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6170 "getTaskThumbnails()");
6171 TaskRecord tr = taskForIdLocked(id);
6172 if (tr != null) {
6173 return mMainStack.getTaskThumbnailsLocked(tr);
6174 }
6175 }
6176 return null;
6177 }
6178
6179 public boolean removeSubTask(int taskId, int subTaskIndex) {
6180 synchronized (this) {
6181 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6182 "removeSubTask()");
6183 long ident = Binder.clearCallingIdentity();
6184 try {
6185 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
6186 } finally {
6187 Binder.restoreCallingIdentity(ident);
6188 }
6189 }
6190 }
6191
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006192 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006193 TaskRecord tr = root.task;
6194 Intent baseIntent = new Intent(
6195 tr.intent != null ? tr.intent : tr.affinityIntent);
6196 ComponentName component = baseIntent.getComponent();
6197 if (component == null) {
6198 Slog.w(TAG, "Now component for base intent of task: " + tr);
6199 return;
6200 }
6201
6202 // Find any running services associated with this app.
6203 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07006204 for (ServiceRecord sr : mServiceMap.getAllServices(root.userId)) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006205 if (sr.packageName.equals(component.getPackageName())) {
6206 services.add(sr);
6207 }
6208 }
6209
6210 // Take care of any running services associated with the app.
6211 for (int i=0; i<services.size(); i++) {
6212 ServiceRecord sr = services.get(i);
6213 if (sr.startRequested) {
6214 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006215 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006216 stopServiceLocked(sr);
6217 } else {
6218 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
6219 sr.makeNextStartId(), baseIntent, -1));
6220 if (sr.app != null && sr.app.thread != null) {
6221 sendServiceArgsLocked(sr, false);
6222 }
6223 }
6224 }
6225 }
6226
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006227 if (killProcesses) {
6228 // Find any running processes associated with this app.
6229 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6230 SparseArray<ProcessRecord> appProcs
6231 = mProcessNames.getMap().get(component.getPackageName());
6232 if (appProcs != null) {
6233 for (int i=0; i<appProcs.size(); i++) {
6234 procs.add(appProcs.valueAt(i));
6235 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006236 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006237
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006238 // Kill the running processes.
6239 for (int i=0; i<procs.size(); i++) {
6240 ProcessRecord pr = procs.get(i);
6241 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6242 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
6243 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
6244 pr.processName, pr.setAdj, "remove task");
6245 Process.killProcessQuiet(pr.pid);
6246 } else {
6247 pr.waitingToKill = "remove task";
6248 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006249 }
6250 }
6251 }
6252
6253 public boolean removeTask(int taskId, int flags) {
6254 synchronized (this) {
6255 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6256 "removeTask()");
6257 long ident = Binder.clearCallingIdentity();
6258 try {
6259 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
6260 if (r != null) {
6261 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07006262 cleanUpRemovedTaskLocked(r,
6263 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006264 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07006265 } else {
6266 TaskRecord tr = null;
6267 int i=0;
6268 while (i < mRecentTasks.size()) {
6269 TaskRecord t = mRecentTasks.get(i);
6270 if (t.taskId == taskId) {
6271 tr = t;
6272 break;
6273 }
6274 i++;
6275 }
6276 if (tr != null) {
6277 if (tr.numActivities <= 0) {
6278 // Caller is just removing a recent task that is
6279 // not actively running. That is easy!
6280 mRecentTasks.remove(i);
6281 } else {
6282 Slog.w(TAG, "removeTask: task " + taskId
6283 + " does not have activities to remove, "
6284 + " but numActivities=" + tr.numActivities
6285 + ": " + tr);
6286 }
6287 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006288 }
6289 } finally {
6290 Binder.restoreCallingIdentity(ident);
6291 }
6292 }
6293 return false;
6294 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08006295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6297 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006298 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 TaskRecord jt = startTask;
6300
6301 // First look backwards
6302 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006303 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006304 if (r.task != jt) {
6305 jt = r.task;
6306 if (affinity.equals(jt.affinity)) {
6307 return j;
6308 }
6309 }
6310 }
6311
6312 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006313 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006314 jt = startTask;
6315 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006316 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 if (r.task != jt) {
6318 if (affinity.equals(jt.affinity)) {
6319 return j;
6320 }
6321 jt = r.task;
6322 }
6323 }
6324
6325 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006326 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 return N-1;
6328 }
6329
6330 return -1;
6331 }
6332
6333 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006334 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006336 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6338 "moveTaskToFront()");
6339
6340 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006341 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6342 Binder.getCallingUid(), "Task to front")) {
6343 return;
6344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006345 final long origId = Binder.clearCallingIdentity();
6346 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006347 TaskRecord tr = taskForIdLocked(task);
6348 if (tr != null) {
6349 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6350 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006351 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006352 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6353 // Caller wants the home activity moved with it. To accomplish this,
6354 // we'll just move the home task to the top first.
6355 mMainStack.moveHomeToFrontLocked();
6356 }
6357 mMainStack.moveTaskToFrontLocked(tr, null);
6358 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006360 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6361 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08006363 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6364 mMainStack.mUserLeaving = true;
6365 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006366 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6367 // Caller wants the home activity moved with it. To accomplish this,
6368 // we'll just move the home task to the top first.
6369 mMainStack.moveHomeToFrontLocked();
6370 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006371 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 return;
6373 }
6374 }
6375 } finally {
6376 Binder.restoreCallingIdentity(origId);
6377 }
6378 }
6379 }
6380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 public void moveTaskToBack(int task) {
6382 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6383 "moveTaskToBack()");
6384
6385 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006386 if (mMainStack.mResumedActivity != null
6387 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006388 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6389 Binder.getCallingUid(), "Task to back")) {
6390 return;
6391 }
6392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006393 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006394 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 Binder.restoreCallingIdentity(origId);
6396 }
6397 }
6398
6399 /**
6400 * Moves an activity, and all of the other activities within the same task, to the bottom
6401 * of the history stack. The activity's order within the task is unchanged.
6402 *
6403 * @param token A reference to the activity we wish to move
6404 * @param nonRoot If false then this only works if the activity is the root
6405 * of a task; if true it will work for any activity in a task.
6406 * @return Returns true if the move completed, false if not.
6407 */
6408 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6409 synchronized(this) {
6410 final long origId = Binder.clearCallingIdentity();
6411 int taskId = getTaskForActivityLocked(token, !nonRoot);
6412 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006413 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006414 }
6415 Binder.restoreCallingIdentity(origId);
6416 }
6417 return false;
6418 }
6419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 public void moveTaskBackwards(int task) {
6421 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6422 "moveTaskBackwards()");
6423
6424 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006425 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6426 Binder.getCallingUid(), "Task backwards")) {
6427 return;
6428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 final long origId = Binder.clearCallingIdentity();
6430 moveTaskBackwardsLocked(task);
6431 Binder.restoreCallingIdentity(origId);
6432 }
6433 }
6434
6435 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006436 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 }
6438
6439 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6440 synchronized(this) {
6441 return getTaskForActivityLocked(token, onlyRoot);
6442 }
6443 }
6444
6445 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006446 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 TaskRecord lastTask = null;
6448 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006449 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006450 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006451 if (!onlyRoot || lastTask != r.task) {
6452 return r.task.taskId;
6453 }
6454 return -1;
6455 }
6456 lastTask = r.task;
6457 }
6458
6459 return -1;
6460 }
6461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 public void finishOtherInstances(IBinder token, ComponentName className) {
6463 synchronized(this) {
6464 final long origId = Binder.clearCallingIdentity();
6465
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006466 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 TaskRecord lastTask = null;
6468 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006469 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006470 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08006471 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006472 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006473 null, "others")) {
6474 i--;
6475 N--;
6476 }
6477 }
6478 lastTask = r.task;
6479 }
6480
6481 Binder.restoreCallingIdentity(origId);
6482 }
6483 }
6484
6485 // =========================================================
6486 // THUMBNAILS
6487 // =========================================================
6488
6489 public void reportThumbnail(IBinder token,
6490 Bitmap thumbnail, CharSequence description) {
6491 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6492 final long origId = Binder.clearCallingIdentity();
6493 sendPendingThumbnail(null, token, thumbnail, description, true);
6494 Binder.restoreCallingIdentity(origId);
6495 }
6496
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006497 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006498 Bitmap thumbnail, CharSequence description, boolean always) {
6499 TaskRecord task = null;
6500 ArrayList receivers = null;
6501
6502 //System.out.println("Send pending thumbnail: " + r);
6503
6504 synchronized(this) {
6505 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006506 r = mMainStack.isInStackLocked(token);
6507 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006508 return;
6509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006511 if (thumbnail == null && r.thumbHolder != null) {
6512 thumbnail = r.thumbHolder.lastThumbnail;
6513 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006514 }
6515 if (thumbnail == null && !always) {
6516 // If there is no thumbnail, and this entry is not actually
6517 // going away, then abort for now and pick up the next
6518 // thumbnail we get.
6519 return;
6520 }
6521 task = r.task;
6522
6523 int N = mPendingThumbnails.size();
6524 int i=0;
6525 while (i<N) {
6526 PendingThumbnailsRecord pr =
6527 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6528 //System.out.println("Looking in " + pr.pendingRecords);
6529 if (pr.pendingRecords.remove(r)) {
6530 if (receivers == null) {
6531 receivers = new ArrayList();
6532 }
6533 receivers.add(pr);
6534 if (pr.pendingRecords.size() == 0) {
6535 pr.finished = true;
6536 mPendingThumbnails.remove(i);
6537 N--;
6538 continue;
6539 }
6540 }
6541 i++;
6542 }
6543 }
6544
6545 if (receivers != null) {
6546 final int N = receivers.size();
6547 for (int i=0; i<N; i++) {
6548 try {
6549 PendingThumbnailsRecord pr =
6550 (PendingThumbnailsRecord)receivers.get(i);
6551 pr.receiver.newThumbnail(
6552 task != null ? task.taskId : -1, thumbnail, description);
6553 if (pr.finished) {
6554 pr.receiver.finished();
6555 }
6556 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006557 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 }
6559 }
6560 }
6561 }
6562
6563 // =========================================================
6564 // CONTENT PROVIDERS
6565 // =========================================================
6566
Jeff Brown10e89712011-07-08 18:52:57 -07006567 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6568 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006570 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006571 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006572 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006573 } catch (RemoteException ex) {
6574 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006575 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006576 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6577 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006578 if (providers != null) {
6579 final int N = providers.size();
6580 for (int i=0; i<N; i++) {
6581 ProviderInfo cpi =
6582 (ProviderInfo)providers.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006583
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006584 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006585 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006586 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006587 cpr = new ContentProviderRecord(cpi, app.info, comp);
Amith Yamasani742a6712011-05-04 14:49:28 -07006588 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006589 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006590 if (DEBUG_MU)
6591 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006592 app.pubProviders.put(cpi.name, cpr);
6593 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006594 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 }
6596 }
6597 return providers;
6598 }
6599
6600 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006601 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006603 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006604 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006605 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006606 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 return null;
6608 }
6609 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006610 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006611 == PackageManager.PERMISSION_GRANTED) {
6612 return null;
6613 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006614
6615 PathPermission[] pps = cpi.pathPermissions;
6616 if (pps != null) {
6617 int i = pps.length;
6618 while (i > 0) {
6619 i--;
6620 PathPermission pp = pps[i];
6621 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006622 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006623 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006624 return null;
6625 }
6626 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006627 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006628 == PackageManager.PERMISSION_GRANTED) {
6629 return null;
6630 }
6631 }
6632 }
6633
Dianne Hackbornb424b632010-08-18 15:59:05 -07006634 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6635 if (perms != null) {
6636 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6637 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6638 return null;
6639 }
6640 }
6641 }
6642
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006643 String msg;
6644 if (!cpi.exported) {
6645 msg = "Permission Denial: opening provider " + cpi.name
6646 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6647 + ", uid=" + callingUid + ") that is not exported from uid "
6648 + cpi.applicationInfo.uid;
6649 } else {
6650 msg = "Permission Denial: opening provider " + cpi.name
6651 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6652 + ", uid=" + callingUid + ") requires "
6653 + cpi.readPermission + " or " + cpi.writePermission;
6654 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006655 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 return msg;
6657 }
6658
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006659 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6660 if (r != null) {
6661 Integer cnt = r.conProviders.get(cpr);
6662 if (DEBUG_PROVIDER) Slog.v(TAG,
6663 "Adding provider requested by "
6664 + r.processName + " from process "
6665 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6666 + " cnt=" + (cnt == null ? 1 : cnt));
6667 if (cnt == null) {
6668 cpr.clients.add(r);
6669 r.conProviders.put(cpr, new Integer(1));
6670 return true;
6671 } else {
6672 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
6673 }
6674 } else {
6675 cpr.externals++;
6676 }
6677 return false;
6678 }
6679
6680 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
6681 if (r != null) {
6682 Integer cnt = r.conProviders.get(cpr);
6683 if (DEBUG_PROVIDER) Slog.v(TAG,
6684 "Removing provider requested by "
6685 + r.processName + " from process "
6686 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6687 + " cnt=" + cnt);
6688 if (cnt == null || cnt.intValue() <= 1) {
6689 cpr.clients.remove(r);
6690 r.conProviders.remove(cpr);
6691 return true;
6692 } else {
6693 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
6694 }
6695 } else {
6696 cpr.externals++;
6697 }
6698 return false;
6699 }
6700
Amith Yamasani742a6712011-05-04 14:49:28 -07006701 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6702 String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 ContentProviderRecord cpr;
6704 ProviderInfo cpi = null;
6705
6706 synchronized(this) {
6707 ProcessRecord r = null;
6708 if (caller != null) {
6709 r = getRecordForAppLocked(caller);
6710 if (r == null) {
6711 throw new SecurityException(
6712 "Unable to find app for caller " + caller
6713 + " (pid=" + Binder.getCallingPid()
6714 + ") when getting content provider " + name);
6715 }
6716 }
6717
6718 // First check if this content provider has been published...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006719 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
Amith Yamasani742a6712011-05-04 14:49:28 -07006720 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006721 boolean providerRunning = cpr != null;
6722 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006724 String msg;
6725 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6726 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 }
6728
6729 if (r != null && cpr.canRunHere(r)) {
6730 // This provider has been published or is in the process
6731 // of being published... but it is also allowed to run
6732 // in the caller's process, so don't make a connection
6733 // and just let the caller instantiate its own instance.
6734 if (cpr.provider != null) {
6735 // don't give caller the provider object, it needs
6736 // to make its own.
6737 cpr = new ContentProviderRecord(cpr);
6738 }
6739 return cpr;
6740 }
6741
6742 final long origId = Binder.clearCallingIdentity();
6743
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006744 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006745 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006746 final boolean countChanged = incProviderCount(r, cpr);
6747 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006748 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006749 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006750 // make sure to count it as being accessed and thus
6751 // back up on the LRU list. This is good because
6752 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006753 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006754 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006755 }
6756
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006757 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006758 if (false) {
6759 if (cpr.name.flattenToShortString().equals(
6760 "com.android.providers.calendar/.CalendarProvider2")) {
6761 Slog.v(TAG, "****************** KILLING "
6762 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006763 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006764 }
6765 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006766 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006767 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6768 // NOTE: there is still a race here where a signal could be
6769 // pending on the process even though we managed to update its
6770 // adj level. Not sure what to do about this, but at least
6771 // the race is now smaller.
6772 if (!success) {
6773 // Uh oh... it looks like the provider's process
6774 // has been killed on us. We need to wait for a new
6775 // process to be started, and make sure its death
6776 // doesn't kill our process.
6777 Slog.i(TAG,
6778 "Existing provider " + cpr.name.flattenToShortString()
6779 + " is crashing; detaching " + r);
6780 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006781 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006782 if (!lastRef) {
6783 // This wasn't the last ref our process had on
6784 // the provider... we have now been killed, bail.
6785 return null;
6786 }
6787 providerRunning = false;
6788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 }
6790
6791 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006793
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006794 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006796 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006797 resolveContentProvider(name,
6798 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 } catch (RemoteException ex) {
6800 }
6801 if (cpi == null) {
6802 return null;
6803 }
6804
Amith Yamasani742a6712011-05-04 14:49:28 -07006805 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo,
6806 Binder.getOrigCallingUser());
6807
Dianne Hackbornb424b632010-08-18 15:59:05 -07006808 String msg;
6809 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6810 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 }
6812
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006813 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006814 && !cpi.processName.equals("system")) {
6815 // If this content provider does not run in the system
6816 // process, and the system is not yet ready to run other
6817 // processes, then fail fast instead of hanging.
6818 throw new IllegalArgumentException(
6819 "Attempt to launch content provider before system ready");
6820 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006821
6822 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006823 cpr = mProviderMap.getProviderByClass(comp, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006824 final boolean firstClass = cpr == null;
6825 if (firstClass) {
6826 try {
6827 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006828 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006829 getApplicationInfo(
6830 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006831 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006833 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834 + cpi.name);
6835 return null;
6836 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006837 ai = getAppInfoForUser(ai, Binder.getOrigCallingUser());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006838 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839 } catch (RemoteException ex) {
6840 // pm is in same process, this will never happen.
6841 }
6842 }
6843
6844 if (r != null && cpr.canRunHere(r)) {
6845 // If this is a multiprocess provider, then just return its
6846 // info and allow the caller to instantiate it. Only do
6847 // this if the provider is the same user as the caller's
6848 // process, or can run as root (so can be in any process).
6849 return cpr;
6850 }
6851
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006852 if (DEBUG_PROVIDER) {
6853 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006854 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006855 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006856 }
6857
6858 // This is single process, and our app is now connecting to it.
6859 // See if we are already in the process of launching this
6860 // provider.
6861 final int N = mLaunchingProviders.size();
6862 int i;
6863 for (i=0; i<N; i++) {
6864 if (mLaunchingProviders.get(i) == cpr) {
6865 break;
6866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006867 }
6868
6869 // If the provider is not already being launched, then get it
6870 // started.
6871 if (i >= N) {
6872 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006873
6874 try {
6875 // Content provider is now in use, its package can't be stopped.
6876 try {
6877 AppGlobals.getPackageManager().setPackageStoppedState(
6878 cpr.appInfo.packageName, false);
6879 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006880 } catch (IllegalArgumentException e) {
6881 Slog.w(TAG, "Failed trying to unstop package "
6882 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006883 }
6884
6885 ProcessRecord proc = startProcessLocked(cpi.processName,
6886 cpr.appInfo, false, 0, "content provider",
6887 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006888 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006889 if (proc == null) {
6890 Slog.w(TAG, "Unable to launch app "
6891 + cpi.applicationInfo.packageName + "/"
6892 + cpi.applicationInfo.uid + " for provider "
6893 + name + ": process is bad");
6894 return null;
6895 }
6896 cpr.launchingApp = proc;
6897 mLaunchingProviders.add(cpr);
6898 } finally {
6899 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 }
6902
6903 // Make sure the provider is published (the same provider class
6904 // may be published under multiple names).
6905 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006906 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006907 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006908 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006909 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 }
6911 }
6912
6913 // Wait for the provider to be published...
6914 synchronized (cpr) {
6915 while (cpr.provider == null) {
6916 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006917 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006918 + cpi.applicationInfo.packageName + "/"
6919 + cpi.applicationInfo.uid + " for provider "
6920 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006921 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 cpi.applicationInfo.packageName,
6923 cpi.applicationInfo.uid, name);
6924 return null;
6925 }
6926 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006927 if (DEBUG_MU) {
6928 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6929 + cpr.launchingApp);
6930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 cpr.wait();
6932 } catch (InterruptedException ex) {
6933 }
6934 }
6935 }
6936 return cpr;
6937 }
6938
6939 public final ContentProviderHolder getContentProvider(
6940 IApplicationThread caller, String name) {
6941 if (caller == null) {
6942 String msg = "null IApplicationThread when getting content provider "
6943 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006944 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006945 throw new SecurityException(msg);
6946 }
6947
Amith Yamasani742a6712011-05-04 14:49:28 -07006948 ContentProviderHolder contentProvider = getContentProviderImpl(caller, name);
6949 return contentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 }
6951
6952 private ContentProviderHolder getContentProviderExternal(String name) {
6953 return getContentProviderImpl(null, name);
6954 }
6955
6956 /**
6957 * Drop a content provider from a ProcessRecord's bookkeeping
6958 * @param cpr
6959 */
6960 public void removeContentProvider(IApplicationThread caller, String name) {
6961 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006962 int userId = UserId.getUserId(Binder.getCallingUid());
6963 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006965 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006966 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006967 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 return;
6969 }
6970 final ProcessRecord r = getRecordForAppLocked(caller);
6971 if (r == null) {
6972 throw new SecurityException(
6973 "Unable to find app for caller " + caller +
6974 " when removing content provider " + name);
6975 }
6976 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006977 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006978 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6979 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
6980 + r.info.processName + " from process "
6981 + localCpr.appInfo.processName);
6982 if (localCpr.launchingApp == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006983 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006984 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006985 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006986 return;
6987 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006988 if (decProviderCount(r, localCpr)) {
6989 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006992 }
6993 }
6994
6995 private void removeContentProviderExternal(String name) {
6996 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006997 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6998 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006999 if(cpr == null) {
7000 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08007001 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 return;
7003 }
7004
7005 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007006 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007007 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
7008 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 localCpr.externals--;
7010 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007011 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007012 }
7013 updateOomAdjLocked();
7014 }
7015 }
7016
7017 public final void publishContentProviders(IApplicationThread caller,
7018 List<ContentProviderHolder> providers) {
7019 if (providers == null) {
7020 return;
7021 }
7022
7023 synchronized(this) {
7024 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07007025 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007026 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 if (r == null) {
7028 throw new SecurityException(
7029 "Unable to find app for caller " + caller
7030 + " (pid=" + Binder.getCallingPid()
7031 + ") when publishing content providers");
7032 }
7033
7034 final long origId = Binder.clearCallingIdentity();
7035
7036 final int N = providers.size();
7037 for (int i=0; i<N; i++) {
7038 ContentProviderHolder src = providers.get(i);
7039 if (src == null || src.info == null || src.provider == null) {
7040 continue;
7041 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07007042 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007043 if (DEBUG_MU)
7044 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007046 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07007047 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007048 String names[] = dst.info.authority.split(";");
7049 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07007050 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007051 }
7052
7053 int NL = mLaunchingProviders.size();
7054 int j;
7055 for (j=0; j<NL; j++) {
7056 if (mLaunchingProviders.get(j) == dst) {
7057 mLaunchingProviders.remove(j);
7058 j--;
7059 NL--;
7060 }
7061 }
7062 synchronized (dst) {
7063 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07007064 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007065 dst.notifyAll();
7066 }
7067 updateOomAdjLocked(r);
7068 }
7069 }
7070
7071 Binder.restoreCallingIdentity(origId);
7072 }
7073 }
7074
7075 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07007076 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06007077 synchronized (mSelf) {
7078 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7079 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08007080 if (providers != null) {
7081 for (int i=providers.size()-1; i>=0; i--) {
7082 ProviderInfo pi = (ProviderInfo)providers.get(i);
7083 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7084 Slog.w(TAG, "Not installing system proc provider " + pi.name
7085 + ": not system .apk");
7086 providers.remove(i);
7087 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08007088 }
7089 }
7090 }
Josh Bartel2ecce342010-02-25 10:55:48 -06007091 if (providers != null) {
7092 mSystemThread.installSystemProviders(providers);
7093 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08007094
7095 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01007096
7097 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 }
7099
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07007100 /**
7101 * Allows app to retrieve the MIME type of a URI without having permission
7102 * to access its content provider.
7103 *
7104 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7105 *
7106 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7107 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7108 */
7109 public String getProviderMimeType(Uri uri) {
7110 final String name = uri.getAuthority();
7111 final long ident = Binder.clearCallingIdentity();
7112 ContentProviderHolder holder = null;
7113
7114 try {
7115 holder = getContentProviderExternal(name);
7116 if (holder != null) {
7117 return holder.provider.getType(uri);
7118 }
7119 } catch (RemoteException e) {
7120 Log.w(TAG, "Content provider dead retrieving " + uri, e);
7121 return null;
7122 } finally {
7123 if (holder != null) {
7124 removeContentProviderExternal(name);
7125 }
7126 Binder.restoreCallingIdentity(ident);
7127 }
7128
7129 return null;
7130 }
7131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 // =========================================================
7133 // GLOBAL MANAGEMENT
7134 // =========================================================
7135
7136 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007137 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007138 String proc = customProcess != null ? customProcess : info.processName;
7139 BatteryStatsImpl.Uid.Proc ps = null;
7140 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007141 int uid = info.uid;
7142 if (isolated) {
7143 int userId = UserId.getUserId(uid);
7144 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7145 uid = 0;
7146 while (true) {
7147 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7148 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7149 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7150 }
7151 uid = UserId.getUid(userId, mNextIsolatedProcessUid);
7152 mNextIsolatedProcessUid++;
7153 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7154 // No process for this uid, use it.
7155 break;
7156 }
7157 stepsLeft--;
7158 if (stepsLeft <= 0) {
7159 return null;
7160 }
7161 }
7162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007163 synchronized (stats) {
7164 ps = stats.getProcessStatsLocked(info.uid, proc);
7165 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007166 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 }
7168
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007169 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7170 ProcessRecord app;
7171 if (!isolated) {
7172 app = getProcessRecordLocked(info.processName, info.uid);
7173 } else {
7174 app = null;
7175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007176
7177 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007178 app = newProcessRecordLocked(null, info, null, isolated);
7179 mProcessNames.put(info.processName, app.uid, app);
7180 if (isolated) {
7181 mIsolatedProcesses.put(app.uid, app);
7182 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007183 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 }
7185
Dianne Hackborne7f97212011-02-24 14:40:20 -08007186 // This package really, really can not be stopped.
7187 try {
7188 AppGlobals.getPackageManager().setPackageStoppedState(
7189 info.packageName, false);
7190 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08007191 } catch (IllegalArgumentException e) {
7192 Slog.w(TAG, "Failed trying to unstop package "
7193 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08007194 }
7195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007196 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7197 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7198 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007199 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007200 }
7201 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7202 mPersistentStartingProcesses.add(app);
7203 startProcessLocked(app, "added application", app.processName);
7204 }
7205
7206 return app;
7207 }
7208
7209 public void unhandledBack() {
7210 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7211 "unhandledBack()");
7212
7213 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007214 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007215 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 TAG, "Performing unhandledBack(): stack size = " + count);
7217 if (count > 1) {
7218 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007219 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007220 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7221 Binder.restoreCallingIdentity(origId);
7222 }
7223 }
7224 }
7225
7226 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7227 String name = uri.getAuthority();
7228 ContentProviderHolder cph = getContentProviderExternal(name);
7229 ParcelFileDescriptor pfd = null;
7230 if (cph != null) {
7231 // We record the binder invoker's uid in thread-local storage before
7232 // going to the content provider to open the file. Later, in the code
7233 // that handles all permissions checks, we look for this uid and use
7234 // that rather than the Activity Manager's own uid. The effect is that
7235 // we do the check against the caller's permissions even though it looks
7236 // to the content provider like the Activity Manager itself is making
7237 // the request.
7238 sCallerIdentity.set(new Identity(
7239 Binder.getCallingPid(), Binder.getCallingUid()));
7240 try {
7241 pfd = cph.provider.openFile(uri, "r");
7242 } catch (FileNotFoundException e) {
7243 // do nothing; pfd will be returned null
7244 } finally {
7245 // Ensure that whatever happens, we clean up the identity state
7246 sCallerIdentity.remove();
7247 }
7248
7249 // We've got the fd now, so we're done with the provider.
7250 removeContentProviderExternal(name);
7251 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007252 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 }
7254 return pfd;
7255 }
7256
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007257 // Actually is sleeping or shutting down or whatever else in the future
7258 // is an inactive state.
7259 public boolean isSleeping() {
7260 return mSleeping || mShuttingDown;
7261 }
7262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007263 public void goingToSleep() {
7264 synchronized(this) {
7265 mSleeping = true;
7266 mWindowManager.setEventDispatching(false);
7267
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007268 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007269
7270 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07007271 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007272 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7273 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007274 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 }
7276 }
7277
Dianne Hackborn55280a92009-05-07 15:53:46 -07007278 public boolean shutdown(int timeout) {
7279 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7280 != PackageManager.PERMISSION_GRANTED) {
7281 throw new SecurityException("Requires permission "
7282 + android.Manifest.permission.SHUTDOWN);
7283 }
7284
7285 boolean timedout = false;
7286
7287 synchronized(this) {
7288 mShuttingDown = true;
7289 mWindowManager.setEventDispatching(false);
7290
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007291 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007292 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07007293 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007294 while (mMainStack.mResumedActivity != null
Dianne Hackborncbb722e2012-02-07 18:33:49 -08007295 || mMainStack.mPausingActivities.size() > 0) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07007296 long delay = endTime - System.currentTimeMillis();
7297 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007298 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07007299 timedout = true;
7300 break;
7301 }
7302 try {
7303 this.wait();
7304 } catch (InterruptedException e) {
7305 }
7306 }
7307 }
7308 }
7309
7310 mUsageStatsService.shutdown();
7311 mBatteryStatsService.shutdown();
7312
7313 return timedout;
7314 }
7315
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007316 public final void activitySlept(IBinder token) {
7317 if (localLOGV) Slog.v(
7318 TAG, "Activity slept: token=" + token);
7319
7320 ActivityRecord r = null;
7321
7322 final long origId = Binder.clearCallingIdentity();
7323
7324 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007325 r = mMainStack.isInStackLocked(token);
7326 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007327 mMainStack.activitySleptLocked(r);
7328 }
7329 }
7330
7331 Binder.restoreCallingIdentity(origId);
7332 }
7333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007334 public void wakingUp() {
7335 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007336 mWindowManager.setEventDispatching(true);
7337 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007338 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007339 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 }
7341 }
7342
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007343 public void stopAppSwitches() {
7344 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7345 != PackageManager.PERMISSION_GRANTED) {
7346 throw new SecurityException("Requires permission "
7347 + android.Manifest.permission.STOP_APP_SWITCHES);
7348 }
7349
7350 synchronized(this) {
7351 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7352 + APP_SWITCH_DELAY_TIME;
7353 mDidAppSwitch = false;
7354 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7355 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7356 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7357 }
7358 }
7359
7360 public void resumeAppSwitches() {
7361 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7362 != PackageManager.PERMISSION_GRANTED) {
7363 throw new SecurityException("Requires permission "
7364 + android.Manifest.permission.STOP_APP_SWITCHES);
7365 }
7366
7367 synchronized(this) {
7368 // Note that we don't execute any pending app switches... we will
7369 // let those wait until either the timeout, or the next start
7370 // activity request.
7371 mAppSwitchesAllowedTime = 0;
7372 }
7373 }
7374
7375 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7376 String name) {
7377 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7378 return true;
7379 }
7380
7381 final int perm = checkComponentPermission(
7382 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007383 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007384 if (perm == PackageManager.PERMISSION_GRANTED) {
7385 return true;
7386 }
7387
Joe Onorato8a9b2202010-02-26 18:56:32 -08007388 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007389 return false;
7390 }
7391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 public void setDebugApp(String packageName, boolean waitForDebugger,
7393 boolean persistent) {
7394 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7395 "setDebugApp()");
7396
7397 // Note that this is not really thread safe if there are multiple
7398 // callers into it at the same time, but that's not a situation we
7399 // care about.
7400 if (persistent) {
7401 final ContentResolver resolver = mContext.getContentResolver();
7402 Settings.System.putString(
7403 resolver, Settings.System.DEBUG_APP,
7404 packageName);
7405 Settings.System.putInt(
7406 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7407 waitForDebugger ? 1 : 0);
7408 }
7409
7410 synchronized (this) {
7411 if (!persistent) {
7412 mOrigDebugApp = mDebugApp;
7413 mOrigWaitForDebugger = mWaitForDebugger;
7414 }
7415 mDebugApp = packageName;
7416 mWaitForDebugger = waitForDebugger;
7417 mDebugTransient = !persistent;
7418 if (packageName != null) {
7419 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07007420 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007421 Binder.restoreCallingIdentity(origId);
7422 }
7423 }
7424 }
7425
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007426 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7427 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7428 synchronized (this) {
7429 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7430 if (!isDebuggable) {
7431 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7432 throw new SecurityException("Process not debuggable: " + app.packageName);
7433 }
7434 }
7435 mProfileApp = processName;
7436 mProfileFile = profileFile;
7437 if (mProfileFd != null) {
7438 try {
7439 mProfileFd.close();
7440 } catch (IOException e) {
7441 }
7442 mProfileFd = null;
7443 }
7444 mProfileFd = profileFd;
7445 mProfileType = 0;
7446 mAutoStopProfiler = autoStopProfiler;
7447 }
7448 }
7449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007450 public void setAlwaysFinish(boolean enabled) {
7451 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7452 "setAlwaysFinish()");
7453
7454 Settings.System.putInt(
7455 mContext.getContentResolver(),
7456 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7457
7458 synchronized (this) {
7459 mAlwaysFinishActivities = enabled;
7460 }
7461 }
7462
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007463 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007464 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007465 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007467 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007468 }
7469 }
7470
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007471 public boolean isUserAMonkey() {
7472 // For now the fact that there is a controller implies
7473 // we have a monkey.
7474 synchronized (this) {
7475 return mController != null;
7476 }
7477 }
7478
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007479 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06007480 synchronized (this) {
7481 mWatchers.register(watcher);
7482 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007483 }
7484
7485 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06007486 synchronized (this) {
7487 mWatchers.unregister(watcher);
7488 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007489 }
7490
Jeff Sharkeya4620792011-05-20 15:29:23 -07007491 public void registerProcessObserver(IProcessObserver observer) {
7492 mProcessObservers.register(observer);
7493 }
7494
7495 public void unregisterProcessObserver(IProcessObserver observer) {
7496 mProcessObservers.unregister(observer);
7497 }
7498
Daniel Sandler69a48172010-06-23 16:29:36 -04007499 public void setImmersive(IBinder token, boolean immersive) {
7500 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007501 ActivityRecord r = mMainStack.isInStackLocked(token);
7502 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007503 throw new IllegalArgumentException();
7504 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007505 r.immersive = immersive;
7506 }
7507 }
7508
7509 public boolean isImmersive(IBinder token) {
7510 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007511 ActivityRecord r = mMainStack.isInStackLocked(token);
7512 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007513 throw new IllegalArgumentException();
7514 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007515 return r.immersive;
7516 }
7517 }
7518
7519 public boolean isTopActivityImmersive() {
7520 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007521 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007522 return (r != null) ? r.immersive : false;
7523 }
7524 }
7525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007526 public final void enterSafeMode() {
7527 synchronized(this) {
7528 // It only makes sense to do this before the system is ready
7529 // and started launching other packages.
7530 if (!mSystemReady) {
7531 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007532 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 } catch (RemoteException e) {
7534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007535 }
7536 }
7537 }
7538
Jeff Brownb09abc12011-01-13 21:08:27 -08007539 public final void showSafeModeOverlay() {
7540 View v = LayoutInflater.from(mContext).inflate(
7541 com.android.internal.R.layout.safe_mode, null);
7542 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7543 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7544 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7545 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7546 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7547 lp.format = v.getBackground().getOpacity();
7548 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7549 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7550 ((WindowManager)mContext.getSystemService(
7551 Context.WINDOW_SERVICE)).addView(v, lp);
7552 }
7553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007554 public void noteWakeupAlarm(IIntentSender sender) {
7555 if (!(sender instanceof PendingIntentRecord)) {
7556 return;
7557 }
7558 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7559 synchronized (stats) {
7560 if (mBatteryStatsService.isOnBattery()) {
7561 mBatteryStatsService.enforceCallingPermission();
7562 PendingIntentRecord rec = (PendingIntentRecord)sender;
7563 int MY_UID = Binder.getCallingUid();
7564 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7565 BatteryStatsImpl.Uid.Pkg pkg =
7566 stats.getPackageStatsLocked(uid, rec.key.packageName);
7567 pkg.incWakeupsLocked();
7568 }
7569 }
7570 }
7571
Dianne Hackborn64825172011-03-02 21:32:58 -08007572 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007574 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007575 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007576 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007577 // XXX Note: don't acquire main activity lock here, because the window
7578 // manager calls in with its locks held.
7579
7580 boolean killed = false;
7581 synchronized (mPidsSelfLocked) {
7582 int[] types = new int[pids.length];
7583 int worstType = 0;
7584 for (int i=0; i<pids.length; i++) {
7585 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7586 if (proc != null) {
7587 int type = proc.setAdj;
7588 types[i] = type;
7589 if (type > worstType) {
7590 worstType = type;
7591 }
7592 }
7593 }
7594
Dianne Hackborn64825172011-03-02 21:32:58 -08007595 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007596 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007597 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7598 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007599 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007600 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007601
7602 // If this is not a secure call, don't let it kill processes that
7603 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007604 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7605 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007606 }
7607
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007608 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007609 for (int i=0; i<pids.length; i++) {
7610 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7611 if (proc == null) {
7612 continue;
7613 }
7614 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007615 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007616 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007617 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7618 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007619 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007620 proc.killedBackground = true;
7621 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 }
7623 }
7624 }
7625 return killed;
7626 }
7627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007628 public final void startRunning(String pkg, String cls, String action,
7629 String data) {
7630 synchronized(this) {
7631 if (mStartRunning) {
7632 return;
7633 }
7634 mStartRunning = true;
7635 mTopComponent = pkg != null && cls != null
7636 ? new ComponentName(pkg, cls) : null;
7637 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7638 mTopData = data;
7639 if (!mSystemReady) {
7640 return;
7641 }
7642 }
7643
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007644 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007645 }
7646
7647 private void retrieveSettings() {
7648 final ContentResolver resolver = mContext.getContentResolver();
7649 String debugApp = Settings.System.getString(
7650 resolver, Settings.System.DEBUG_APP);
7651 boolean waitForDebugger = Settings.System.getInt(
7652 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7653 boolean alwaysFinishActivities = Settings.System.getInt(
7654 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7655
7656 Configuration configuration = new Configuration();
7657 Settings.System.getConfiguration(resolver, configuration);
7658
7659 synchronized (this) {
7660 mDebugApp = mOrigDebugApp = debugApp;
7661 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7662 mAlwaysFinishActivities = alwaysFinishActivities;
7663 // This happens before any activities are started, so we can
7664 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007665 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007666 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007667 }
7668 }
7669
7670 public boolean testIsSystemReady() {
7671 // no need to synchronize(this) just to read & return the value
7672 return mSystemReady;
7673 }
7674
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007675 private static File getCalledPreBootReceiversFile() {
7676 File dataDir = Environment.getDataDirectory();
7677 File systemDir = new File(dataDir, "system");
7678 File fname = new File(systemDir, "called_pre_boots.dat");
7679 return fname;
7680 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007681
7682 static final int LAST_DONE_VERSION = 10000;
7683
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007684 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7685 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7686 File file = getCalledPreBootReceiversFile();
7687 FileInputStream fis = null;
7688 try {
7689 fis = new FileInputStream(file);
7690 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007691 int fvers = dis.readInt();
7692 if (fvers == LAST_DONE_VERSION) {
7693 String vers = dis.readUTF();
7694 String codename = dis.readUTF();
7695 String build = dis.readUTF();
7696 if (android.os.Build.VERSION.RELEASE.equals(vers)
7697 && android.os.Build.VERSION.CODENAME.equals(codename)
7698 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7699 int num = dis.readInt();
7700 while (num > 0) {
7701 num--;
7702 String pkg = dis.readUTF();
7703 String cls = dis.readUTF();
7704 lastDoneReceivers.add(new ComponentName(pkg, cls));
7705 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007706 }
7707 }
7708 } catch (FileNotFoundException e) {
7709 } catch (IOException e) {
7710 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7711 } finally {
7712 if (fis != null) {
7713 try {
7714 fis.close();
7715 } catch (IOException e) {
7716 }
7717 }
7718 }
7719 return lastDoneReceivers;
7720 }
7721
7722 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7723 File file = getCalledPreBootReceiversFile();
7724 FileOutputStream fos = null;
7725 DataOutputStream dos = null;
7726 try {
7727 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7728 fos = new FileOutputStream(file);
7729 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007730 dos.writeInt(LAST_DONE_VERSION);
7731 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007732 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007733 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007734 dos.writeInt(list.size());
7735 for (int i=0; i<list.size(); i++) {
7736 dos.writeUTF(list.get(i).getPackageName());
7737 dos.writeUTF(list.get(i).getClassName());
7738 }
7739 } catch (IOException e) {
7740 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7741 file.delete();
7742 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007743 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007744 if (dos != null) {
7745 try {
7746 dos.close();
7747 } catch (IOException e) {
7748 // TODO Auto-generated catch block
7749 e.printStackTrace();
7750 }
7751 }
7752 }
7753 }
7754
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007755 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007756 synchronized(this) {
7757 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007758 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007759 return;
7760 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007761
7762 // Check to see if there are any update receivers to run.
7763 if (!mDidUpdate) {
7764 if (mWaitingUpdate) {
7765 return;
7766 }
7767 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7768 List<ResolveInfo> ris = null;
7769 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007770 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007771 intent, null, 0);
7772 } catch (RemoteException e) {
7773 }
7774 if (ris != null) {
7775 for (int i=ris.size()-1; i>=0; i--) {
7776 if ((ris.get(i).activityInfo.applicationInfo.flags
7777 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7778 ris.remove(i);
7779 }
7780 }
7781 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007782
7783 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7784
7785 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007786 for (int i=0; i<ris.size(); i++) {
7787 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007788 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7789 if (lastDoneReceivers.contains(comp)) {
7790 ris.remove(i);
7791 i--;
7792 }
7793 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007794
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007795 for (int i=0; i<ris.size(); i++) {
7796 ActivityInfo ai = ris.get(i).activityInfo;
7797 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7798 doneReceivers.add(comp);
7799 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007800 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08007801 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007802 finisher = new IIntentReceiver.Stub() {
7803 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07007804 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007805 boolean sticky) {
7806 // The raw IIntentReceiver interface is called
7807 // with the AM lock held, so redispatch to
7808 // execute our code without the lock.
7809 mHandler.post(new Runnable() {
7810 public void run() {
7811 synchronized (ActivityManagerService.this) {
7812 mDidUpdate = true;
7813 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007814 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007815 showBootMessage(mContext.getText(
7816 R.string.android_upgrading_complete),
7817 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007818 systemReady(goingCallback);
7819 }
7820 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007821 }
7822 };
7823 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007824 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Amith Yamasani742a6712011-05-04 14:49:28 -07007825 /* TODO: Send this to all users */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007826 broadcastIntentLocked(null, null, intent, null, finisher,
Amith Yamasani742a6712011-05-04 14:49:28 -07007827 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7828 Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08007829 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007830 mWaitingUpdate = true;
7831 }
7832 }
7833 }
7834 if (mWaitingUpdate) {
7835 return;
7836 }
7837 mDidUpdate = true;
7838 }
7839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007840 mSystemReady = true;
7841 if (!mStartRunning) {
7842 return;
7843 }
7844 }
7845
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007846 ArrayList<ProcessRecord> procsToKill = null;
7847 synchronized(mPidsSelfLocked) {
7848 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7849 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7850 if (!isAllowedWhileBooting(proc.info)){
7851 if (procsToKill == null) {
7852 procsToKill = new ArrayList<ProcessRecord>();
7853 }
7854 procsToKill.add(proc);
7855 }
7856 }
7857 }
7858
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007859 synchronized(this) {
7860 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007861 for (int i=procsToKill.size()-1; i>=0; i--) {
7862 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007863 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007864 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007865 }
7866 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007867
7868 // Now that we have cleaned up any update processes, we
7869 // are ready to start launching real processes and know that
7870 // we won't trample on them any more.
7871 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007872 }
7873
Joe Onorato8a9b2202010-02-26 18:56:32 -08007874 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007875 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007876 SystemClock.uptimeMillis());
7877
7878 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007879 // Make sure we have no pre-ready processes sitting around.
7880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007881 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7882 ResolveInfo ri = mContext.getPackageManager()
7883 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007884 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 CharSequence errorMsg = null;
7886 if (ri != null) {
7887 ActivityInfo ai = ri.activityInfo;
7888 ApplicationInfo app = ai.applicationInfo;
7889 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7890 mTopAction = Intent.ACTION_FACTORY_TEST;
7891 mTopData = null;
7892 mTopComponent = new ComponentName(app.packageName,
7893 ai.name);
7894 } else {
7895 errorMsg = mContext.getResources().getText(
7896 com.android.internal.R.string.factorytest_not_system);
7897 }
7898 } else {
7899 errorMsg = mContext.getResources().getText(
7900 com.android.internal.R.string.factorytest_no_action);
7901 }
7902 if (errorMsg != null) {
7903 mTopAction = null;
7904 mTopData = null;
7905 mTopComponent = null;
7906 Message msg = Message.obtain();
7907 msg.what = SHOW_FACTORY_ERROR_MSG;
7908 msg.getData().putCharSequence("msg", errorMsg);
7909 mHandler.sendMessage(msg);
7910 }
7911 }
7912 }
7913
7914 retrieveSettings();
7915
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007916 if (goingCallback != null) goingCallback.run();
7917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007918 synchronized (this) {
7919 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7920 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007921 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007922 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007923 if (apps != null) {
7924 int N = apps.size();
7925 int i;
7926 for (i=0; i<N; i++) {
7927 ApplicationInfo info
7928 = (ApplicationInfo)apps.get(i);
7929 if (info != null &&
7930 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007931 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932 }
7933 }
7934 }
7935 } catch (RemoteException ex) {
7936 // pm is in same process, this will never happen.
7937 }
7938 }
7939
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007940 // Start up initial activity.
7941 mBooting = true;
7942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007944 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945 Message msg = Message.obtain();
7946 msg.what = SHOW_UID_ERROR_MSG;
7947 mHandler.sendMessage(msg);
7948 }
7949 } catch (RemoteException e) {
7950 }
7951
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007952 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 }
7954 }
7955
Dan Egnorb7f03672009-12-09 16:22:32 -08007956 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007957 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007958 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007959 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007960 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007961 startAppProblemLocked(app);
7962 app.stopFreezingAllLocked();
7963 return handleAppCrashLocked(app);
7964 }
7965
Dan Egnorb7f03672009-12-09 16:22:32 -08007966 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007967 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007968 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007969 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007970 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7971 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007972 startAppProblemLocked(app);
7973 app.stopFreezingAllLocked();
7974 }
7975
7976 /**
7977 * Generate a process error record, suitable for attachment to a ProcessRecord.
7978 *
7979 * @param app The ProcessRecord in which the error occurred.
7980 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7981 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007982 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007983 * @param shortMsg Short message describing the crash.
7984 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007985 * @param stackTrace Full crash stack trace, may be null.
7986 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 * @return Returns a fully-formed AppErrorStateInfo record.
7988 */
7989 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007990 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007991 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007993 report.condition = condition;
7994 report.processName = app.processName;
7995 report.pid = app.pid;
7996 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007997 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007998 report.shortMsg = shortMsg;
7999 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08008000 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001
8002 return report;
8003 }
8004
Dan Egnor42471dd2010-01-07 17:25:22 -08008005 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008006 synchronized (this) {
8007 app.crashing = false;
8008 app.crashingReport = null;
8009 app.notResponding = false;
8010 app.notRespondingReport = null;
8011 if (app.anrDialog == fromDialog) {
8012 app.anrDialog = null;
8013 }
8014 if (app.waitDialog == fromDialog) {
8015 app.waitDialog = null;
8016 }
8017 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08008018 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008019 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07008020 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
8021 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008022 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 }
8025 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008026
Dan Egnorb7f03672009-12-09 16:22:32 -08008027 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 long now = SystemClock.uptimeMillis();
8029
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008030 Long crashTime;
8031 if (!app.isolated) {
8032 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8033 } else {
8034 crashTime = null;
8035 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07008036 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008038 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08008040 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008041 app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008042 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8043 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008044 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008045 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008046 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008047 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048 }
8049 }
8050 if (!app.persistent) {
8051 // We don't want to start this process again until the user
8052 // explicitly does so... but for persistent process, we really
8053 // need to keep it running. If a persistent process is actually
8054 // repeatedly crashing, then badness for everyone.
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008055 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008056 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008057 if (!app.isolated) {
8058 // XXX We don't have a way to mark isolated processes
8059 // as bad, since they don't have a peristent identity.
8060 mBadProcesses.put(app.info.processName, app.uid, now);
8061 mProcessCrashTimes.remove(app.info.processName, app.uid);
8062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008063 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07008065 // Don't let services in this process be restarted and potentially
8066 // annoy the user repeatedly. Unless it is persistent, since those
8067 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08008068 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08008069 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008070 return false;
8071 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08008072 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008073 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008074 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008075 if (r.app == app) {
8076 // If the top running activity is from this crashing
8077 // process, then terminate it to avoid getting in a loop.
8078 Slog.w(TAG, " Force finishing activity "
8079 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08008080 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008081 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008082 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08008083 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008084 // stopped, to avoid a situation where one will get
8085 // re-start our crashing activity once it gets resumed again.
8086 index--;
8087 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008088 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008089 if (r.state == ActivityState.RESUMED
8090 || r.state == ActivityState.PAUSING
8091 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008092 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008093 Slog.w(TAG, " Force finishing activity "
8094 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008095 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008096 Activity.RESULT_CANCELED, null, "crashed");
8097 }
8098 }
8099 }
8100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008101 }
8102
8103 // Bump up the crash count of any services currently running in the proc.
8104 if (app.services.size() != 0) {
8105 // Any services running in the application need to be placed
8106 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008107 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008109 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 sr.crashCount++;
8111 }
8112 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02008113
8114 // If the crashing process is what we consider to be the "home process" and it has been
8115 // replaced by a third-party app, clear the package preferred activities from packages
8116 // with a home activity running in the process to prevent a repeatedly crashing app
8117 // from blocking the user to manually clear the list.
8118 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8119 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8120 Iterator it = mHomeProcess.activities.iterator();
8121 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07008122 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02008123 if (r.isHomeActivity) {
8124 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8125 try {
8126 ActivityThread.getPackageManager()
8127 .clearPackagePreferredActivities(r.packageName);
8128 } catch (RemoteException c) {
8129 // pm is in same process, this will never happen.
8130 }
8131 }
8132 }
8133 }
8134
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008135 if (!app.isolated) {
8136 // XXX Can't keep track of crash times for isolated processes,
8137 // because they don't have a perisistent identity.
8138 mProcessCrashTimes.put(app.info.processName, app.uid, now);
8139 }
8140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008141 return true;
8142 }
8143
8144 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08008145 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8146 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008147 skipCurrentReceiverLocked(app);
8148 }
8149
8150 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08008151 for (BroadcastQueue queue : mBroadcastQueues) {
8152 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 }
8154 }
8155
Dan Egnor60d87622009-12-16 16:32:58 -08008156 /**
8157 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8158 * The application process will exit immediately after this call returns.
8159 * @param app object of the crashing app, null for the system server
8160 * @param crashInfo describing the exception
8161 */
8162 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008163 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008164 final String processName = app == null ? "system_server"
8165 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008166
8167 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008168 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008169 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008170 crashInfo.exceptionClassName,
8171 crashInfo.exceptionMessage,
8172 crashInfo.throwFileName,
8173 crashInfo.throwLineNumber);
8174
Jeff Sharkeya353d262011-10-28 11:12:06 -07008175 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008176
8177 crashApplication(r, crashInfo);
8178 }
8179
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008180 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008181 IBinder app,
8182 int violationMask,
8183 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008184 ProcessRecord r = findAppProcess(app, "StrictMode");
8185 if (r == null) {
8186 return;
8187 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008188
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008189 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08008190 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008191 boolean logIt = true;
8192 synchronized (mAlreadyLoggedViolatedStacks) {
8193 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8194 logIt = false;
8195 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008196 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008197 // the relative pain numbers, without logging all
8198 // the stack traces repeatedly. We'd want to do
8199 // likewise in the client code, which also does
8200 // dup suppression, before the Binder call.
8201 } else {
8202 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8203 mAlreadyLoggedViolatedStacks.clear();
8204 }
8205 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8206 }
8207 }
8208 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008209 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008210 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008211 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008212
8213 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8214 AppErrorResult result = new AppErrorResult();
8215 synchronized (this) {
8216 final long origId = Binder.clearCallingIdentity();
8217
8218 Message msg = Message.obtain();
8219 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8220 HashMap<String, Object> data = new HashMap<String, Object>();
8221 data.put("result", result);
8222 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008223 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008224 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008225 msg.obj = data;
8226 mHandler.sendMessage(msg);
8227
8228 Binder.restoreCallingIdentity(origId);
8229 }
8230 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07008231 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008232 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008233 }
8234
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008235 // Depending on the policy in effect, there could be a bunch of
8236 // these in quick succession so we try to batch these together to
8237 // minimize disk writes, number of dropbox entries, and maximize
8238 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008239 private void logStrictModeViolationToDropBox(
8240 ProcessRecord process,
8241 StrictMode.ViolationInfo info) {
8242 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008243 return;
8244 }
8245 final boolean isSystemApp = process == null ||
8246 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8247 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008248 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008249 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8250 final DropBoxManager dbox = (DropBoxManager)
8251 mContext.getSystemService(Context.DROPBOX_SERVICE);
8252
8253 // Exit early if the dropbox isn't configured to accept this report type.
8254 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8255
8256 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008257 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008258 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8259 synchronized (sb) {
8260 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008261 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008262 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8263 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008264 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8265 if (info.violationNumThisLoop != 0) {
8266 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8267 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07008268 if (info.numAnimationsRunning != 0) {
8269 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8270 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07008271 if (info.broadcastIntentAction != null) {
8272 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8273 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008274 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008275 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008276 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08008277 if (info.numInstances != -1) {
8278 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8279 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008280 if (info.tags != null) {
8281 for (String tag : info.tags) {
8282 sb.append("Span-Tag: ").append(tag).append("\n");
8283 }
8284 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008285 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008286 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8287 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008288 }
8289 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008290
8291 // Only buffer up to ~64k. Various logging bits truncate
8292 // things at 128k.
8293 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008294 }
8295
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008296 // Flush immediately if the buffer's grown too large, or this
8297 // is a non-system app. Non-system apps are isolated with a
8298 // different tag & policy and not batched.
8299 //
8300 // Batching is useful during internal testing with
8301 // StrictMode settings turned up high. Without batching,
8302 // thousands of separate files could be created on boot.
8303 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008304 new Thread("Error dump: " + dropboxTag) {
8305 @Override
8306 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008307 String report;
8308 synchronized (sb) {
8309 report = sb.toString();
8310 sb.delete(0, sb.length());
8311 sb.trimToSize();
8312 }
8313 if (report.length() != 0) {
8314 dbox.addText(dropboxTag, report);
8315 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008316 }
8317 }.start();
8318 return;
8319 }
8320
8321 // System app batching:
8322 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008323 // An existing dropbox-writing thread is outstanding, so
8324 // we don't need to start it up. The existing thread will
8325 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008326 return;
8327 }
8328
8329 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8330 // (After this point, we shouldn't access AMS internal data structures.)
8331 new Thread("Error dump: " + dropboxTag) {
8332 @Override
8333 public void run() {
8334 // 5 second sleep to let stacks arrive and be batched together
8335 try {
8336 Thread.sleep(5000); // 5 seconds
8337 } catch (InterruptedException e) {}
8338
8339 String errorReport;
8340 synchronized (mStrictModeBuffer) {
8341 errorReport = mStrictModeBuffer.toString();
8342 if (errorReport.length() == 0) {
8343 return;
8344 }
8345 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8346 mStrictModeBuffer.trimToSize();
8347 }
8348 dbox.addText(dropboxTag, errorReport);
8349 }
8350 }.start();
8351 }
8352
Dan Egnor60d87622009-12-16 16:32:58 -08008353 /**
8354 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8355 * @param app object of the crashing app, null for the system server
8356 * @param tag reported by the caller
8357 * @param crashInfo describing the context of the error
8358 * @return true if the process should exit immediately (WTF is fatal)
8359 */
8360 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008361 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008362 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008363 final String processName = app == null ? "system_server"
8364 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008365
8366 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008367 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008368 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008369 tag, crashInfo.exceptionMessage);
8370
Jeff Sharkeya353d262011-10-28 11:12:06 -07008371 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008372
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008373 if (r != null && r.pid != Process.myPid() &&
8374 Settings.Secure.getInt(mContext.getContentResolver(),
8375 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008376 crashApplication(r, crashInfo);
8377 return true;
8378 } else {
8379 return false;
8380 }
8381 }
8382
8383 /**
8384 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8385 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8386 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008387 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008388 if (app == null) {
8389 return null;
8390 }
8391
8392 synchronized (this) {
8393 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8394 final int NA = apps.size();
8395 for (int ia=0; ia<NA; ia++) {
8396 ProcessRecord p = apps.valueAt(ia);
8397 if (p.thread != null && p.thread.asBinder() == app) {
8398 return p;
8399 }
8400 }
8401 }
8402
Dianne Hackborncb44d962011-03-10 17:02:27 -08008403 Slog.w(TAG, "Can't find mystery application for " + reason
8404 + " from pid=" + Binder.getCallingPid()
8405 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008406 return null;
8407 }
8408 }
8409
8410 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008411 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8412 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008413 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008414 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8415 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008416 // Watchdog thread ends up invoking this function (with
8417 // a null ProcessRecord) to add the stack file to dropbox.
8418 // Do not acquire a lock on this (am) in such cases, as it
8419 // could cause a potential deadlock, if and when watchdog
8420 // is invoked due to unavailability of lock on am and it
8421 // would prevent watchdog from killing system_server.
8422 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008423 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008424 return;
8425 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008426 // Note: ProcessRecord 'process' is guarded by the service
8427 // instance. (notably process.pkgList, which could otherwise change
8428 // concurrently during execution of this method)
8429 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008430 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008431 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008432 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008433 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8434 for (String pkg : process.pkgList) {
8435 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008436 try {
Dan Egnora455d192010-03-12 08:52:28 -08008437 PackageInfo pi = pm.getPackageInfo(pkg, 0);
8438 if (pi != null) {
8439 sb.append(" v").append(pi.versionCode);
8440 if (pi.versionName != null) {
8441 sb.append(" (").append(pi.versionName).append(")");
8442 }
8443 }
8444 } catch (RemoteException e) {
8445 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008446 }
Dan Egnora455d192010-03-12 08:52:28 -08008447 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008448 }
Dan Egnora455d192010-03-12 08:52:28 -08008449 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008450 }
8451
8452 private static String processClass(ProcessRecord process) {
8453 if (process == null || process.pid == MY_PID) {
8454 return "system_server";
8455 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8456 return "system_app";
8457 } else {
8458 return "data_app";
8459 }
8460 }
8461
8462 /**
8463 * Write a description of an error (crash, WTF, ANR) to the drop box.
8464 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8465 * @param process which caused the error, null means the system server
8466 * @param activity which triggered the error, null if unknown
8467 * @param parent activity related to the error, null if unknown
8468 * @param subject line related to the error, null if absent
8469 * @param report in long form describing the error, null if absent
8470 * @param logFile to include in the report, null if none
8471 * @param crashInfo giving an application stack trace, null if absent
8472 */
8473 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008474 ProcessRecord process, String processName, ActivityRecord activity,
8475 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008476 final String report, final File logFile,
8477 final ApplicationErrorReport.CrashInfo crashInfo) {
8478 // NOTE -- this must never acquire the ActivityManagerService lock,
8479 // otherwise the watchdog may be prevented from resetting the system.
8480
8481 final String dropboxTag = processClass(process) + "_" + eventType;
8482 final DropBoxManager dbox = (DropBoxManager)
8483 mContext.getSystemService(Context.DROPBOX_SERVICE);
8484
8485 // Exit early if the dropbox isn't configured to accept this report type.
8486 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8487
8488 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008489 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008490 if (activity != null) {
8491 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8492 }
8493 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8494 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8495 }
8496 if (parent != null && parent != activity) {
8497 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8498 }
8499 if (subject != null) {
8500 sb.append("Subject: ").append(subject).append("\n");
8501 }
8502 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008503 if (Debug.isDebuggerConnected()) {
8504 sb.append("Debugger: Connected\n");
8505 }
Dan Egnora455d192010-03-12 08:52:28 -08008506 sb.append("\n");
8507
8508 // Do the rest in a worker thread to avoid blocking the caller on I/O
8509 // (After this point, we shouldn't access AMS internal data structures.)
8510 Thread worker = new Thread("Error dump: " + dropboxTag) {
8511 @Override
8512 public void run() {
8513 if (report != null) {
8514 sb.append(report);
8515 }
8516 if (logFile != null) {
8517 try {
8518 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8519 } catch (IOException e) {
8520 Slog.e(TAG, "Error reading " + logFile, e);
8521 }
8522 }
8523 if (crashInfo != null && crashInfo.stackTrace != null) {
8524 sb.append(crashInfo.stackTrace);
8525 }
8526
8527 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8528 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8529 if (lines > 0) {
8530 sb.append("\n");
8531
8532 // Merge several logcat streams, and take the last N lines
8533 InputStreamReader input = null;
8534 try {
8535 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8536 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8537 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8538
8539 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8540 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8541 input = new InputStreamReader(logcat.getInputStream());
8542
8543 int num;
8544 char[] buf = new char[8192];
8545 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8546 } catch (IOException e) {
8547 Slog.e(TAG, "Error running logcat", e);
8548 } finally {
8549 if (input != null) try { input.close(); } catch (IOException e) {}
8550 }
8551 }
8552
8553 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008554 }
Dan Egnora455d192010-03-12 08:52:28 -08008555 };
8556
8557 if (process == null || process.pid == MY_PID) {
8558 worker.run(); // We may be about to die -- need to run this synchronously
8559 } else {
8560 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008561 }
8562 }
8563
8564 /**
8565 * Bring up the "unexpected error" dialog box for a crashing app.
8566 * Deal with edge cases (intercepts from instrumented applications,
8567 * ActivityController, error intent receivers, that sort of thing).
8568 * @param r the application crashing
8569 * @param crashInfo describing the failure
8570 */
8571 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008572 long timeMillis = System.currentTimeMillis();
8573 String shortMsg = crashInfo.exceptionClassName;
8574 String longMsg = crashInfo.exceptionMessage;
8575 String stackTrace = crashInfo.stackTrace;
8576 if (shortMsg != null && longMsg != null) {
8577 longMsg = shortMsg + ": " + longMsg;
8578 } else if (shortMsg != null) {
8579 longMsg = shortMsg;
8580 }
8581
Dan Egnor60d87622009-12-16 16:32:58 -08008582 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008583 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008584 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 try {
8586 String name = r != null ? r.processName : null;
8587 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008588 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008589 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008590 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008591 + " at watcher's request");
8592 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008593 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 }
8595 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008596 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597 }
8598 }
8599
8600 final long origId = Binder.clearCallingIdentity();
8601
8602 // If this process is running instrumentation, finish it.
8603 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008604 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008606 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8607 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 Bundle info = new Bundle();
8609 info.putString("shortMsg", shortMsg);
8610 info.putString("longMsg", longMsg);
8611 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8612 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008613 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008614 }
8615
Dan Egnor60d87622009-12-16 16:32:58 -08008616 // If we can't identify the process or it's already exceeded its crash quota,
8617 // quit right away without showing a crash dialog.
8618 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008619 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008620 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 }
8622
8623 Message msg = Message.obtain();
8624 msg.what = SHOW_ERROR_MSG;
8625 HashMap data = new HashMap();
8626 data.put("result", result);
8627 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 msg.obj = data;
8629 mHandler.sendMessage(msg);
8630
8631 Binder.restoreCallingIdentity(origId);
8632 }
8633
8634 int res = result.get();
8635
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008636 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008638 if (r != null && !r.isolated) {
8639 // XXX Can't keep track of crash time for isolated processes,
8640 // since they don't have a persistent identity.
8641 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008642 SystemClock.uptimeMillis());
8643 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008644 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008645 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008646 }
8647 }
8648
8649 if (appErrorIntent != null) {
8650 try {
8651 mContext.startActivity(appErrorIntent);
8652 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008653 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008656 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008657
8658 Intent createAppErrorIntentLocked(ProcessRecord r,
8659 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8660 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008661 if (report == null) {
8662 return null;
8663 }
8664 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8665 result.setComponent(r.errorReportReceiver);
8666 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8667 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8668 return result;
8669 }
8670
Dan Egnorb7f03672009-12-09 16:22:32 -08008671 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8672 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008673 if (r.errorReportReceiver == null) {
8674 return null;
8675 }
8676
8677 if (!r.crashing && !r.notResponding) {
8678 return null;
8679 }
8680
Dan Egnorb7f03672009-12-09 16:22:32 -08008681 ApplicationErrorReport report = new ApplicationErrorReport();
8682 report.packageName = r.info.packageName;
8683 report.installerPackageName = r.errorReportReceiver.getPackageName();
8684 report.processName = r.processName;
8685 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008686 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008687
Dan Egnorb7f03672009-12-09 16:22:32 -08008688 if (r.crashing) {
8689 report.type = ApplicationErrorReport.TYPE_CRASH;
8690 report.crashInfo = crashInfo;
8691 } else if (r.notResponding) {
8692 report.type = ApplicationErrorReport.TYPE_ANR;
8693 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008694
Dan Egnorb7f03672009-12-09 16:22:32 -08008695 report.anrInfo.activity = r.notRespondingReport.tag;
8696 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8697 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008698 }
8699
Dan Egnorb7f03672009-12-09 16:22:32 -08008700 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008701 }
8702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008703 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8704 // assume our apps are happy - lazy create the list
8705 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8706
8707 synchronized (this) {
8708
8709 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008710 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8711 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008712 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8713 // This one's in trouble, so we'll generate a report for it
8714 // crashes are higher priority (in case there's a crash *and* an anr)
8715 ActivityManager.ProcessErrorStateInfo report = null;
8716 if (app.crashing) {
8717 report = app.crashingReport;
8718 } else if (app.notResponding) {
8719 report = app.notRespondingReport;
8720 }
8721
8722 if (report != null) {
8723 if (errList == null) {
8724 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8725 }
8726 errList.add(report);
8727 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008728 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 " crashing = " + app.crashing +
8730 " notResponding = " + app.notResponding);
8731 }
8732 }
8733 }
8734 }
8735
8736 return errList;
8737 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008738
8739 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008740 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008741 if (currApp != null) {
8742 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8743 }
8744 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008745 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8746 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008747 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8748 if (currApp != null) {
8749 currApp.lru = 0;
8750 }
8751 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008752 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008753 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8754 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8755 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8756 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8757 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8758 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8759 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8760 } else {
8761 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8762 }
8763 }
8764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008765 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8766 // Lazy instantiation of list
8767 List<ActivityManager.RunningAppProcessInfo> runList = null;
8768 synchronized (this) {
8769 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008770 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8771 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008772 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8773 // Generate process state info for running application
8774 ActivityManager.RunningAppProcessInfo currApp =
8775 new ActivityManager.RunningAppProcessInfo(app.processName,
8776 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07008777 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008778 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07008779 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07008780 }
Dianne Hackborn42499172010-10-15 18:45:07 -07008781 if (app.persistent) {
8782 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008784 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008785 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008786 currApp.importanceReasonCode = app.adjTypeCode;
8787 if (app.adjSource instanceof ProcessRecord) {
8788 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008789 currApp.importanceReasonImportance = oomAdjToImportance(
8790 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008791 } else if (app.adjSource instanceof ActivityRecord) {
8792 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008793 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8794 }
8795 if (app.adjTarget instanceof ComponentName) {
8796 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8797 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008798 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008799 // + " lru=" + currApp.lru);
8800 if (runList == null) {
8801 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8802 }
8803 runList.add(currApp);
8804 }
8805 }
8806 }
8807 return runList;
8808 }
8809
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008810 public List<ApplicationInfo> getRunningExternalApplications() {
8811 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8812 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8813 if (runningApps != null && runningApps.size() > 0) {
8814 Set<String> extList = new HashSet<String>();
8815 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8816 if (app.pkgList != null) {
8817 for (String pkg : app.pkgList) {
8818 extList.add(pkg);
8819 }
8820 }
8821 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008822 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008823 for (String pkg : extList) {
8824 try {
8825 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
8826 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8827 retList.add(info);
8828 }
8829 } catch (RemoteException e) {
8830 }
8831 }
8832 }
8833 return retList;
8834 }
8835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008836 @Override
8837 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008838 if (checkCallingPermission(android.Manifest.permission.DUMP)
8839 != PackageManager.PERMISSION_GRANTED) {
8840 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8841 + Binder.getCallingPid()
8842 + ", uid=" + Binder.getCallingUid()
8843 + " without permission "
8844 + android.Manifest.permission.DUMP);
8845 return;
8846 }
8847
8848 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008849 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008850 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008851
8852 int opti = 0;
8853 while (opti < args.length) {
8854 String opt = args[opti];
8855 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8856 break;
8857 }
8858 opti++;
8859 if ("-a".equals(opt)) {
8860 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 } else if ("-c".equals(opt)) {
8862 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008863 } else if ("-h".equals(opt)) {
8864 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008865 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008866 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008867 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008868 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8869 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8870 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008871 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008872 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008873 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008874 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008875 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008876 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008877 pw.println(" all: dump all activities");
8878 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008879 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008880 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8881 pw.println(" a partial substring in a component name, a");
8882 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008883 pw.println(" -a: include all available server state.");
8884 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008885 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008886 } else {
8887 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008889 }
8890
8891 // Is the caller requesting to dump a particular piece of data?
8892 if (opti < args.length) {
8893 String cmd = args[opti];
8894 opti++;
8895 if ("activities".equals(cmd) || "a".equals(cmd)) {
8896 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008897 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008898 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008899 return;
8900 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008901 String[] newArgs;
8902 String name;
8903 if (opti >= args.length) {
8904 name = null;
8905 newArgs = EMPTY_STRING_ARRAY;
8906 } else {
8907 name = args[opti];
8908 opti++;
8909 newArgs = new String[args.length - opti];
8910 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8911 args.length - opti);
8912 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008913 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008914 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008915 }
8916 return;
8917 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008918 String[] newArgs;
8919 String name;
8920 if (opti >= args.length) {
8921 name = null;
8922 newArgs = EMPTY_STRING_ARRAY;
8923 } else {
8924 name = args[opti];
8925 opti++;
8926 newArgs = new String[args.length - opti];
8927 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8928 args.length - opti);
8929 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008930 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008931 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008932 }
8933 return;
8934 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008935 String[] newArgs;
8936 String name;
8937 if (opti >= args.length) {
8938 name = null;
8939 newArgs = EMPTY_STRING_ARRAY;
8940 } else {
8941 name = args[opti];
8942 opti++;
8943 newArgs = new String[args.length - opti];
8944 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8945 args.length - opti);
8946 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008947 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008948 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008949 }
8950 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008951 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8952 synchronized (this) {
8953 dumpOomLocked(fd, pw, args, opti, true);
8954 }
8955 return;
Marco Nelissen18cb2872011-11-15 11:19:53 -08008956 } else if ("provider".equals(cmd)) {
8957 String[] newArgs;
8958 String name;
8959 if (opti >= args.length) {
8960 name = null;
8961 newArgs = EMPTY_STRING_ARRAY;
8962 } else {
8963 name = args[opti];
8964 opti++;
8965 newArgs = new String[args.length - opti];
8966 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8967 }
8968 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8969 pw.println("No providers match: " + name);
8970 pw.println("Use -h for help.");
8971 }
8972 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008973 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8974 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008975 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008976 }
8977 return;
8978 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008979 String[] newArgs;
8980 String name;
8981 if (opti >= args.length) {
8982 name = null;
8983 newArgs = EMPTY_STRING_ARRAY;
8984 } else {
8985 name = args[opti];
8986 opti++;
8987 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008988 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8989 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008990 }
8991 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8992 pw.println("No services match: " + name);
8993 pw.println("Use -h for help.");
8994 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008995 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008996 } else if ("package".equals(cmd)) {
8997 String[] newArgs;
8998 if (opti >= args.length) {
8999 pw.println("package: no package name specified");
9000 pw.println("Use -h for help.");
9001 return;
9002 } else {
9003 dumpPackage = args[opti];
9004 opti++;
9005 newArgs = new String[args.length - opti];
9006 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9007 args.length - opti);
9008 args = newArgs;
9009 opti = 0;
9010 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009011 } else if ("services".equals(cmd) || "s".equals(cmd)) {
9012 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009013 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009014 }
9015 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07009016 } else {
9017 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009018 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9019 pw.println("Bad activity command, or no activities match: " + cmd);
9020 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009021 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009022 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009023 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009024 }
9025
9026 // No piece of data specified, dump everything.
9027 synchronized (this) {
9028 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009029 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009030 if (needSep) {
9031 pw.println(" ");
9032 }
9033 if (dumpAll) {
9034 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009035 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009036 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009037 if (needSep) {
9038 pw.println(" ");
9039 }
9040 if (dumpAll) {
9041 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009042 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009043 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009044 if (needSep) {
9045 pw.println(" ");
9046 }
9047 if (dumpAll) {
9048 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009049 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009050 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009051 if (needSep) {
9052 pw.println(" ");
9053 }
9054 if (dumpAll) {
9055 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009056 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009057 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009058 if (needSep) {
9059 pw.println(" ");
9060 }
9061 if (dumpAll) {
9062 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009063 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009064 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009065 }
9066 }
9067
9068 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009069 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009070 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9071 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009072 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
9073 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009074 pw.println(" ");
9075 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009076 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
9077 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009078 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009080 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009081 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009082 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009083 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009084 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009085 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009086 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009087 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009088 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009089 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009090 if (mMainStack.mGoingToSleepActivities.size() > 0) {
9091 pw.println(" ");
9092 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009093 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009094 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009095 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009096 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009097 pw.println(" ");
9098 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009099 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009100 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009102
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009103 pw.println(" ");
Dianne Hackborncbb722e2012-02-07 18:33:49 -08009104 if (mMainStack.mPausingActivities.size() > 0) {
9105 pw.println(" mPausingActivities: " + Arrays.toString(
9106 mMainStack.mPausingActivities.toArray()));
9107 }
9108 if (mMainStack.mInputPausedActivities.size() > 0) {
9109 pw.println(" mInputPausedActivities: " + Arrays.toString(
9110 mMainStack.mInputPausedActivities.toArray()));
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009111 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009112 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009113 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009114 if (dumpAll) {
9115 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9116 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009117 pw.println(" mDismissKeyguardOnNextActivity: "
9118 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009120
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009121 if (mRecentTasks.size() > 0) {
9122 pw.println();
9123 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009124
9125 final int N = mRecentTasks.size();
9126 for (int i=0; i<N; i++) {
9127 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009128 if (dumpPackage != null) {
9129 if (tr.realActivity == null ||
9130 !dumpPackage.equals(tr.realActivity)) {
9131 continue;
9132 }
9133 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009134 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
9135 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009136 if (dumpAll) {
9137 mRecentTasks.get(i).dump(pw, " ");
9138 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009139 }
9140 }
9141
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009142 if (dumpAll) {
9143 pw.println(" ");
9144 pw.println(" mCurTask: " + mCurTask);
9145 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009146
9147 return true;
9148 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009149
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009150 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009151 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009152 boolean needSep = false;
9153 int numPers = 0;
9154
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009155 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9156
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009157 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009158 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9159 final int NA = procs.size();
9160 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009161 ProcessRecord r = procs.valueAt(ia);
9162 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9163 continue;
9164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 if (!needSep) {
9166 pw.println(" All known processes:");
9167 needSep = true;
9168 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009169 pw.print(r.persistent ? " *PERS*" : " *APP*");
9170 pw.print(" UID "); pw.print(procs.keyAt(ia));
9171 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 r.dump(pw, " ");
9173 if (r.persistent) {
9174 numPers++;
9175 }
9176 }
9177 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009178 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08009179
9180 if (mIsolatedProcesses.size() > 0) {
9181 if (needSep) pw.println(" ");
9182 needSep = true;
9183 pw.println(" Isolated process list (sorted by uid):");
9184 for (int i=0; i<mIsolatedProcesses.size(); i++) {
9185 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9186 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9187 continue;
9188 }
9189 pw.println(String.format("%sIsolated #%2d: %s",
9190 " ", i, r.toString()));
9191 }
9192 }
9193
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009194 if (mLruProcesses.size() > 0) {
9195 if (needSep) pw.println(" ");
9196 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07009197 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009198 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009199 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009200 needSep = true;
9201 }
9202
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009203 if (dumpAll) {
9204 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009205 boolean printed = false;
9206 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9207 ProcessRecord r = mPidsSelfLocked.valueAt(i);
9208 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9209 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009210 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009211 if (!printed) {
9212 if (needSep) pw.println(" ");
9213 needSep = true;
9214 pw.println(" PID mappings:");
9215 printed = true;
9216 }
9217 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9218 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009219 }
9220 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009221 }
9222
9223 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009224 synchronized (mPidsSelfLocked) {
9225 boolean printed = false;
9226 for (int i=0; i<mForegroundProcesses.size(); i++) {
9227 ProcessRecord r = mPidsSelfLocked.get(
9228 mForegroundProcesses.valueAt(i).pid);
9229 if (dumpPackage != null && (r == null
9230 || !dumpPackage.equals(r.info.packageName))) {
9231 continue;
9232 }
9233 if (!printed) {
9234 if (needSep) pw.println(" ");
9235 needSep = true;
9236 pw.println(" Foreground Processes:");
9237 printed = true;
9238 }
9239 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9240 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009242 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009243 }
9244
9245 if (mPersistentStartingProcesses.size() > 0) {
9246 if (needSep) pw.println(" ");
9247 needSep = true;
9248 pw.println(" Persisent processes that are starting:");
9249 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009250 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009253 if (mRemovedProcesses.size() > 0) {
9254 if (needSep) pw.println(" ");
9255 needSep = true;
9256 pw.println(" Processes that are being removed:");
9257 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009258 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009259 }
9260
9261 if (mProcessesOnHold.size() > 0) {
9262 if (needSep) pw.println(" ");
9263 needSep = true;
9264 pw.println(" Processes that are on old until the system is ready:");
9265 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009266 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009269 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009270
9271 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009272 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009273 long now = SystemClock.uptimeMillis();
9274 for (Map.Entry<String, SparseArray<Long>> procs
9275 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009276 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009277 SparseArray<Long> uids = procs.getValue();
9278 final int N = uids.size();
9279 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009280 int puid = uids.keyAt(i);
9281 ProcessRecord r = mProcessNames.get(pname, puid);
9282 if (dumpPackage != null && (r == null
9283 || !dumpPackage.equals(r.info.packageName))) {
9284 continue;
9285 }
9286 if (!printed) {
9287 if (needSep) pw.println(" ");
9288 needSep = true;
9289 pw.println(" Time since processes crashed:");
9290 printed = true;
9291 }
9292 pw.print(" Process "); pw.print(pname);
9293 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009294 pw.print(": last crashed ");
9295 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009296 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009297 }
9298 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009300
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009301 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009302 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009303 for (Map.Entry<String, SparseArray<Long>> procs
9304 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009305 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009306 SparseArray<Long> uids = procs.getValue();
9307 final int N = uids.size();
9308 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009309 int puid = uids.keyAt(i);
9310 ProcessRecord r = mProcessNames.get(pname, puid);
9311 if (dumpPackage != null && (r == null
9312 || !dumpPackage.equals(r.info.packageName))) {
9313 continue;
9314 }
9315 if (!printed) {
9316 if (needSep) pw.println(" ");
9317 needSep = true;
9318 pw.println(" Bad processes:");
9319 }
9320 pw.print(" Bad process "); pw.print(pname);
9321 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009322 pw.print(": crashed at time ");
9323 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009324 }
9325 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009327
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009328 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009329 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009330 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009331 if (dumpAll) {
9332 StringBuilder sb = new StringBuilder(128);
9333 sb.append(" mPreviousProcessVisibleTime: ");
9334 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9335 pw.println(sb);
9336 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009337 if (mHeavyWeightProcess != null) {
9338 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9339 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009340 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009341 if (dumpAll) {
9342 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009343 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009344 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009345 for (Map.Entry<String, Integer> entry
9346 : mCompatModePackages.getPackages().entrySet()) {
9347 String pkg = entry.getKey();
9348 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009349 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9350 continue;
9351 }
9352 if (!printed) {
9353 pw.println(" mScreenCompatPackages:");
9354 printed = true;
9355 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009356 pw.print(" "); pw.print(pkg); pw.print(": ");
9357 pw.print(mode); pw.println();
9358 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009359 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009360 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009361 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9362 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9363 || mOrigWaitForDebugger) {
9364 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9365 + " mDebugTransient=" + mDebugTransient
9366 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9367 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009368 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9369 || mProfileFd != null) {
9370 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9371 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9372 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9373 + mAutoStopProfiler);
9374 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009375 if (mAlwaysFinishActivities || mController != null) {
9376 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9377 + " mController=" + mController);
9378 }
9379 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009380 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009382 + " mProcessesReady=" + mProcessesReady
9383 + " mSystemReady=" + mSystemReady);
9384 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009385 + " mBooted=" + mBooted
9386 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009387 pw.print(" mLastPowerCheckRealtime=");
9388 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9389 pw.println("");
9390 pw.print(" mLastPowerCheckUptime=");
9391 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9392 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009393 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9394 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009395 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009396 pw.println(" mNumServiceProcs=" + mNumServiceProcs
9397 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009399
9400 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 }
9402
Dianne Hackborn287952c2010-09-22 22:34:31 -07009403 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009404 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009405 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009406 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009407 long now = SystemClock.uptimeMillis();
9408 for (int i=0; i<mProcessesToGc.size(); i++) {
9409 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009410 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9411 continue;
9412 }
9413 if (!printed) {
9414 if (needSep) pw.println(" ");
9415 needSep = true;
9416 pw.println(" Processes that are waiting to GC:");
9417 printed = true;
9418 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009419 pw.print(" Process "); pw.println(proc);
9420 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9421 pw.print(", last gced=");
9422 pw.print(now-proc.lastRequestedGc);
9423 pw.print(" ms ago, last lowMem=");
9424 pw.print(now-proc.lastLowMemory);
9425 pw.println(" ms ago");
9426
9427 }
9428 }
9429 return needSep;
9430 }
9431
9432 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9433 int opti, boolean dumpAll) {
9434 boolean needSep = false;
9435
9436 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009437 if (needSep) pw.println(" ");
9438 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009439 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009440 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009441 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009442 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9443 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9444 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9445 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9446 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009447 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009448 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009449 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009450 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009451 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009452 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009453
9454 if (needSep) pw.println(" ");
9455 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009456 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009457 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009458 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009459 needSep = true;
9460 }
9461
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009462 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009463
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009464 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009465 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009466 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009467 if (mHeavyWeightProcess != null) {
9468 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9469 }
9470
9471 return true;
9472 }
9473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009474 /**
9475 * There are three ways to call this:
9476 * - no service specified: dump all the services
9477 * - a flattened component name that matched an existing service was specified as the
9478 * first arg: dump that one service
9479 * - the first arg isn't the flattened component name of an existing service:
9480 * dump all services whose component contains the first arg as a substring
9481 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009482 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9483 int opti, boolean dumpAll) {
9484 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009485
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009486 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009487 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009488 try {
9489 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9490 for (UserInfo user : users) {
9491 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9492 services.add(r1);
9493 }
9494 }
9495 } catch (RemoteException re) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009496 }
9497 }
9498 } else {
9499 ComponentName componentName = name != null
9500 ? ComponentName.unflattenFromString(name) : null;
9501 int objectId = 0;
9502 if (componentName == null) {
9503 // Not a '/' separated full component name; maybe an object ID?
9504 try {
9505 objectId = Integer.parseInt(name, 16);
9506 name = null;
9507 componentName = null;
9508 } catch (RuntimeException e) {
9509 }
9510 }
9511
9512 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009513 try {
9514 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9515 for (UserInfo user : users) {
9516 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9517 if (componentName != null) {
9518 if (r1.name.equals(componentName)) {
9519 services.add(r1);
9520 }
9521 } else if (name != null) {
9522 if (r1.name.flattenToString().contains(name)) {
9523 services.add(r1);
9524 }
9525 } else if (System.identityHashCode(r1) == objectId) {
9526 services.add(r1);
9527 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009528 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009529 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009530 } catch (RemoteException re) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 }
9532 }
9533 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009534
9535 if (services.size() <= 0) {
9536 return false;
9537 }
9538
9539 boolean needSep = false;
9540 for (int i=0; i<services.size(); i++) {
9541 if (needSep) {
9542 pw.println();
9543 }
9544 needSep = true;
9545 dumpService("", fd, pw, services.get(i), args, dumpAll);
9546 }
9547 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009548 }
9549
9550 /**
9551 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9552 * there is a thread associated with the service.
9553 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009554 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9555 final ServiceRecord r, String[] args, boolean dumpAll) {
9556 String innerPrefix = prefix + " ";
9557 synchronized (this) {
9558 pw.print(prefix); pw.print("SERVICE ");
9559 pw.print(r.shortName); pw.print(" ");
9560 pw.print(Integer.toHexString(System.identityHashCode(r)));
9561 pw.print(" pid=");
9562 if (r.app != null) pw.println(r.app.pid);
9563 else pw.println("(not running)");
9564 if (dumpAll) {
9565 r.dump(pw, innerPrefix);
9566 }
9567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009568 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009569 pw.print(prefix); pw.println(" Client:");
9570 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009571 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009572 TransferPipe tp = new TransferPipe();
9573 try {
9574 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9575 tp.setBufferPrefix(prefix + " ");
9576 tp.go(fd);
9577 } finally {
9578 tp.kill();
9579 }
9580 } catch (IOException e) {
9581 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009582 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009583 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009584 }
9585 }
9586 }
9587
Marco Nelissen18cb2872011-11-15 11:19:53 -08009588 /**
9589 * There are three ways to call this:
9590 * - no provider specified: dump all the providers
9591 * - a flattened component name that matched an existing provider was specified as the
9592 * first arg: dump that one provider
9593 * - the first arg isn't the flattened component name of an existing provider:
9594 * dump all providers whose component contains the first arg as a substring
9595 */
9596 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9597 int opti, boolean dumpAll) {
9598 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
9599
9600 if ("all".equals(name)) {
9601 synchronized (this) {
9602 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
9603 providers.add(r1);
9604 }
9605 }
9606 } else {
9607 ComponentName componentName = name != null
9608 ? ComponentName.unflattenFromString(name) : null;
9609 int objectId = 0;
9610 if (componentName == null) {
9611 // Not a '/' separated full component name; maybe an object ID?
9612 try {
9613 objectId = Integer.parseInt(name, 16);
9614 name = null;
9615 componentName = null;
9616 } catch (RuntimeException e) {
9617 }
9618 }
9619
9620 synchronized (this) {
9621 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
9622 if (componentName != null) {
9623 if (r1.name.equals(componentName)) {
9624 providers.add(r1);
9625 }
9626 } else if (name != null) {
9627 if (r1.name.flattenToString().contains(name)) {
9628 providers.add(r1);
9629 }
9630 } else if (System.identityHashCode(r1) == objectId) {
9631 providers.add(r1);
9632 }
9633 }
9634 }
9635 }
9636
9637 if (providers.size() <= 0) {
9638 return false;
9639 }
9640
9641 boolean needSep = false;
9642 for (int i=0; i<providers.size(); i++) {
9643 if (needSep) {
9644 pw.println();
9645 }
9646 needSep = true;
9647 dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
9648 }
9649 return true;
9650 }
9651
9652 /**
9653 * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
9654 * there is a thread associated with the provider.
9655 */
9656 private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
9657 final ContentProviderRecord r, String[] args, boolean dumpAll) {
9658 String innerPrefix = prefix + " ";
9659 synchronized (this) {
9660 pw.print(prefix); pw.print("PROVIDER ");
9661 pw.print(r);
9662 pw.print(" pid=");
9663 if (r.proc != null) pw.println(r.proc.pid);
9664 else pw.println("(not running)");
9665 if (dumpAll) {
9666 r.dump(pw, innerPrefix);
9667 }
9668 }
9669 if (r.proc != null && r.proc.thread != null) {
9670 pw.println(" Client:");
9671 pw.flush();
9672 try {
9673 TransferPipe tp = new TransferPipe();
9674 try {
9675 r.proc.thread.dumpProvider(
9676 tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
9677 tp.setBufferPrefix(" ");
9678 // Short timeout, since blocking here can
9679 // deadlock with the application.
9680 tp.go(fd, 2000);
9681 } finally {
9682 tp.kill();
9683 }
9684 } catch (IOException ex) {
9685 pw.println(" Failure while dumping the provider: " + ex);
9686 } catch (RemoteException ex) {
9687 pw.println(" Got a RemoteException while dumping the service");
9688 }
9689 }
9690 }
9691
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009692 static class ItemMatcher {
9693 ArrayList<ComponentName> components;
9694 ArrayList<String> strings;
9695 ArrayList<Integer> objects;
9696 boolean all;
9697
9698 ItemMatcher() {
9699 all = true;
9700 }
9701
9702 void build(String name) {
9703 ComponentName componentName = ComponentName.unflattenFromString(name);
9704 if (componentName != null) {
9705 if (components == null) {
9706 components = new ArrayList<ComponentName>();
9707 }
9708 components.add(componentName);
9709 all = false;
9710 } else {
9711 int objectId = 0;
9712 // Not a '/' separated full component name; maybe an object ID?
9713 try {
9714 objectId = Integer.parseInt(name, 16);
9715 if (objects == null) {
9716 objects = new ArrayList<Integer>();
9717 }
9718 objects.add(objectId);
9719 all = false;
9720 } catch (RuntimeException e) {
9721 // Not an integer; just do string match.
9722 if (strings == null) {
9723 strings = new ArrayList<String>();
9724 }
9725 strings.add(name);
9726 all = false;
9727 }
9728 }
9729 }
9730
9731 int build(String[] args, int opti) {
9732 for (; opti<args.length; opti++) {
9733 String name = args[opti];
9734 if ("--".equals(name)) {
9735 return opti+1;
9736 }
9737 build(name);
9738 }
9739 return opti;
9740 }
9741
9742 boolean match(Object object, ComponentName comp) {
9743 if (all) {
9744 return true;
9745 }
9746 if (components != null) {
9747 for (int i=0; i<components.size(); i++) {
9748 if (components.get(i).equals(comp)) {
9749 return true;
9750 }
9751 }
9752 }
9753 if (objects != null) {
9754 for (int i=0; i<objects.size(); i++) {
9755 if (System.identityHashCode(object) == objects.get(i)) {
9756 return true;
9757 }
9758 }
9759 }
9760 if (strings != null) {
9761 String flat = comp.flattenToString();
9762 for (int i=0; i<strings.size(); i++) {
9763 if (flat.contains(strings.get(i))) {
9764 return true;
9765 }
9766 }
9767 }
9768 return false;
9769 }
9770 }
9771
Dianne Hackborn625ac272010-09-17 18:29:22 -07009772 /**
9773 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009774 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009775 * - the cmd arg isn't the flattened component name of an existing activity:
9776 * dump all activity whose component contains the cmd as a substring
9777 * - A hex number of the ActivityRecord object instance.
9778 */
9779 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9780 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009781 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009782
9783 if ("all".equals(name)) {
9784 synchronized (this) {
9785 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009786 activities.add(r1);
9787 }
9788 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009789 } else if ("top".equals(name)) {
9790 synchronized (this) {
9791 final int N = mMainStack.mHistory.size();
9792 if (N > 0) {
9793 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9794 }
9795 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009796 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009797 ItemMatcher matcher = new ItemMatcher();
9798 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009799
9800 synchronized (this) {
9801 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009802 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009803 activities.add(r1);
9804 }
9805 }
9806 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009807 }
9808
9809 if (activities.size() <= 0) {
9810 return false;
9811 }
9812
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009813 String[] newArgs = new String[args.length - opti];
9814 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9815
Dianne Hackborn30d71892010-12-11 10:37:55 -08009816 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009817 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009818 for (int i=activities.size()-1; i>=0; i--) {
9819 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009820 if (needSep) {
9821 pw.println();
9822 }
9823 needSep = true;
9824 synchronized (this) {
9825 if (lastTask != r.task) {
9826 lastTask = r.task;
9827 pw.print("TASK "); pw.print(lastTask.affinity);
9828 pw.print(" id="); pw.println(lastTask.taskId);
9829 if (dumpAll) {
9830 lastTask.dump(pw, " ");
9831 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009832 }
9833 }
9834 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009835 }
9836 return true;
9837 }
9838
9839 /**
9840 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9841 * there is a thread associated with the activity.
9842 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009843 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009844 final ActivityRecord r, String[] args, boolean dumpAll) {
9845 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009846 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009847 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9848 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9849 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009850 if (r.app != null) pw.println(r.app.pid);
9851 else pw.println("(not running)");
9852 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009853 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009854 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009855 }
9856 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009857 // flush anything that is already in the PrintWriter since the thread is going
9858 // to write to the file descriptor directly
9859 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009860 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009861 TransferPipe tp = new TransferPipe();
9862 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009863 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9864 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009865 tp.go(fd);
9866 } finally {
9867 tp.kill();
9868 }
9869 } catch (IOException e) {
9870 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009871 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009872 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009873 }
9874 }
9875 }
9876
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009877 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009878 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009879 boolean needSep = false;
9880
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009881 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009882 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009883 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009884 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009885 Iterator it = mRegisteredReceivers.values().iterator();
9886 while (it.hasNext()) {
9887 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009888 if (dumpPackage != null && (r.app == null ||
9889 !dumpPackage.equals(r.app.info.packageName))) {
9890 continue;
9891 }
9892 if (!printed) {
9893 pw.println(" Registered Receivers:");
9894 needSep = true;
9895 printed = true;
9896 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009897 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 r.dump(pw, " ");
9899 }
9900 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009901
9902 if (mReceiverResolver.dump(pw, needSep ?
9903 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9904 " ", dumpPackage, false)) {
9905 needSep = true;
9906 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009907 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009908
9909 for (BroadcastQueue q : mBroadcastQueues) {
9910 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009913 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009914
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009915 if (mStickyBroadcasts != null && dumpPackage == null) {
9916 if (needSep) {
9917 pw.println();
9918 }
9919 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009920 pw.println(" Sticky broadcasts:");
9921 StringBuilder sb = new StringBuilder(128);
9922 for (Map.Entry<String, ArrayList<Intent>> ent
9923 : mStickyBroadcasts.entrySet()) {
9924 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009925 if (dumpAll) {
9926 pw.println(":");
9927 ArrayList<Intent> intents = ent.getValue();
9928 final int N = intents.size();
9929 for (int i=0; i<N; i++) {
9930 sb.setLength(0);
9931 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009932 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009933 pw.println(sb.toString());
9934 Bundle bundle = intents.get(i).getExtras();
9935 if (bundle != null) {
9936 pw.print(" ");
9937 pw.println(bundle.toString());
9938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009940 } else {
9941 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009942 }
9943 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009944 needSep = true;
9945 }
9946
9947 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009948 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009949 for (BroadcastQueue queue : mBroadcastQueues) {
9950 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9951 + queue.mBroadcastsScheduled);
9952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009953 pw.println(" mHandler:");
9954 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009955 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009957
9958 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009959 }
9960
Marco Nelissen18cb2872011-11-15 11:19:53 -08009961 /**
9962 * Prints a list of ServiceRecords (dumpsys activity services)
9963 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009964 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009965 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009966 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009967
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009968 ItemMatcher matcher = new ItemMatcher();
9969 matcher.build(args, opti);
9970
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009971 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009972 try {
9973 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9974 for (UserInfo user : users) {
9975 if (mServiceMap.getAllServices(user.id).size() > 0) {
9976 boolean printed = false;
9977 long nowReal = SystemClock.elapsedRealtime();
9978 Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9979 user.id).iterator();
9980 needSep = false;
9981 while (it.hasNext()) {
9982 ServiceRecord r = it.next();
9983 if (!matcher.match(r, r.name)) {
9984 continue;
9985 }
9986 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9987 continue;
9988 }
9989 if (!printed) {
9990 pw.println(" Active services:");
9991 printed = true;
9992 }
9993 if (needSep) {
9994 pw.println();
9995 }
9996 pw.print(" * ");
9997 pw.println(r);
9998 if (dumpAll) {
9999 r.dump(pw, " ");
10000 needSep = true;
10001 } else {
10002 pw.print(" app=");
10003 pw.println(r.app);
10004 pw.print(" created=");
10005 TimeUtils.formatDuration(r.createTime, nowReal, pw);
10006 pw.print(" started=");
10007 pw.print(r.startRequested);
10008 pw.print(" connections=");
10009 pw.println(r.connections.size());
10010 if (r.connections.size() > 0) {
10011 pw.println(" Connections:");
10012 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
10013 for (int i = 0; i < clist.size(); i++) {
10014 ConnectionRecord conn = clist.get(i);
10015 pw.print(" ");
10016 pw.print(conn.binding.intent.intent.getIntent()
10017 .toShortString(false, false, false));
10018 pw.print(" -> ");
10019 ProcessRecord proc = conn.binding.client;
10020 pw.println(proc != null ? proc.toShortString() : "null");
10021 }
10022 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -080010023 }
10024 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010025 if (dumpClient && r.app != null && r.app.thread != null) {
10026 pw.println(" Client:");
10027 pw.flush();
10028 try {
10029 TransferPipe tp = new TransferPipe();
10030 try {
10031 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
10032 r, args);
10033 tp.setBufferPrefix(" ");
10034 // Short timeout, since blocking here can
10035 // deadlock with the application.
10036 tp.go(fd, 2000);
10037 } finally {
10038 tp.kill();
10039 }
10040 } catch (IOException e) {
10041 pw.println(" Failure while dumping the service: " + e);
10042 } catch (RemoteException e) {
10043 pw.println(" Got a RemoteException while dumping the service");
10044 }
10045 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010046 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010047 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010048 needSep = printed;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010050 }
Amith Yamasani742a6712011-05-04 14:49:28 -070010051 } catch (RemoteException re) {
10052
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010055 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010056 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010057 for (int i=0; i<mPendingServices.size(); i++) {
10058 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010059 if (!matcher.match(r, r.name)) {
10060 continue;
10061 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010062 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10063 continue;
10064 }
10065 if (!printed) {
10066 if (needSep) pw.println(" ");
10067 needSep = true;
10068 pw.println(" Pending services:");
10069 printed = true;
10070 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010071 pw.print(" * Pending "); pw.println(r);
10072 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010074 needSep = true;
10075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010076
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010077 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010078 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010079 for (int i=0; i<mRestartingServices.size(); i++) {
10080 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010081 if (!matcher.match(r, r.name)) {
10082 continue;
10083 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010084 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10085 continue;
10086 }
10087 if (!printed) {
10088 if (needSep) pw.println(" ");
10089 needSep = true;
10090 pw.println(" Restarting services:");
10091 printed = true;
10092 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010093 pw.print(" * Restarting "); pw.println(r);
10094 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010095 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010096 needSep = true;
10097 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010099 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010100 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010101 for (int i=0; i<mStoppingServices.size(); i++) {
10102 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010103 if (!matcher.match(r, r.name)) {
10104 continue;
10105 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010106 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
10107 continue;
10108 }
10109 if (!printed) {
10110 if (needSep) pw.println(" ");
10111 needSep = true;
10112 pw.println(" Stopping services:");
10113 printed = true;
10114 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010115 pw.print(" * Stopping "); pw.println(r);
10116 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010117 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010118 needSep = true;
10119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010120
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010121 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010122 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010123 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010124 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 = mServiceConnections.values().iterator();
10126 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010127 ArrayList<ConnectionRecord> r = it.next();
10128 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010129 ConnectionRecord cr = r.get(i);
10130 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
10131 continue;
10132 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010133 if (dumpPackage != null && (cr.binding.client == null
10134 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
10135 continue;
10136 }
10137 if (!printed) {
10138 if (needSep) pw.println(" ");
10139 needSep = true;
10140 pw.println(" Connection bindings to services:");
10141 printed = true;
10142 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010143 pw.print(" * "); pw.println(cr);
10144 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010146 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010147 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010148 }
10149 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010150
10151 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010152 }
10153
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010154 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010155 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010156 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010157
Dianne Hackborn1c9b2602011-08-19 14:08:43 -070010158 ItemMatcher matcher = new ItemMatcher();
10159 matcher.build(args, opti);
10160
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010161 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -070010162
10163 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010164
10165 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010166 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010167 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010168 ContentProviderRecord r = mLaunchingProviders.get(i);
10169 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
10170 continue;
10171 }
10172 if (!printed) {
10173 if (needSep) pw.println(" ");
10174 needSep = true;
10175 pw.println(" Launching content providers:");
10176 printed = true;
10177 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010178 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010179 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010180 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010181 }
10182
10183 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010184 if (needSep) pw.println();
10185 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010186 pw.println("Granted Uri Permissions:");
10187 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
10188 int uid = mGrantedUriPermissions.keyAt(i);
10189 HashMap<Uri, UriPermission> perms
10190 = mGrantedUriPermissions.valueAt(i);
10191 pw.print(" * UID "); pw.print(uid);
10192 pw.println(" holds:");
10193 for (UriPermission perm : perms.values()) {
10194 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010195 if (dumpAll) {
10196 perm.dump(pw, " ");
10197 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010198 }
10199 }
10200 needSep = true;
10201 }
10202
10203 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010204 }
10205
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010206 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010207 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010208 boolean needSep = false;
10209
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010210 if (mIntentSenderRecords.size() > 0) {
10211 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010212 Iterator<WeakReference<PendingIntentRecord>> it
10213 = mIntentSenderRecords.values().iterator();
10214 while (it.hasNext()) {
10215 WeakReference<PendingIntentRecord> ref = it.next();
10216 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010217 if (dumpPackage != null && (rec == null
10218 || !dumpPackage.equals(rec.key.packageName))) {
10219 continue;
10220 }
10221 if (!printed) {
10222 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
10223 printed = true;
10224 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010225 needSep = true;
10226 if (rec != null) {
10227 pw.print(" * "); pw.println(rec);
10228 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010229 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010230 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010231 } else {
10232 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010233 }
10234 }
10235 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -080010236
10237 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010238 }
10239
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010240 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010241 String prefix, String label, boolean complete, boolean brief, boolean client,
10242 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010243 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010244 boolean needNL = false;
10245 final String innerPrefix = prefix + " ";
10246 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010248 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010249 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
10250 continue;
10251 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -070010252 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010253 if (needNL) {
10254 pw.println(" ");
10255 needNL = false;
10256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010257 if (lastTask != r.task) {
10258 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010259 pw.print(prefix);
10260 pw.print(full ? "* " : " ");
10261 pw.println(lastTask);
10262 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010263 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010264 } else if (complete) {
10265 // Complete + brief == give a summary. Isn't that obvious?!?
10266 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010267 pw.print(prefix); pw.print(" ");
10268 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010269 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010272 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
10273 pw.print(" #"); pw.print(i); pw.print(": ");
10274 pw.println(r);
10275 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010276 r.dump(pw, innerPrefix);
10277 } else if (complete) {
10278 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010279 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010280 if (r.app != null) {
10281 pw.print(innerPrefix); pw.println(r.app);
10282 }
10283 }
10284 if (client && r.app != null && r.app.thread != null) {
10285 // flush anything that is already in the PrintWriter since the thread is going
10286 // to write to the file descriptor directly
10287 pw.flush();
10288 try {
10289 TransferPipe tp = new TransferPipe();
10290 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -080010291 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10292 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010293 // Short timeout, since blocking here can
10294 // deadlock with the application.
10295 tp.go(fd, 2000);
10296 } finally {
10297 tp.kill();
10298 }
10299 } catch (IOException e) {
10300 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10301 } catch (RemoteException e) {
10302 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10303 }
10304 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010306 }
10307 }
10308
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010309 private static String buildOomTag(String prefix, String space, int val, int base) {
10310 if (val == base) {
10311 if (space == null) return prefix;
10312 return prefix + " ";
10313 }
10314 return prefix + "+" + Integer.toString(val-base);
10315 }
10316
10317 private static final int dumpProcessList(PrintWriter pw,
10318 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010319 String prefix, String normalLabel, String persistentLabel,
10320 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010321 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010322 final int N = list.size()-1;
10323 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010324 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010325 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10326 continue;
10327 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010328 pw.println(String.format("%s%s #%2d: %s",
10329 prefix, (r.persistent ? persistentLabel : normalLabel),
10330 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010331 if (r.persistent) {
10332 numPers++;
10333 }
10334 }
10335 return numPers;
10336 }
10337
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010338 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -070010339 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -070010340 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010341 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010342
Dianne Hackborn905577f2011-09-07 18:31:28 -070010343 ArrayList<Pair<ProcessRecord, Integer>> list
10344 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10345 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010346 ProcessRecord r = origList.get(i);
10347 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10348 continue;
10349 }
Dianne Hackborn905577f2011-09-07 18:31:28 -070010350 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10351 }
10352
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010353 if (list.size() <= 0) {
10354 return false;
10355 }
10356
Dianne Hackborn905577f2011-09-07 18:31:28 -070010357 Comparator<Pair<ProcessRecord, Integer>> comparator
10358 = new Comparator<Pair<ProcessRecord, Integer>>() {
10359 @Override
10360 public int compare(Pair<ProcessRecord, Integer> object1,
10361 Pair<ProcessRecord, Integer> object2) {
10362 if (object1.first.setAdj != object2.first.setAdj) {
10363 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10364 }
10365 if (object1.second.intValue() != object2.second.intValue()) {
10366 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10367 }
10368 return 0;
10369 }
10370 };
10371
10372 Collections.sort(list, comparator);
10373
Dianne Hackborn287952c2010-09-22 22:34:31 -070010374 final long curRealtime = SystemClock.elapsedRealtime();
10375 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10376 final long curUptime = SystemClock.uptimeMillis();
10377 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10378
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010379 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070010380 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010381 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010382 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070010383 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010384 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10385 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010386 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10387 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010388 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10389 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010390 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10391 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010392 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010393 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010394 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10395 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10396 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10397 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10398 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10399 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10400 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10401 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010402 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10403 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010404 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10405 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010406 } else {
10407 oomAdj = Integer.toString(r.setAdj);
10408 }
10409 String schedGroup;
10410 switch (r.setSchedGroup) {
10411 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10412 schedGroup = "B";
10413 break;
10414 case Process.THREAD_GROUP_DEFAULT:
10415 schedGroup = "F";
10416 break;
10417 default:
10418 schedGroup = Integer.toString(r.setSchedGroup);
10419 break;
10420 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010421 String foreground;
10422 if (r.foregroundActivities) {
10423 foreground = "A";
10424 } else if (r.foregroundServices) {
10425 foreground = "S";
10426 } else {
10427 foreground = " ";
10428 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010429 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -070010430 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010431 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10432 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -070010433 if (r.adjSource != null || r.adjTarget != null) {
10434 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010435 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070010436 if (r.adjTarget instanceof ComponentName) {
10437 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10438 } else if (r.adjTarget != null) {
10439 pw.print(r.adjTarget.toString());
10440 } else {
10441 pw.print("{null}");
10442 }
10443 pw.print("<=");
10444 if (r.adjSource instanceof ProcessRecord) {
10445 pw.print("Proc{");
10446 pw.print(((ProcessRecord)r.adjSource).toShortString());
10447 pw.println("}");
10448 } else if (r.adjSource != null) {
10449 pw.println(r.adjSource.toString());
10450 } else {
10451 pw.println("{null}");
10452 }
10453 }
10454 if (inclDetails) {
10455 pw.print(prefix);
10456 pw.print(" ");
10457 pw.print("oom: max="); pw.print(r.maxAdj);
10458 pw.print(" hidden="); pw.print(r.hiddenAdj);
10459 pw.print(" curRaw="); pw.print(r.curRawAdj);
10460 pw.print(" setRaw="); pw.print(r.setRawAdj);
10461 pw.print(" cur="); pw.print(r.curAdj);
10462 pw.print(" set="); pw.println(r.setAdj);
10463 pw.print(prefix);
10464 pw.print(" ");
10465 pw.print("keeping="); pw.print(r.keeping);
10466 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010467 pw.print(" empty="); pw.print(r.empty);
10468 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010469
10470 if (!r.keeping) {
10471 if (r.lastWakeTime != 0) {
10472 long wtime;
10473 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10474 synchronized (stats) {
10475 wtime = stats.getProcessWakeTime(r.info.uid,
10476 r.pid, curRealtime);
10477 }
10478 long timeUsed = wtime - r.lastWakeTime;
10479 pw.print(prefix);
10480 pw.print(" ");
10481 pw.print("keep awake over ");
10482 TimeUtils.formatDuration(realtimeSince, pw);
10483 pw.print(" used ");
10484 TimeUtils.formatDuration(timeUsed, pw);
10485 pw.print(" (");
10486 pw.print((timeUsed*100)/realtimeSince);
10487 pw.println("%)");
10488 }
10489 if (r.lastCpuTime != 0) {
10490 long timeUsed = r.curCpuTime - r.lastCpuTime;
10491 pw.print(prefix);
10492 pw.print(" ");
10493 pw.print("run cpu over ");
10494 TimeUtils.formatDuration(uptimeSince, pw);
10495 pw.print(" used ");
10496 TimeUtils.formatDuration(timeUsed, pw);
10497 pw.print(" (");
10498 pw.print((timeUsed*100)/uptimeSince);
10499 pw.println("%)");
10500 }
10501 }
10502 }
10503 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010504 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010505 }
10506
Dianne Hackbornb437e092011-08-05 17:50:29 -070010507 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010508 ArrayList<ProcessRecord> procs;
10509 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010510 if (args != null && args.length > start
10511 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010512 procs = new ArrayList<ProcessRecord>();
10513 int pid = -1;
10514 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010515 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010516 } catch (NumberFormatException e) {
10517
10518 }
10519 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10520 ProcessRecord proc = mLruProcesses.get(i);
10521 if (proc.pid == pid) {
10522 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010523 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010524 procs.add(proc);
10525 }
10526 }
10527 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010528 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010529 return null;
10530 }
10531 } else {
10532 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10533 }
10534 }
10535 return procs;
10536 }
10537
10538 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10539 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010540 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010541 if (procs == null) {
10542 return;
10543 }
10544
10545 long uptime = SystemClock.uptimeMillis();
10546 long realtime = SystemClock.elapsedRealtime();
10547 pw.println("Applications Graphics Acceleration Info:");
10548 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10549
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010550 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10551 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010552 if (r.thread != null) {
10553 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10554 pw.flush();
10555 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010556 TransferPipe tp = new TransferPipe();
10557 try {
10558 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10559 tp.go(fd);
10560 } finally {
10561 tp.kill();
10562 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010563 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010564 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010565 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -070010566 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010567 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010568 pw.flush();
10569 }
10570 }
10571 }
Chet Haase9c1e23b2011-03-24 10:51:31 -070010572 }
10573
Jeff Brown6754ba22011-12-14 20:20:01 -080010574 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10575 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10576 if (procs == null) {
10577 return;
10578 }
10579
10580 pw.println("Applications Database Info:");
10581
10582 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10583 ProcessRecord r = procs.get(i);
10584 if (r.thread != null) {
10585 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10586 pw.flush();
10587 try {
10588 TransferPipe tp = new TransferPipe();
10589 try {
10590 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10591 tp.go(fd);
10592 } finally {
10593 tp.kill();
10594 }
10595 } catch (IOException e) {
10596 pw.println("Failure while dumping the app: " + r);
10597 pw.flush();
10598 } catch (RemoteException e) {
10599 pw.println("Got a RemoteException while dumping the app " + r);
10600 pw.flush();
10601 }
10602 }
10603 }
10604 }
10605
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010606 final static class MemItem {
10607 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010608 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010609 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010610 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010611 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010612
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010613 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010614 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010615 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010616 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010617 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010618 }
10619 }
10620
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010621 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010622 boolean sort) {
10623 if (sort) {
10624 Collections.sort(items, new Comparator<MemItem>() {
10625 @Override
10626 public int compare(MemItem lhs, MemItem rhs) {
10627 if (lhs.pss < rhs.pss) {
10628 return 1;
10629 } else if (lhs.pss > rhs.pss) {
10630 return -1;
10631 }
10632 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010633 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010634 });
10635 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010636
10637 for (int i=0; i<items.size(); i++) {
10638 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010639 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010640 if (mi.subitems != null) {
10641 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10642 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010643 }
10644 }
10645
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010646 // These are in KB.
10647 static final long[] DUMP_MEM_BUCKETS = new long[] {
10648 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10649 120*1024, 160*1024, 200*1024,
10650 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10651 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10652 };
10653
Dianne Hackborn672342c2011-11-29 11:29:02 -080010654 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10655 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010656 int start = label.lastIndexOf('.');
10657 if (start >= 0) start++;
10658 else start = 0;
10659 int end = label.length();
10660 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10661 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10662 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10663 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010664 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010665 out.append(label, start, end);
10666 return;
10667 }
10668 }
10669 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010670 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010671 out.append(label, start, end);
10672 }
10673
10674 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10675 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10676 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10677 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10678 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10679 };
10680 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10681 "System", "Persistent", "Foreground",
10682 "Visible", "Perceptible", "Heavy Weight",
10683 "Backup", "A Services", "Home", "Previous",
10684 "B Services", "Background"
10685 };
10686
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010687 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010688 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010689 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010690 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010691 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010692
10693 int opti = 0;
10694 while (opti < args.length) {
10695 String opt = args[opti];
10696 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10697 break;
10698 }
10699 opti++;
10700 if ("-a".equals(opt)) {
10701 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010702 } else if ("--oom".equals(opt)) {
10703 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010704 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010705 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010706 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010707 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010708 pw.println("If [process] is specified it can be the name or ");
10709 pw.println("pid of a specific process to dump.");
10710 return;
10711 } else {
10712 pw.println("Unknown argument: " + opt + "; use -h for help");
10713 }
10714 }
10715
10716 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010717 if (procs == null) {
10718 return;
10719 }
10720
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010721 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010722 long uptime = SystemClock.uptimeMillis();
10723 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010724
10725 if (procs.size() == 1 || isCheckinRequest) {
10726 dumpAll = true;
10727 }
10728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010729 if (isCheckinRequest) {
10730 // short checkin version
10731 pw.println(uptime + "," + realtime);
10732 pw.flush();
10733 } else {
10734 pw.println("Applications Memory Usage (kB):");
10735 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10736 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010737
Dianne Hackbornb437e092011-08-05 17:50:29 -070010738 String[] innerArgs = new String[args.length-opti];
10739 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10740
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010741 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10742 long nativePss=0, dalvikPss=0, otherPss=0;
10743 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10744
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010745 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10746 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10747 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010748
10749 long totalPss = 0;
10750
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010751 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10752 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010753 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010754 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010755 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10756 pw.flush();
10757 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010758 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010759 if (dumpAll) {
10760 try {
10761 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10762 } catch (RemoteException e) {
10763 if (!isCheckinRequest) {
10764 pw.println("Got RemoteException!");
10765 pw.flush();
10766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010768 } else {
10769 mi = new Debug.MemoryInfo();
10770 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010771 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010772
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010773 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010774 long myTotalPss = mi.getTotalPss();
10775 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010776 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010777 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010778 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010779
10780 nativePss += mi.nativePss;
10781 dalvikPss += mi.dalvikPss;
10782 otherPss += mi.otherPss;
10783 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10784 long mem = mi.getOtherPss(j);
10785 miscPss[j] += mem;
10786 otherPss -= mem;
10787 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010788
10789 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010790 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10791 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010792 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010793 if (oomProcs[oomIndex] == null) {
10794 oomProcs[oomIndex] = new ArrayList<MemItem>();
10795 }
10796 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010797 break;
10798 }
10799 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010801 }
10802 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010803
10804 if (!isCheckinRequest && procs.size() > 1) {
10805 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10806
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010807 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10808 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10809 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010810 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010811 String label = Debug.MemoryInfo.getOtherLabel(j);
10812 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010813 }
10814
Dianne Hackbornb437e092011-08-05 17:50:29 -070010815 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10816 for (int j=0; j<oomPss.length; j++) {
10817 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010818 String label = DUMP_MEM_OOM_LABEL[j];
10819 MemItem item = new MemItem(label, label, oomPss[j],
10820 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010821 item.subitems = oomProcs[j];
10822 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010823 }
10824 }
10825
Dianne Hackborn672342c2011-11-29 11:29:02 -080010826 if (outTag != null || outStack != null) {
10827 if (outTag != null) {
10828 appendMemBucket(outTag, totalPss, "total", false);
10829 }
10830 if (outStack != null) {
10831 appendMemBucket(outStack, totalPss, "total", true);
10832 }
10833 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010834 for (int i=0; i<oomMems.size(); i++) {
10835 MemItem miCat = oomMems.get(i);
10836 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10837 continue;
10838 }
10839 if (miCat.id < ProcessList.SERVICE_ADJ
10840 || miCat.id == ProcessList.HOME_APP_ADJ
10841 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010842 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10843 outTag.append(" / ");
10844 }
10845 if (outStack != null) {
10846 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10847 if (firstLine) {
10848 outStack.append(":");
10849 firstLine = false;
10850 }
10851 outStack.append("\n\t at ");
10852 } else {
10853 outStack.append("$");
10854 }
10855 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010856 for (int j=0; j<miCat.subitems.size(); j++) {
10857 MemItem mi = miCat.subitems.get(j);
10858 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010859 if (outTag != null) {
10860 outTag.append(" ");
10861 }
10862 if (outStack != null) {
10863 outStack.append("$");
10864 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010865 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010866 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10867 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10868 }
10869 if (outStack != null) {
10870 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10871 }
10872 }
10873 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10874 outStack.append("(");
10875 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10876 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10877 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10878 outStack.append(":");
10879 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10880 }
10881 }
10882 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010883 }
10884 }
10885 }
10886 }
10887
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010888 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010889 pw.println();
10890 pw.println("Total PSS by process:");
10891 dumpMemItems(pw, " ", procMems, true);
10892 pw.println();
10893 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010894 pw.println("Total PSS by OOM adjustment:");
10895 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010896 if (!oomOnly) {
10897 PrintWriter out = categoryPw != null ? categoryPw : pw;
10898 out.println();
10899 out.println("Total PSS by category:");
10900 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010901 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010902 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010903 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 }
10906
10907 /**
10908 * Searches array of arguments for the specified string
10909 * @param args array of argument strings
10910 * @param value value to search for
10911 * @return true if the value is contained in the array
10912 */
10913 private static boolean scanArgs(String[] args, String value) {
10914 if (args != null) {
10915 for (String arg : args) {
10916 if (value.equals(arg)) {
10917 return true;
10918 }
10919 }
10920 }
10921 return false;
10922 }
10923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010924 private final void killServicesLocked(ProcessRecord app,
10925 boolean allowRestart) {
10926 // Report disconnected services.
10927 if (false) {
10928 // XXX we are letting the client link to the service for
10929 // death notifications.
10930 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010931 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010932 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010933 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010934 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010935 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010936 = r.connections.values().iterator();
10937 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010938 ArrayList<ConnectionRecord> cl = jt.next();
10939 for (int i=0; i<cl.size(); i++) {
10940 ConnectionRecord c = cl.get(i);
10941 if (c.binding.client != app) {
10942 try {
10943 //c.conn.connected(r.className, null);
10944 } catch (Exception e) {
10945 // todo: this should be asynchronous!
10946 Slog.w(TAG, "Exception thrown disconnected servce "
10947 + r.shortName
10948 + " from app " + app.processName, e);
10949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010950 }
10951 }
10952 }
10953 }
10954 }
10955 }
10956 }
10957
10958 // Clean up any connections this application has to other services.
10959 if (app.connections.size() > 0) {
10960 Iterator<ConnectionRecord> it = app.connections.iterator();
10961 while (it.hasNext()) {
10962 ConnectionRecord r = it.next();
10963 removeConnectionLocked(r, app, null);
10964 }
10965 }
10966 app.connections.clear();
10967
10968 if (app.services.size() != 0) {
10969 // Any services running in the application need to be placed
10970 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010971 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010973 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 synchronized (sr.stats.getBatteryStats()) {
10975 sr.stats.stopLaunchedLocked();
10976 }
10977 sr.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010978 sr.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010980 if (mStoppingServices.remove(sr)) {
10981 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10982 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010983
10984 boolean hasClients = sr.bindings.size() > 0;
10985 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010986 Iterator<IntentBindRecord> bindings
10987 = sr.bindings.values().iterator();
10988 while (bindings.hasNext()) {
10989 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010990 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010991 + ": shouldUnbind=" + b.hasBound);
10992 b.binder = null;
10993 b.requested = b.received = b.hasBound = false;
10994 }
10995 }
10996
Dianne Hackborn070783f2010-12-29 16:46:28 -080010997 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10998 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010999 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011000 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011001 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011002 sr.crashCount, sr.shortName, app.pid);
11003 bringDownServiceLocked(sr, true);
11004 } else if (!allowRestart) {
11005 bringDownServiceLocked(sr, true);
11006 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011007 boolean canceled = scheduleServiceRestartLocked(sr, true);
11008
11009 // Should the service remain running? Note that in the
11010 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011011 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011012 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
11013 if (sr.pendingStarts.size() == 0) {
11014 sr.startRequested = false;
11015 if (!hasClients) {
11016 // Whoops, no reason to restart!
11017 bringDownServiceLocked(sr, true);
11018 }
11019 }
11020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011021 }
11022 }
11023
11024 if (!allowRestart) {
11025 app.services.clear();
11026 }
11027 }
11028
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011029 // Make sure we have no more records on the stopping list.
11030 int i = mStoppingServices.size();
11031 while (i > 0) {
11032 i--;
11033 ServiceRecord sr = mStoppingServices.get(i);
11034 if (sr.app == app) {
11035 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011036 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011037 }
11038 }
11039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011040 app.executingServices.clear();
11041 }
11042
11043 private final void removeDyingProviderLocked(ProcessRecord proc,
11044 ContentProviderRecord cpr) {
11045 synchronized (cpr) {
11046 cpr.launchingApp = null;
11047 cpr.notifyAll();
11048 }
11049
Amith Yamasani742a6712011-05-04 14:49:28 -070011050 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011051 String names[] = cpr.info.authority.split(";");
11052 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011053 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011054 }
11055
11056 Iterator<ProcessRecord> cit = cpr.clients.iterator();
11057 while (cit.hasNext()) {
11058 ProcessRecord capp = cit.next();
11059 if (!capp.persistent && capp.thread != null
11060 && capp.pid != 0
11061 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011062 Slog.i(TAG, "Kill " + capp.processName
11063 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011064 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070011065 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011066 capp.processName, capp.setAdj, "dying provider "
11067 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011068 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011069 }
11070 }
11071
11072 mLaunchingProviders.remove(cpr);
11073 }
11074
11075 /**
11076 * Main code for cleaning up a process when it has gone away. This is
11077 * called both as a result of the process dying, or directly when stopping
11078 * a process when running in single process mode.
11079 */
11080 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011081 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011082 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011083 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011084 }
11085
Dianne Hackborn36124872009-10-08 16:22:03 -070011086 mProcessesToGc.remove(app);
11087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011088 // Dismiss any open dialogs.
11089 if (app.crashDialog != null) {
11090 app.crashDialog.dismiss();
11091 app.crashDialog = null;
11092 }
11093 if (app.anrDialog != null) {
11094 app.anrDialog.dismiss();
11095 app.anrDialog = null;
11096 }
11097 if (app.waitDialog != null) {
11098 app.waitDialog.dismiss();
11099 app.waitDialog = null;
11100 }
11101
11102 app.crashing = false;
11103 app.notResponding = false;
11104
11105 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070011106 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011107 app.thread = null;
11108 app.forcingToForeground = null;
11109 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011110 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070011111 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011112 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011113
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011114 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115
11116 boolean restart = false;
11117
11118 int NL = mLaunchingProviders.size();
11119
11120 // Remove published content providers.
11121 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011122 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011123 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011124 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011125 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070011126 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011127
11128 // See if someone is waiting for this provider... in which
11129 // case we don't remove it, but just let it restart.
11130 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011131 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 for (; i<NL; i++) {
11133 if (mLaunchingProviders.get(i) == cpr) {
11134 restart = true;
11135 break;
11136 }
11137 }
11138 } else {
11139 i = NL;
11140 }
11141
11142 if (i >= NL) {
11143 removeDyingProviderLocked(app, cpr);
11144 NL = mLaunchingProviders.size();
11145 }
11146 }
11147 app.pubProviders.clear();
11148 }
11149
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011150 // Take care of any launching providers waiting for this process.
11151 if (checkAppInLaunchingProvidersLocked(app, false)) {
11152 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011153 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 // Unregister from connected content providers.
11156 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070011157 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011158 while (it.hasNext()) {
11159 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
11160 cpr.clients.remove(app);
11161 }
11162 app.conProviders.clear();
11163 }
11164
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011165 // At this point there may be remaining entries in mLaunchingProviders
11166 // where we were the only one waiting, so they are no longer of use.
11167 // Look for these and clean up if found.
11168 // XXX Commented out for now. Trying to figure out a way to reproduce
11169 // the actual situation to identify what is actually going on.
11170 if (false) {
11171 for (int i=0; i<NL; i++) {
11172 ContentProviderRecord cpr = (ContentProviderRecord)
11173 mLaunchingProviders.get(i);
11174 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
11175 synchronized (cpr) {
11176 cpr.launchingApp = null;
11177 cpr.notifyAll();
11178 }
11179 }
11180 }
11181 }
11182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011183 skipCurrentReceiverLocked(app);
11184
11185 // Unregister any receivers.
11186 if (app.receivers.size() > 0) {
11187 Iterator<ReceiverList> it = app.receivers.iterator();
11188 while (it.hasNext()) {
11189 removeReceiverLocked(it.next());
11190 }
11191 app.receivers.clear();
11192 }
11193
Christopher Tate181fafa2009-05-14 11:12:14 -070011194 // If the app is undergoing backup, tell the backup manager about it
11195 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011196 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070011197 try {
11198 IBackupManager bm = IBackupManager.Stub.asInterface(
11199 ServiceManager.getService(Context.BACKUP_SERVICE));
11200 bm.agentDisconnected(app.info.packageName);
11201 } catch (RemoteException e) {
11202 // can't happen; backup manager is local
11203 }
11204 }
11205
Jeff Sharkey287bd832011-05-28 19:36:26 -070011206 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070011207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011208 // If the caller is restarting this app, then leave it in its
11209 // current lists and let the caller take care of it.
11210 if (restarting) {
11211 return;
11212 }
11213
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011214 if (!app.persistent || app.isolated) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011215 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011216 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011217 mProcessNames.remove(app.processName, app.uid);
11218 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070011219 if (mHeavyWeightProcess == app) {
11220 mHeavyWeightProcess = null;
11221 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
11222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011223 } else if (!app.removed) {
11224 // This app is persistent, so we need to keep its record around.
11225 // If it is not already on the pending app list, add it there
11226 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011227 if (mPersistentStartingProcesses.indexOf(app) < 0) {
11228 mPersistentStartingProcesses.add(app);
11229 restart = true;
11230 }
11231 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011232 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
11233 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011234 mProcessesOnHold.remove(app);
11235
The Android Open Source Project4df24232009-03-05 14:34:35 -080011236 if (app == mHomeProcess) {
11237 mHomeProcess = null;
11238 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070011239 if (app == mPreviousProcess) {
11240 mPreviousProcess = null;
11241 }
11242
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011243 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011244 // We have components that still need to be running in the
11245 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011246 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011247 startProcessLocked(app, "restart", app.processName);
11248 } else if (app.pid > 0 && app.pid != MY_PID) {
11249 // Goodbye!
11250 synchronized (mPidsSelfLocked) {
11251 mPidsSelfLocked.remove(app.pid);
11252 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
11253 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070011254 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 }
11256 }
11257
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011258 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
11259 // Look through the content providers we are waiting to have launched,
11260 // and if any run in this process then either schedule a restart of
11261 // the process or kill the client waiting for it if this process has
11262 // gone bad.
11263 int NL = mLaunchingProviders.size();
11264 boolean restart = false;
11265 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011266 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080011267 if (cpr.launchingApp == app) {
11268 if (!alwaysBad && !app.bad) {
11269 restart = true;
11270 } else {
11271 removeDyingProviderLocked(app, cpr);
11272 NL = mLaunchingProviders.size();
11273 }
11274 }
11275 }
11276 return restart;
11277 }
11278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011279 // =========================================================
11280 // SERVICES
11281 // =========================================================
11282
11283 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
11284 ActivityManager.RunningServiceInfo info =
11285 new ActivityManager.RunningServiceInfo();
11286 info.service = r.name;
11287 if (r.app != null) {
11288 info.pid = r.app.pid;
11289 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011290 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011291 info.process = r.processName;
11292 info.foreground = r.isForeground;
11293 info.activeSince = r.createTime;
11294 info.started = r.startRequested;
11295 info.clientCount = r.connections.size();
11296 info.crashCount = r.crashCount;
11297 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011298 if (r.isForeground) {
11299 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
11300 }
11301 if (r.startRequested) {
11302 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
11303 }
Dan Egnor42471dd2010-01-07 17:25:22 -080011304 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070011305 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
11306 }
11307 if (r.app != null && r.app.persistent) {
11308 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
11309 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011310
11311 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
11312 for (int i=0; i<connl.size(); i++) {
11313 ConnectionRecord conn = connl.get(i);
11314 if (conn.clientLabel != 0) {
11315 info.clientPackage = conn.binding.client.info.packageName;
11316 info.clientLabel = conn.clientLabel;
11317 return info;
11318 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011319 }
11320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 return info;
11322 }
11323
11324 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11325 int flags) {
11326 synchronized (this) {
11327 ArrayList<ActivityManager.RunningServiceInfo> res
11328 = new ArrayList<ActivityManager.RunningServiceInfo>();
11329
Amith Yamasani742a6712011-05-04 14:49:28 -070011330 int userId = UserId.getUserId(Binder.getCallingUid());
11331 if (mServiceMap.getAllServices(userId).size() > 0) {
11332 Iterator<ServiceRecord> it
11333 = mServiceMap.getAllServices(userId).iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011334 while (it.hasNext() && res.size() < maxNum) {
11335 res.add(makeRunningServiceInfoLocked(it.next()));
11336 }
11337 }
11338
11339 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11340 ServiceRecord r = mRestartingServices.get(i);
11341 ActivityManager.RunningServiceInfo info =
11342 makeRunningServiceInfoLocked(r);
11343 info.restarting = r.nextRestartTime;
11344 res.add(info);
11345 }
11346
11347 return res;
11348 }
11349 }
11350
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011351 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
11352 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011353 int userId = UserId.getUserId(Binder.getCallingUid());
11354 ServiceRecord r = mServiceMap.getServiceByName(name, userId);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011355 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011356 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11357 for (int i=0; i<conn.size(); i++) {
11358 if (conn.get(i).clientIntent != null) {
11359 return conn.get(i).clientIntent;
11360 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011361 }
11362 }
11363 }
11364 }
11365 return null;
11366 }
11367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011368 private final ServiceRecord findServiceLocked(ComponentName name,
11369 IBinder token) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011370 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 return r == token ? r : null;
11372 }
11373
11374 private final class ServiceLookupResult {
11375 final ServiceRecord record;
11376 final String permission;
11377
11378 ServiceLookupResult(ServiceRecord _record, String _permission) {
11379 record = _record;
11380 permission = _permission;
11381 }
11382 };
11383
11384 private ServiceLookupResult findServiceLocked(Intent service,
11385 String resolvedType) {
11386 ServiceRecord r = null;
11387 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011388 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011389 }
11390 if (r == null) {
11391 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani742a6712011-05-04 14:49:28 -070011392 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011393 }
11394
11395 if (r == null) {
11396 try {
11397 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011398 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011399 service, resolvedType, 0);
11400 ServiceInfo sInfo =
11401 rInfo != null ? rInfo.serviceInfo : null;
11402 if (sInfo == null) {
11403 return null;
11404 }
11405
11406 ComponentName name = new ComponentName(
11407 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011408 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 } catch (RemoteException ex) {
11410 // pm is in same process, this will never happen.
11411 }
11412 }
11413 if (r != null) {
11414 int callingPid = Binder.getCallingPid();
11415 int callingUid = Binder.getCallingUid();
11416 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011417 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011418 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011419 if (!r.exported) {
11420 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11421 + " from pid=" + callingPid
11422 + ", uid=" + callingUid
11423 + " that is not exported from uid " + r.appInfo.uid);
11424 return new ServiceLookupResult(null, "not exported from uid "
11425 + r.appInfo.uid);
11426 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011427 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011428 + " from pid=" + callingPid
11429 + ", uid=" + callingUid
11430 + " requires " + r.permission);
11431 return new ServiceLookupResult(null, r.permission);
11432 }
11433 return new ServiceLookupResult(r, null);
11434 }
11435 return null;
11436 }
11437
11438 private class ServiceRestarter implements Runnable {
11439 private ServiceRecord mService;
11440
11441 void setService(ServiceRecord service) {
11442 mService = service;
11443 }
11444
11445 public void run() {
11446 synchronized(ActivityManagerService.this) {
11447 performServiceRestartLocked(mService);
11448 }
11449 }
11450 }
11451
11452 private ServiceLookupResult retrieveServiceLocked(Intent service,
11453 String resolvedType, int callingPid, int callingUid) {
11454 ServiceRecord r = null;
Amith Yamasani742a6712011-05-04 14:49:28 -070011455 if (DEBUG_SERVICE)
11456 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
11457 + " origCallingUid=" + callingUid);
11458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011459 if (service.getComponent() != null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011460 r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011461 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011462 if (r == null) {
11463 Intent.FilterComparison filter = new Intent.FilterComparison(service);
11464 r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
11465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011466 if (r == null) {
11467 try {
11468 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011469 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011470 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011471 ServiceInfo sInfo =
11472 rInfo != null ? rInfo.serviceInfo : null;
11473 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011474 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011475 ": not found");
11476 return null;
11477 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011478 if (Binder.getOrigCallingUser() > 0) {
11479 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo,
11480 Binder.getOrigCallingUser());
11481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011482 ComponentName name = new ComponentName(
11483 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011484 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011485 if (r == null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011486 Intent.FilterComparison filter = new Intent.FilterComparison(
11487 service.cloneFilter());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011488 ServiceRestarter res = new ServiceRestarter();
11489 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11490 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11491 synchronized (stats) {
11492 ss = stats.getServiceStatsLocked(
11493 sInfo.applicationInfo.uid, sInfo.packageName,
11494 sInfo.name);
11495 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080011496 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011497 res.setService(r);
Amith Yamasani742a6712011-05-04 14:49:28 -070011498 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11499 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500
11501 // Make sure this component isn't in the pending list.
11502 int N = mPendingServices.size();
11503 for (int i=0; i<N; i++) {
11504 ServiceRecord pr = mPendingServices.get(i);
11505 if (pr.name.equals(name)) {
11506 mPendingServices.remove(i);
11507 i--;
11508 N--;
11509 }
11510 }
11511 }
11512 } catch (RemoteException ex) {
11513 // pm is in same process, this will never happen.
11514 }
11515 }
11516 if (r != null) {
11517 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011518 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011519 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011520 if (!r.exported) {
11521 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11522 + " from pid=" + callingPid
11523 + ", uid=" + callingUid
11524 + " that is not exported from uid " + r.appInfo.uid);
11525 return new ServiceLookupResult(null, "not exported from uid "
11526 + r.appInfo.uid);
11527 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011528 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011529 + " from pid=" + callingPid
11530 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011531 + " requires " + r.permission);
11532 return new ServiceLookupResult(null, r.permission);
11533 }
11534 return new ServiceLookupResult(r, null);
11535 }
11536 return null;
11537 }
11538
Dianne Hackborn287952c2010-09-22 22:34:31 -070011539 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11540 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11541 + why + " of " + r + " in app " + r.app);
11542 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11543 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011544 long now = SystemClock.uptimeMillis();
11545 if (r.executeNesting == 0 && r.app != null) {
11546 if (r.app.executingServices.size() == 0) {
11547 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11548 msg.obj = r.app;
11549 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11550 }
11551 r.app.executingServices.add(r);
11552 }
11553 r.executeNesting++;
11554 r.executingStart = now;
11555 }
11556
11557 private final void sendServiceArgsLocked(ServiceRecord r,
11558 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011559 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 if (N == 0) {
11561 return;
11562 }
11563
Dianne Hackborn39792d22010-08-19 18:01:52 -070011564 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011565 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011566 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011567 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11568 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011569 if (si.intent == null && N > 1) {
11570 // If somehow we got a dummy null intent in the middle,
11571 // then skip it. DO NOT skip a null intent when it is
11572 // the only one in the list -- this is to support the
11573 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011574 continue;
11575 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070011576 si.deliveredTime = SystemClock.uptimeMillis();
11577 r.deliveredStarts.add(si);
11578 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011579 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011580 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070011581 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070011582 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070011583 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011584 if (!oomAdjusted) {
11585 oomAdjusted = true;
11586 updateOomAdjLocked(r.app);
11587 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011588 int flags = 0;
11589 if (si.deliveryCount > 0) {
11590 flags |= Service.START_FLAG_RETRY;
11591 }
11592 if (si.doneExecutingCount > 0) {
11593 flags |= Service.START_FLAG_REDELIVERY;
11594 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011595 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011596 } catch (RemoteException e) {
11597 // Remote process gone... we'll let the normal cleanup take
11598 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011599 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011600 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011601 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011602 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011603 break;
11604 }
11605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011606 }
11607
11608 private final boolean requestServiceBindingLocked(ServiceRecord r,
11609 IntentBindRecord i, boolean rebind) {
11610 if (r.app == null || r.app.thread == null) {
11611 // If service is not currently running, can't yet bind.
11612 return false;
11613 }
11614 if ((!i.requested || rebind) && i.apps.size() > 0) {
11615 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011616 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011617 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11618 if (!rebind) {
11619 i.requested = true;
11620 }
11621 i.hasBound = true;
11622 i.doRebind = false;
11623 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011624 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011625 return false;
11626 }
11627 }
11628 return true;
11629 }
11630
11631 private final void requestServiceBindingsLocked(ServiceRecord r) {
11632 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11633 while (bindings.hasNext()) {
11634 IntentBindRecord i = bindings.next();
11635 if (!requestServiceBindingLocked(r, i, false)) {
11636 break;
11637 }
11638 }
11639 }
11640
11641 private final void realStartServiceLocked(ServiceRecord r,
11642 ProcessRecord app) throws RemoteException {
11643 if (app.thread == null) {
11644 throw new RemoteException();
11645 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011646 if (DEBUG_MU)
11647 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011648 + ", ProcessRecord.uid = " + app.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011649 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070011650 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011651
11652 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011653 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011654 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655
11656 boolean created = false;
11657 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011658 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070011659 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011660 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011662 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011663 synchronized (r.stats.getBatteryStats()) {
11664 r.stats.startLaunchedLocked();
11665 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011666 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011667 app.thread.scheduleCreateService(r, r.serviceInfo,
11668 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011669 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011670 created = true;
11671 } finally {
11672 if (!created) {
11673 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011674 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011675 }
11676 }
11677
11678 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011679
11680 // If the service is in the started state, and there are no
11681 // pending arguments, then fake up one so its onStartCommand() will
11682 // be called.
11683 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011684 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11685 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011686 }
11687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011688 sendServiceArgsLocked(r, true);
11689 }
11690
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011691 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11692 boolean allowCancel) {
11693 boolean canceled = false;
11694
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011695 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011696 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070011697 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011698
Dianne Hackborn070783f2010-12-29 16:46:28 -080011699 if ((r.serviceInfo.applicationInfo.flags
11700 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11701 minDuration /= 4;
11702 }
11703
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011704 // Any delivered but not yet finished starts should be put back
11705 // on the pending list.
11706 final int N = r.deliveredStarts.size();
11707 if (N > 0) {
11708 for (int i=N-1; i>=0; i--) {
11709 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070011710 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011711 if (si.intent == null) {
11712 // We'll generate this again if needed.
11713 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11714 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11715 r.pendingStarts.add(0, si);
11716 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11717 dur *= 2;
11718 if (minDuration < dur) minDuration = dur;
11719 if (resetTime < dur) resetTime = dur;
11720 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011721 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011722 + r.name);
11723 canceled = true;
11724 }
11725 }
11726 r.deliveredStarts.clear();
11727 }
11728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011729 r.totalRestartCount++;
11730 if (r.restartDelay == 0) {
11731 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011732 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011733 } else {
11734 // If it has been a "reasonably long time" since the service
11735 // was started, then reset our restart duration back to
11736 // the beginning, so we don't infinitely increase the duration
11737 // on a service that just occasionally gets killed (which is
11738 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011739 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011740 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011741 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011742 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080011743 if ((r.serviceInfo.applicationInfo.flags
11744 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11745 // Services in peristent processes will restart much more
11746 // quickly, since they are pretty important. (Think SystemUI).
11747 r.restartDelay += minDuration/2;
11748 } else {
11749 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11750 if (r.restartDelay < minDuration) {
11751 r.restartDelay = minDuration;
11752 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011754 }
11755 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011756
11757 r.nextRestartTime = now + r.restartDelay;
11758
11759 // Make sure that we don't end up restarting a bunch of services
11760 // all at the same time.
11761 boolean repeat;
11762 do {
11763 repeat = false;
11764 for (int i=mRestartingServices.size()-1; i>=0; i--) {
11765 ServiceRecord r2 = mRestartingServices.get(i);
11766 if (r2 != r && r.nextRestartTime
11767 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11768 && r.nextRestartTime
11769 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11770 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11771 r.restartDelay = r.nextRestartTime - now;
11772 repeat = true;
11773 break;
11774 }
11775 }
11776 } while (repeat);
11777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 if (!mRestartingServices.contains(r)) {
11779 mRestartingServices.add(r);
11780 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011781
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011782 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011784 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011785 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011786 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011787 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011788 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080011789 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011790 r.shortName, r.restartDelay);
11791
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011792 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011793 }
11794
11795 final void performServiceRestartLocked(ServiceRecord r) {
11796 if (!mRestartingServices.contains(r)) {
11797 return;
11798 }
11799 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11800 }
11801
11802 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11803 if (r.restartDelay == 0) {
11804 return false;
11805 }
11806 r.resetRestartCounter();
11807 mRestartingServices.remove(r);
11808 mHandler.removeCallbacks(r.restarter);
11809 return true;
11810 }
11811
11812 private final boolean bringUpServiceLocked(ServiceRecord r,
11813 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011814 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011815 //r.dump(" ");
11816
Dianne Hackborn36124872009-10-08 16:22:03 -070011817 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011818 sendServiceArgsLocked(r, false);
11819 return true;
11820 }
11821
11822 if (!whileRestarting && r.restartDelay > 0) {
11823 // If waiting for a restart, then do nothing.
11824 return true;
11825 }
11826
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011827 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011829 // We are now bringing the service up, so no longer in the
11830 // restarting state.
11831 mRestartingServices.remove(r);
11832
Dianne Hackborne7f97212011-02-24 14:40:20 -080011833 // Service is now being launched, its package can't be stopped.
11834 try {
11835 AppGlobals.getPackageManager().setPackageStoppedState(
11836 r.packageName, false);
11837 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011838 } catch (IllegalArgumentException e) {
11839 Slog.w(TAG, "Failed trying to unstop package "
11840 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011841 }
11842
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011843 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011844 final String appName = r.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011845 ProcessRecord app;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011847 if (!isolated) {
11848 app = getProcessRecordLocked(appName, r.appInfo.uid);
11849 if (DEBUG_MU)
11850 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11851 if (app != null && app.thread != null) {
11852 try {
11853 app.addPackage(r.appInfo.packageName);
11854 realStartServiceLocked(r, app);
11855 return true;
11856 } catch (RemoteException e) {
11857 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11858 }
11859
11860 // If a dead object exception was thrown -- fall through to
11861 // restart the application.
11862 }
11863 } else {
11864 // If this service runs in an isolated process, then each time
11865 // we call startProcessLocked() we will get a new isolated
11866 // process, starting another process if we are currently waiting
11867 // for a previous process to come up. To deal with this, we store
11868 // in the service any current isolated process it is running in or
11869 // waiting to have come up.
11870 app = r.isolatedProc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011871 }
11872
Dianne Hackborn36124872009-10-08 16:22:03 -070011873 // Not running -- get it started, and enqueue this service record
11874 // to be executed when the app comes up.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011875 if (app == null) {
11876 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11877 "service", r.name, false, isolated)) == null) {
11878 Slog.w(TAG, "Unable to launch app "
11879 + r.appInfo.packageName + "/"
11880 + r.appInfo.uid + " for service "
11881 + r.intent.getIntent() + ": process is bad");
11882 bringDownServiceLocked(r, true);
11883 return false;
11884 }
11885 if (isolated) {
11886 r.isolatedProc = app;
11887 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011888 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011890 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011891 mPendingServices.add(r);
11892 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011894 return true;
11895 }
11896
11897 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011898 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011899 //r.dump(" ");
11900
11901 // Does it still need to run?
11902 if (!force && r.startRequested) {
11903 return;
11904 }
11905 if (r.connections.size() > 0) {
11906 if (!force) {
11907 // XXX should probably keep a count of the number of auto-create
11908 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011909 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011910 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011911 ArrayList<ConnectionRecord> cr = it.next();
11912 for (int i=0; i<cr.size(); i++) {
11913 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11914 return;
11915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011916 }
11917 }
11918 }
11919
11920 // Report to all of the connections that the service is no longer
11921 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011922 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011923 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011924 ArrayList<ConnectionRecord> c = it.next();
11925 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011926 ConnectionRecord cr = c.get(i);
11927 // There is still a connection to the service that is
11928 // being brought down. Mark it as dead.
11929 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011930 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011931 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011932 } catch (Exception e) {
11933 Slog.w(TAG, "Failure disconnecting service " + r.name +
11934 " to connection " + c.get(i).conn.asBinder() +
11935 " (in " + c.get(i).binding.client.processName + ")", e);
11936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011937 }
11938 }
11939 }
11940
11941 // Tell the service that it has been unbound.
11942 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11943 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11944 while (it.hasNext()) {
11945 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011946 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011947 + ": hasBound=" + ibr.hasBound);
11948 if (r.app != null && r.app.thread != null && ibr.hasBound) {
11949 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011950 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011951 updateOomAdjLocked(r.app);
11952 ibr.hasBound = false;
11953 r.app.thread.scheduleUnbindService(r,
11954 ibr.intent.getIntent());
11955 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011956 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011957 + r.shortName, e);
11958 serviceDoneExecutingLocked(r, true);
11959 }
11960 }
11961 }
11962 }
11963
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011964 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011965 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011966 System.identityHashCode(r), r.shortName,
11967 (r.app != null) ? r.app.pid : -1);
11968
Amith Yamasani742a6712011-05-04 14:49:28 -070011969 mServiceMap.removeServiceByName(r.name, r.userId);
11970 mServiceMap.removeServiceByIntent(r.intent, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011971 r.totalRestartCount = 0;
11972 unscheduleServiceRestartLocked(r);
11973
11974 // Also make sure it is not on the pending list.
11975 int N = mPendingServices.size();
11976 for (int i=0; i<N; i++) {
11977 if (mPendingServices.get(i) == r) {
11978 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011979 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011980 i--;
11981 N--;
11982 }
11983 }
11984
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011985 r.cancelNotification();
11986 r.isForeground = false;
11987 r.foregroundId = 0;
11988 r.foregroundNoti = null;
11989
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011990 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011991 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011992 r.pendingStarts.clear();
11993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011994 if (r.app != null) {
11995 synchronized (r.stats.getBatteryStats()) {
11996 r.stats.stopLaunchedLocked();
11997 }
11998 r.app.services.remove(r);
11999 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012000 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012001 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 mStoppingServices.add(r);
12003 updateOomAdjLocked(r.app);
12004 r.app.thread.scheduleStopService(r);
12005 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012006 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012007 + r.shortName, e);
12008 serviceDoneExecutingLocked(r, true);
12009 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012010 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012011 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012012 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012013 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012014 }
12015 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012016 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012017 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012018 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080012019
12020 if (r.bindings.size() > 0) {
12021 r.bindings.clear();
12022 }
12023
12024 if (r.restarter instanceof ServiceRestarter) {
12025 ((ServiceRestarter)r.restarter).setService(null);
12026 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012027 }
12028
12029 ComponentName startServiceLocked(IApplicationThread caller,
12030 Intent service, String resolvedType,
12031 int callingPid, int callingUid) {
12032 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012033 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012034 + " type=" + resolvedType + " args=" + service.getExtras());
12035
12036 if (caller != null) {
12037 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12038 if (callerApp == null) {
12039 throw new SecurityException(
12040 "Unable to find app for caller " + caller
12041 + " (pid=" + Binder.getCallingPid()
12042 + ") when starting service " + service);
12043 }
12044 }
12045
12046 ServiceLookupResult res =
12047 retrieveServiceLocked(service, resolvedType,
12048 callingPid, callingUid);
12049 if (res == null) {
12050 return null;
12051 }
12052 if (res.record == null) {
12053 return new ComponentName("!", res.permission != null
12054 ? res.permission : "private to package");
12055 }
12056 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070012057 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
12058 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012059 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012060 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 }
12062 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012063 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012064 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070012065 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012066 r.lastActivity = SystemClock.uptimeMillis();
12067 synchronized (r.stats.getBatteryStats()) {
12068 r.stats.startRunningLocked();
12069 }
12070 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
12071 return new ComponentName("!", "Service process is bad");
12072 }
12073 return r.name;
12074 }
12075 }
12076
12077 public ComponentName startService(IApplicationThread caller, Intent service,
12078 String resolvedType) {
12079 // Refuse possible leaked file descriptors
12080 if (service != null && service.hasFileDescriptors() == true) {
12081 throw new IllegalArgumentException("File descriptors passed in Intent");
12082 }
12083
Amith Yamasani742a6712011-05-04 14:49:28 -070012084 if (DEBUG_SERVICE)
12085 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012086 synchronized(this) {
12087 final int callingPid = Binder.getCallingPid();
12088 final int callingUid = Binder.getCallingUid();
12089 final long origId = Binder.clearCallingIdentity();
12090 ComponentName res = startServiceLocked(caller, service,
12091 resolvedType, callingPid, callingUid);
12092 Binder.restoreCallingIdentity(origId);
12093 return res;
12094 }
12095 }
12096
12097 ComponentName startServiceInPackage(int uid,
12098 Intent service, String resolvedType) {
12099 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070012100 if (DEBUG_SERVICE)
12101 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012102 final long origId = Binder.clearCallingIdentity();
12103 ComponentName res = startServiceLocked(null, service,
12104 resolvedType, -1, uid);
12105 Binder.restoreCallingIdentity(origId);
12106 return res;
12107 }
12108 }
12109
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012110 private void stopServiceLocked(ServiceRecord service) {
12111 synchronized (service.stats.getBatteryStats()) {
12112 service.stats.stopRunningLocked();
12113 }
12114 service.startRequested = false;
12115 service.callStart = false;
12116 bringDownServiceLocked(service, false);
12117 }
12118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012119 public int stopService(IApplicationThread caller, Intent service,
12120 String resolvedType) {
12121 // Refuse possible leaked file descriptors
12122 if (service != null && service.hasFileDescriptors() == true) {
12123 throw new IllegalArgumentException("File descriptors passed in Intent");
12124 }
12125
12126 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012127 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012128 + " type=" + resolvedType);
12129
12130 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12131 if (caller != null && callerApp == null) {
12132 throw new SecurityException(
12133 "Unable to find app for caller " + caller
12134 + " (pid=" + Binder.getCallingPid()
12135 + ") when stopping service " + service);
12136 }
12137
12138 // If this service is active, make sure it is stopped.
12139 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12140 if (r != null) {
12141 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012143 try {
12144 stopServiceLocked(r.record);
12145 } finally {
12146 Binder.restoreCallingIdentity(origId);
12147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012148 return 1;
12149 }
12150 return -1;
12151 }
12152 }
12153
12154 return 0;
12155 }
12156
12157 public IBinder peekService(Intent service, String resolvedType) {
12158 // Refuse possible leaked file descriptors
12159 if (service != null && service.hasFileDescriptors() == true) {
12160 throw new IllegalArgumentException("File descriptors passed in Intent");
12161 }
12162
12163 IBinder ret = null;
12164
12165 synchronized(this) {
12166 ServiceLookupResult r = findServiceLocked(service, resolvedType);
12167
12168 if (r != null) {
12169 // r.record is null if findServiceLocked() failed the caller permission check
12170 if (r.record == null) {
12171 throw new SecurityException(
12172 "Permission Denial: Accessing service " + r.record.name
12173 + " from pid=" + Binder.getCallingPid()
12174 + ", uid=" + Binder.getCallingUid()
12175 + " requires " + r.permission);
12176 }
12177 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
12178 if (ib != null) {
12179 ret = ib.binder;
12180 }
12181 }
12182 }
12183
12184 return ret;
12185 }
12186
12187 public boolean stopServiceToken(ComponentName className, IBinder token,
12188 int startId) {
12189 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012190 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012191 + " " + token + " startId=" + startId);
12192 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012193 if (r != null) {
12194 if (startId >= 0) {
12195 // Asked to only stop if done with all work. Note that
12196 // to avoid leaks, we will take this as dropping all
12197 // start items up to and including this one.
12198 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12199 if (si != null) {
12200 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070012201 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
12202 cur.removeUriPermissionsLocked();
12203 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012204 break;
12205 }
12206 }
12207 }
12208
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012209 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012210 return false;
12211 }
12212
12213 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012214 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012215 + " is last, but have " + r.deliveredStarts.size()
12216 + " remaining args");
12217 }
12218 }
12219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 synchronized (r.stats.getBatteryStats()) {
12221 r.stats.stopRunningLocked();
12222 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012223 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 }
12225 final long origId = Binder.clearCallingIdentity();
12226 bringDownServiceLocked(r, false);
12227 Binder.restoreCallingIdentity(origId);
12228 return true;
12229 }
12230 }
12231 return false;
12232 }
12233
12234 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012235 int id, Notification notification, boolean removeNotification) {
12236 final long origId = Binder.clearCallingIdentity();
12237 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012238 synchronized(this) {
12239 ServiceRecord r = findServiceLocked(className, token);
12240 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012241 if (id != 0) {
12242 if (notification == null) {
12243 throw new IllegalArgumentException("null notification");
12244 }
12245 if (r.foregroundId != id) {
12246 r.cancelNotification();
12247 r.foregroundId = id;
12248 }
12249 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
12250 r.foregroundNoti = notification;
12251 r.isForeground = true;
12252 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012253 if (r.app != null) {
12254 updateServiceForegroundLocked(r.app, true);
12255 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012256 } else {
12257 if (r.isForeground) {
12258 r.isForeground = false;
12259 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070012260 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012261 updateServiceForegroundLocked(r.app, true);
12262 }
12263 }
12264 if (removeNotification) {
12265 r.cancelNotification();
12266 r.foregroundId = 0;
12267 r.foregroundNoti = null;
12268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012269 }
12270 }
12271 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070012272 } finally {
12273 Binder.restoreCallingIdentity(origId);
12274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275 }
12276
12277 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
12278 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070012279 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012280 if (sr.isForeground) {
12281 anyForeground = true;
12282 break;
12283 }
12284 }
12285 if (anyForeground != proc.foregroundServices) {
12286 proc.foregroundServices = anyForeground;
12287 if (oomAdj) {
12288 updateOomAdjLocked();
12289 }
12290 }
12291 }
12292
12293 public int bindService(IApplicationThread caller, IBinder token,
12294 Intent service, String resolvedType,
12295 IServiceConnection connection, int flags) {
12296 // Refuse possible leaked file descriptors
12297 if (service != null && service.hasFileDescriptors() == true) {
12298 throw new IllegalArgumentException("File descriptors passed in Intent");
12299 }
12300
12301 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012302 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012303 + " type=" + resolvedType + " conn=" + connection.asBinder()
12304 + " flags=0x" + Integer.toHexString(flags));
Amith Yamasani742a6712011-05-04 14:49:28 -070012305 if (DEBUG_MU)
12306 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12307 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012308 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12309 if (callerApp == null) {
12310 throw new SecurityException(
12311 "Unable to find app for caller " + caller
12312 + " (pid=" + Binder.getCallingPid()
12313 + ") when binding service " + service);
12314 }
12315
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012316 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012317 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012318 activity = mMainStack.isInStackLocked(token);
12319 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012320 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012321 return 0;
12322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012323 }
12324
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012325 int clientLabel = 0;
12326 PendingIntent clientIntent = null;
12327
12328 if (callerApp.info.uid == Process.SYSTEM_UID) {
12329 // Hacky kind of thing -- allow system stuff to tell us
12330 // what they are, so we can report this elsewhere for
12331 // others to know why certain services are running.
12332 try {
12333 clientIntent = (PendingIntent)service.getParcelableExtra(
12334 Intent.EXTRA_CLIENT_INTENT);
12335 } catch (RuntimeException e) {
12336 }
12337 if (clientIntent != null) {
12338 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12339 if (clientLabel != 0) {
12340 // There are no useful extras in the intent, trash them.
12341 // System code calling with this stuff just needs to know
12342 // this will happen.
12343 service = service.cloneFilter();
12344 }
12345 }
12346 }
12347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012348 ServiceLookupResult res =
12349 retrieveServiceLocked(service, resolvedType,
Amith Yamasani742a6712011-05-04 14:49:28 -070012350 Binder.getCallingPid(), Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012351 if (res == null) {
12352 return 0;
12353 }
12354 if (res.record == null) {
12355 return -1;
12356 }
12357 ServiceRecord s = res.record;
12358
12359 final long origId = Binder.clearCallingIdentity();
12360
12361 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012362 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012363 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 }
12365
12366 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12367 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012368 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012369
12370 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012371 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12372 if (clist == null) {
12373 clist = new ArrayList<ConnectionRecord>();
12374 s.connections.put(binder, clist);
12375 }
12376 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012377 b.connections.add(c);
12378 if (activity != null) {
12379 if (activity.connections == null) {
12380 activity.connections = new HashSet<ConnectionRecord>();
12381 }
12382 activity.connections.add(c);
12383 }
12384 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012385 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12386 b.client.hasAboveClient = true;
12387 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012388 clist = mServiceConnections.get(binder);
12389 if (clist == null) {
12390 clist = new ArrayList<ConnectionRecord>();
12391 mServiceConnections.put(binder, clist);
12392 }
12393 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012394
12395 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12396 s.lastActivity = SystemClock.uptimeMillis();
12397 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12398 return 0;
12399 }
12400 }
12401
12402 if (s.app != null) {
12403 // This could have made the service more important.
12404 updateOomAdjLocked(s.app);
12405 }
12406
Joe Onorato8a9b2202010-02-26 18:56:32 -080012407 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012408 + ": received=" + b.intent.received
12409 + " apps=" + b.intent.apps.size()
12410 + " doRebind=" + b.intent.doRebind);
12411
12412 if (s.app != null && b.intent.received) {
12413 // Service is already running, so we can immediately
12414 // publish the connection.
12415 try {
12416 c.conn.connected(s.name, b.intent.binder);
12417 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012418 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012419 + " to connection " + c.conn.asBinder()
12420 + " (in " + c.binding.client.processName + ")", e);
12421 }
12422
12423 // If this is the first app connected back to this binding,
12424 // and the service had previously asked to be told when
12425 // rebound, then do so.
12426 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12427 requestServiceBindingLocked(s, b.intent, true);
12428 }
12429 } else if (!b.intent.requested) {
12430 requestServiceBindingLocked(s, b.intent, false);
12431 }
12432
12433 Binder.restoreCallingIdentity(origId);
12434 }
12435
12436 return 1;
12437 }
12438
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012439 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012440 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012441 IBinder binder = c.conn.asBinder();
12442 AppBindRecord b = c.binding;
12443 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012444 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12445 if (clist != null) {
12446 clist.remove(c);
12447 if (clist.size() == 0) {
12448 s.connections.remove(binder);
12449 }
12450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 b.connections.remove(c);
12452 if (c.activity != null && c.activity != skipAct) {
12453 if (c.activity.connections != null) {
12454 c.activity.connections.remove(c);
12455 }
12456 }
12457 if (b.client != skipApp) {
12458 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012459 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12460 b.client.updateHasAboveClientLocked();
12461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012462 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012463 clist = mServiceConnections.get(binder);
12464 if (clist != null) {
12465 clist.remove(c);
12466 if (clist.size() == 0) {
12467 mServiceConnections.remove(binder);
12468 }
12469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012470
12471 if (b.connections.size() == 0) {
12472 b.intent.apps.remove(b.client);
12473 }
12474
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012475 if (!c.serviceDead) {
12476 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12477 + ": shouldUnbind=" + b.intent.hasBound);
12478 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12479 && b.intent.hasBound) {
12480 try {
12481 bumpServiceExecutingLocked(s, "unbind");
12482 updateOomAdjLocked(s.app);
12483 b.intent.hasBound = false;
12484 // Assume the client doesn't want to know about a rebind;
12485 // we will deal with that later if it asks for one.
12486 b.intent.doRebind = false;
12487 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12488 } catch (Exception e) {
12489 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12490 serviceDoneExecutingLocked(s, true);
12491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012492 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012493
12494 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12495 bringDownServiceLocked(s, false);
12496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012497 }
12498 }
12499
12500 public boolean unbindService(IServiceConnection connection) {
12501 synchronized (this) {
12502 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012503 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012504 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12505 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012506 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 + connection.asBinder());
12508 return false;
12509 }
12510
12511 final long origId = Binder.clearCallingIdentity();
12512
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012513 while (clist.size() > 0) {
12514 ConnectionRecord r = clist.get(0);
12515 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012516
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012517 if (r.binding.service.app != null) {
12518 // This could have made the service less important.
12519 updateOomAdjLocked(r.binding.service.app);
12520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012521 }
12522
12523 Binder.restoreCallingIdentity(origId);
12524 }
12525
12526 return true;
12527 }
12528
12529 public void publishService(IBinder token, Intent intent, IBinder service) {
12530 // Refuse possible leaked file descriptors
12531 if (intent != null && intent.hasFileDescriptors() == true) {
12532 throw new IllegalArgumentException("File descriptors passed in Intent");
12533 }
12534
12535 synchronized(this) {
12536 if (!(token instanceof ServiceRecord)) {
12537 throw new IllegalArgumentException("Invalid service token");
12538 }
12539 ServiceRecord r = (ServiceRecord)token;
12540
12541 final long origId = Binder.clearCallingIdentity();
12542
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012543 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012544 + " " + intent + ": " + service);
12545 if (r != null) {
12546 Intent.FilterComparison filter
12547 = new Intent.FilterComparison(intent);
12548 IntentBindRecord b = r.bindings.get(filter);
12549 if (b != null && !b.received) {
12550 b.binder = service;
12551 b.requested = true;
12552 b.received = true;
12553 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012554 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012555 = r.connections.values().iterator();
12556 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012557 ArrayList<ConnectionRecord> clist = it.next();
12558 for (int i=0; i<clist.size(); i++) {
12559 ConnectionRecord c = clist.get(i);
12560 if (!filter.equals(c.binding.intent.intent)) {
12561 if (DEBUG_SERVICE) Slog.v(
12562 TAG, "Not publishing to: " + c);
12563 if (DEBUG_SERVICE) Slog.v(
12564 TAG, "Bound intent: " + c.binding.intent.intent);
12565 if (DEBUG_SERVICE) Slog.v(
12566 TAG, "Published intent: " + intent);
12567 continue;
12568 }
12569 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12570 try {
12571 c.conn.connected(r.name, service);
12572 } catch (Exception e) {
12573 Slog.w(TAG, "Failure sending service " + r.name +
12574 " to connection " + c.conn.asBinder() +
12575 " (in " + c.binding.client.processName + ")", e);
12576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012577 }
12578 }
12579 }
12580 }
12581
12582 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12583
12584 Binder.restoreCallingIdentity(origId);
12585 }
12586 }
12587 }
12588
12589 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12590 // Refuse possible leaked file descriptors
12591 if (intent != null && intent.hasFileDescriptors() == true) {
12592 throw new IllegalArgumentException("File descriptors passed in Intent");
12593 }
12594
12595 synchronized(this) {
12596 if (!(token instanceof ServiceRecord)) {
12597 throw new IllegalArgumentException("Invalid service token");
12598 }
12599 ServiceRecord r = (ServiceRecord)token;
12600
12601 final long origId = Binder.clearCallingIdentity();
12602
12603 if (r != null) {
12604 Intent.FilterComparison filter
12605 = new Intent.FilterComparison(intent);
12606 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012607 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012608 + " at " + b + ": apps="
12609 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020012610
12611 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012612 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020012613 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012614 // Applications have already bound since the last
12615 // unbind, so just rebind right here.
12616 requestServiceBindingLocked(r, b, true);
12617 } else {
12618 // Note to tell the service the next time there is
12619 // a new client.
12620 b.doRebind = true;
12621 }
12622 }
12623
Per Edelberg78f9fff2010-08-30 20:01:35 +020012624 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625
12626 Binder.restoreCallingIdentity(origId);
12627 }
12628 }
12629 }
12630
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012631 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012632 synchronized(this) {
12633 if (!(token instanceof ServiceRecord)) {
12634 throw new IllegalArgumentException("Invalid service token");
12635 }
12636 ServiceRecord r = (ServiceRecord)token;
12637 boolean inStopping = mStoppingServices.contains(token);
12638 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012639 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012640 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012641 + " with incorrect token: given " + token
12642 + ", expected " + r);
12643 return;
12644 }
12645
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012646 if (type == 1) {
12647 // This is a call from a service start... take care of
12648 // book-keeping.
12649 r.callStart = true;
12650 switch (res) {
12651 case Service.START_STICKY_COMPATIBILITY:
12652 case Service.START_STICKY: {
12653 // We are done with the associated start arguments.
12654 r.findDeliveredStart(startId, true);
12655 // Don't stop if killed.
12656 r.stopIfKilled = false;
12657 break;
12658 }
12659 case Service.START_NOT_STICKY: {
12660 // We are done with the associated start arguments.
12661 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012662 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012663 // There is no more work, and this service
12664 // doesn't want to hang around if killed.
12665 r.stopIfKilled = true;
12666 }
12667 break;
12668 }
12669 case Service.START_REDELIVER_INTENT: {
12670 // We'll keep this item until they explicitly
12671 // call stop for it, but keep track of the fact
12672 // that it was delivered.
12673 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12674 if (si != null) {
12675 si.deliveryCount = 0;
12676 si.doneExecutingCount++;
12677 // Don't stop if killed.
12678 r.stopIfKilled = true;
12679 }
12680 break;
12681 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012682 case Service.START_TASK_REMOVED_COMPLETE: {
12683 // Special processing for onTaskRemoved(). Don't
12684 // impact normal onStartCommand() processing.
12685 r.findDeliveredStart(startId, true);
12686 break;
12687 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012688 default:
12689 throw new IllegalArgumentException(
12690 "Unknown service start result: " + res);
12691 }
12692 if (res == Service.START_STICKY_COMPATIBILITY) {
12693 r.callStart = false;
12694 }
12695 }
Amith Yamasani742a6712011-05-04 14:49:28 -070012696 if (DEBUG_MU)
12697 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12698 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012699 final long origId = Binder.clearCallingIdentity();
12700 serviceDoneExecutingLocked(r, inStopping);
12701 Binder.restoreCallingIdentity(origId);
12702 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012703 Slog.w(TAG, "Done executing unknown service from pid "
12704 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012705 }
12706 }
12707 }
12708
12709 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012710 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12711 + ": nesting=" + r.executeNesting
12712 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012713 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012714 r.executeNesting--;
12715 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012716 if (DEBUG_SERVICE) Slog.v(TAG,
12717 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012718 r.app.executingServices.remove(r);
12719 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012720 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12721 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012722 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12723 }
12724 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012725 if (DEBUG_SERVICE) Slog.v(TAG,
12726 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012727 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020012728 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012729 }
12730 updateOomAdjLocked(r.app);
12731 }
12732 }
12733
12734 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012735 String anrMessage = null;
12736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012737 synchronized(this) {
12738 if (proc.executingServices.size() == 0 || proc.thread == null) {
12739 return;
12740 }
12741 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12742 Iterator<ServiceRecord> it = proc.executingServices.iterator();
12743 ServiceRecord timeout = null;
12744 long nextTime = 0;
12745 while (it.hasNext()) {
12746 ServiceRecord sr = it.next();
12747 if (sr.executingStart < maxTime) {
12748 timeout = sr;
12749 break;
12750 }
12751 if (sr.executingStart > nextTime) {
12752 nextTime = sr.executingStart;
12753 }
12754 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012755 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012756 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012757 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 } else {
12759 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12760 msg.obj = proc;
12761 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12762 }
12763 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012764
12765 if (anrMessage != null) {
12766 appNotResponding(proc, null, null, anrMessage);
12767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012768 }
12769
12770 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070012771 // BACKUP AND RESTORE
12772 // =========================================================
12773
12774 // Cause the target app to be launched if necessary and its backup agent
12775 // instantiated. The backup agent will invoke backupAgentCreated() on the
12776 // activity manager to announce its creation.
12777 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012778 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012779 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12780
12781 synchronized(this) {
12782 // !!! TODO: currently no check here that we're already bound
12783 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12784 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12785 synchronized (stats) {
12786 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12787 }
12788
Dianne Hackborne7f97212011-02-24 14:40:20 -080012789 // Backup agent is now in use, its package can't be stopped.
12790 try {
12791 AppGlobals.getPackageManager().setPackageStoppedState(
12792 app.packageName, false);
12793 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012794 } catch (IllegalArgumentException e) {
12795 Slog.w(TAG, "Failed trying to unstop package "
12796 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012797 }
12798
Christopher Tate181fafa2009-05-14 11:12:14 -070012799 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070012800 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12801 ? new ComponentName(app.packageName, app.backupAgentName)
12802 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070012803 // startProcessLocked() returns existing proc's record if it's already running
12804 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080012805 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070012806 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012807 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070012808 return false;
12809 }
12810
12811 r.app = proc;
12812 mBackupTarget = r;
12813 mBackupAppName = app.packageName;
12814
Christopher Tate6fa95972009-06-05 18:43:55 -070012815 // Try not to kill the process during backup
12816 updateOomAdjLocked(proc);
12817
Christopher Tate181fafa2009-05-14 11:12:14 -070012818 // If the process is already attached, schedule the creation of the backup agent now.
12819 // If it is not yet live, this will be done when it attaches to the framework.
12820 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012821 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070012822 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012823 proc.thread.scheduleCreateBackupAgent(app,
12824 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012825 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070012826 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070012827 }
12828 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012829 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070012830 }
12831 // Invariants: at this point, the target app process exists and the application
12832 // is either already running or in the process of coming up. mBackupTarget and
12833 // mBackupAppName describe the app, so that when it binds back to the AM we
12834 // know that it's scheduled for a backup-agent operation.
12835 }
12836
12837 return true;
12838 }
12839
12840 // A backup agent has just come up
12841 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012842 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070012843 + " = " + agent);
12844
12845 synchronized(this) {
12846 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012847 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070012848 return;
12849 }
Dianne Hackborn06740692010-09-22 22:46:21 -070012850 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012851
Dianne Hackborn06740692010-09-22 22:46:21 -070012852 long oldIdent = Binder.clearCallingIdentity();
12853 try {
12854 IBackupManager bm = IBackupManager.Stub.asInterface(
12855 ServiceManager.getService(Context.BACKUP_SERVICE));
12856 bm.agentConnected(agentPackageName, agent);
12857 } catch (RemoteException e) {
12858 // can't happen; the backup manager service is local
12859 } catch (Exception e) {
12860 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12861 e.printStackTrace();
12862 } finally {
12863 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070012864 }
12865 }
12866
12867 // done with this agent
12868 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012869 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070012870 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012871 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070012872 return;
12873 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012874
12875 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070012876 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012877 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070012878 return;
12879 }
12880
Christopher Tate181fafa2009-05-14 11:12:14 -070012881 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012882 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070012883 return;
12884 }
12885
Christopher Tate6fa95972009-06-05 18:43:55 -070012886 ProcessRecord proc = mBackupTarget.app;
12887 mBackupTarget = null;
12888 mBackupAppName = null;
12889
12890 // Not backing this app up any more; reset its OOM adjustment
12891 updateOomAdjLocked(proc);
12892
Christopher Tatec7b31e32009-06-10 15:49:30 -070012893 // If the app crashed during backup, 'thread' will be null here
12894 if (proc.thread != null) {
12895 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012896 proc.thread.scheduleDestroyBackupAgent(appInfo,
12897 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070012898 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012899 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070012900 e.printStackTrace();
12901 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012902 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012903 }
12904 }
12905 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906 // BROADCASTS
12907 // =========================================================
12908
Josh Bartel7f208742010-02-25 11:01:44 -060012909 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012910 List cur) {
12911 final ContentResolver resolver = mContext.getContentResolver();
12912 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12913 if (list == null) {
12914 return cur;
12915 }
12916 int N = list.size();
12917 for (int i=0; i<N; i++) {
12918 Intent intent = list.get(i);
12919 if (filter.match(resolver, intent, true, TAG) >= 0) {
12920 if (cur == null) {
12921 cur = new ArrayList<Intent>();
12922 }
12923 cur.add(intent);
12924 }
12925 }
12926 return cur;
12927 }
12928
Christopher Tatef46723b2012-01-26 14:19:24 -080012929 boolean isPendingBroadcastProcessLocked(int pid) {
12930 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12931 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012933
Christopher Tatef46723b2012-01-26 14:19:24 -080012934 void skipPendingBroadcastLocked(int pid) {
12935 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12936 for (BroadcastQueue queue : mBroadcastQueues) {
12937 queue.skipPendingBroadcastLocked(pid);
12938 }
12939 }
12940
12941 // The app just attached; send any pending broadcasts that it should receive
12942 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12943 boolean didSomething = false;
12944 for (BroadcastQueue queue : mBroadcastQueues) {
12945 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012946 }
Christopher Tatef46723b2012-01-26 14:19:24 -080012947 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012948 }
12949
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012950 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012951 IIntentReceiver receiver, IntentFilter filter, String permission) {
12952 synchronized(this) {
12953 ProcessRecord callerApp = null;
12954 if (caller != null) {
12955 callerApp = getRecordForAppLocked(caller);
12956 if (callerApp == null) {
12957 throw new SecurityException(
12958 "Unable to find app for caller " + caller
12959 + " (pid=" + Binder.getCallingPid()
12960 + ") when registering receiver " + receiver);
12961 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012962 if (callerApp.info.uid != Process.SYSTEM_UID &&
12963 !callerApp.pkgList.contains(callerPackage)) {
12964 throw new SecurityException("Given caller package " + callerPackage
12965 + " is not running in process " + callerApp);
12966 }
12967 } else {
12968 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012969 }
12970
12971 List allSticky = null;
12972
12973 // Look for any matching sticky broadcasts...
12974 Iterator actions = filter.actionsIterator();
12975 if (actions != null) {
12976 while (actions.hasNext()) {
12977 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012978 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012979 }
12980 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012981 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012982 }
12983
12984 // The first sticky in the list is returned directly back to
12985 // the client.
12986 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12987
Joe Onorato8a9b2202010-02-26 18:56:32 -080012988 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012989 + ": " + sticky);
12990
12991 if (receiver == null) {
12992 return sticky;
12993 }
12994
12995 ReceiverList rl
12996 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12997 if (rl == null) {
12998 rl = new ReceiverList(this, callerApp,
12999 Binder.getCallingPid(),
13000 Binder.getCallingUid(), receiver);
13001 if (rl.app != null) {
13002 rl.app.receivers.add(rl);
13003 } else {
13004 try {
13005 receiver.asBinder().linkToDeath(rl, 0);
13006 } catch (RemoteException e) {
13007 return sticky;
13008 }
13009 rl.linkedToDeath = true;
13010 }
13011 mRegisteredReceivers.put(receiver.asBinder(), rl);
13012 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013013 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 rl.add(bf);
13015 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013016 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017 }
13018 mReceiverResolver.addFilter(bf);
13019
13020 // Enqueue broadcasts for all existing stickies that match
13021 // this filter.
13022 if (allSticky != null) {
13023 ArrayList receivers = new ArrayList();
13024 receivers.add(bf);
13025
13026 int N = allSticky.size();
13027 for (int i=0; i<N; i++) {
13028 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080013029 BroadcastQueue queue = broadcastQueueForIntent(intent);
13030 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013031 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013032 false, true, true);
Christopher Tatef46723b2012-01-26 14:19:24 -080013033 queue.enqueueParallelBroadcastLocked(r);
13034 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013035 }
13036 }
13037
13038 return sticky;
13039 }
13040 }
13041
13042 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013043 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013044
Christopher Tatef46723b2012-01-26 14:19:24 -080013045 final long origId = Binder.clearCallingIdentity();
13046 try {
13047 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013048
Christopher Tatef46723b2012-01-26 14:19:24 -080013049 synchronized(this) {
13050 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013051 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080013052 if (rl != null) {
13053 if (rl.curBroadcast != null) {
13054 BroadcastRecord r = rl.curBroadcast;
13055 final boolean doNext = finishReceiverLocked(
13056 receiver.asBinder(), r.resultCode, r.resultData,
13057 r.resultExtras, r.resultAbort, true);
13058 if (doNext) {
13059 doTrim = true;
13060 r.queue.processNextBroadcast(false);
13061 }
13062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013063
Christopher Tatef46723b2012-01-26 14:19:24 -080013064 if (rl.app != null) {
13065 rl.app.receivers.remove(rl);
13066 }
13067 removeReceiverLocked(rl);
13068 if (rl.linkedToDeath) {
13069 rl.linkedToDeath = false;
13070 rl.receiver.asBinder().unlinkToDeath(rl, 0);
13071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013072 }
13073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013074
Christopher Tatef46723b2012-01-26 14:19:24 -080013075 // If we actually concluded any broadcasts, we might now be able
13076 // to trim the recipients' apps from our working set
13077 if (doTrim) {
13078 trimApplications();
13079 return;
13080 }
13081
13082 } finally {
13083 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013085 }
13086
13087 void removeReceiverLocked(ReceiverList rl) {
13088 mRegisteredReceivers.remove(rl.receiver.asBinder());
13089 int N = rl.size();
13090 for (int i=0; i<N; i++) {
13091 mReceiverResolver.removeFilter(rl.get(i));
13092 }
13093 }
13094
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013095 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
13096 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13097 ProcessRecord r = mLruProcesses.get(i);
13098 if (r.thread != null) {
13099 try {
13100 r.thread.dispatchPackageBroadcast(cmd, packages);
13101 } catch (RemoteException ex) {
13102 }
13103 }
13104 }
13105 }
13106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013107 private final int broadcastIntentLocked(ProcessRecord callerApp,
13108 String callerPackage, Intent intent, String resolvedType,
13109 IIntentReceiver resultTo, int resultCode, String resultData,
13110 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013111 boolean ordered, boolean sticky, int callingPid, int callingUid,
13112 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013113 intent = new Intent(intent);
13114
Dianne Hackborne7f97212011-02-24 14:40:20 -080013115 // By default broadcasts do not go to stopped apps.
13116 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13117
Joe Onorato8a9b2202010-02-26 18:56:32 -080013118 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013119 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13120 + " ordered=" + ordered);
13121 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013122 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013123 }
13124
13125 // Handle special intents: if this broadcast is from the package
13126 // manager about a package being removed, we need to remove all of
13127 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013128 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013129 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013130 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13131 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013132 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013133 || uidRemoved) {
13134 if (checkComponentPermission(
13135 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013136 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013137 == PackageManager.PERMISSION_GRANTED) {
13138 if (uidRemoved) {
13139 final Bundle intentExtras = intent.getExtras();
13140 final int uid = intentExtras != null
13141 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13142 if (uid >= 0) {
13143 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13144 synchronized (bs) {
13145 bs.removeUidStatsLocked(uid);
13146 }
13147 }
13148 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013149 // If resources are unvailble just force stop all
13150 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080013151 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013152 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13153 if (list != null && (list.length > 0)) {
13154 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070013155 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013156 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013157 sendPackageBroadcastLocked(
13158 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013159 }
13160 } else {
13161 Uri data = intent.getData();
13162 String ssp;
13163 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13164 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13165 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070013166 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070013167 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013168 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070013169 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13170 new String[] {ssp});
13171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013172 }
13173 }
13174 }
13175 } else {
13176 String msg = "Permission Denial: " + intent.getAction()
13177 + " broadcast from " + callerPackage + " (pid=" + callingPid
13178 + ", uid=" + callingUid + ")"
13179 + " requires "
13180 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013181 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013182 throw new SecurityException(msg);
13183 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013184
13185 // Special case for adding a package: by default turn on compatibility
13186 // mode.
13187 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070013188 Uri data = intent.getData();
13189 String ssp;
13190 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13191 mCompatModePackages.handlePackageAddedLocked(ssp,
13192 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013194 }
13195
13196 /*
13197 * If this is the time zone changed action, queue up a message that will reset the timezone
13198 * of all currently running processes. This message will get queued up before the broadcast
13199 * happens.
13200 */
13201 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13202 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13203 }
13204
Robert Greenwalt03595d02010-11-02 14:08:23 -070013205 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13206 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
13207 }
13208
Robert Greenwalt434203a2010-10-11 16:00:27 -070013209 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13210 ProxyProperties proxy = intent.getParcelableExtra("proxy");
13211 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
13212 }
13213
Dianne Hackborn854060af2009-07-09 18:14:31 -070013214 /*
13215 * Prevent non-system code (defined here to be non-persistent
13216 * processes) from sending protected broadcasts.
13217 */
13218 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
13219 || callingUid == Process.SHELL_UID || callingUid == 0) {
13220 // Always okay.
13221 } else if (callerApp == null || !callerApp.persistent) {
13222 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013223 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070013224 intent.getAction())) {
13225 String msg = "Permission Denial: not allowed to send broadcast "
13226 + intent.getAction() + " from pid="
13227 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013228 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013229 throw new SecurityException(msg);
13230 }
13231 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013232 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070013233 return BROADCAST_SUCCESS;
13234 }
13235 }
13236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013237 // Add to the sticky list if requested.
13238 if (sticky) {
13239 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13240 callingPid, callingUid)
13241 != PackageManager.PERMISSION_GRANTED) {
13242 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13243 + callingPid + ", uid=" + callingUid
13244 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013245 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013246 throw new SecurityException(msg);
13247 }
13248 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013249 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013250 + " and enforce permission " + requiredPermission);
13251 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13252 }
13253 if (intent.getComponent() != null) {
13254 throw new SecurityException(
13255 "Sticky broadcasts can't target a specific component");
13256 }
13257 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13258 if (list == null) {
13259 list = new ArrayList<Intent>();
13260 mStickyBroadcasts.put(intent.getAction(), list);
13261 }
13262 int N = list.size();
13263 int i;
13264 for (i=0; i<N; i++) {
13265 if (intent.filterEquals(list.get(i))) {
13266 // This sticky already exists, replace it.
13267 list.set(i, new Intent(intent));
13268 break;
13269 }
13270 }
13271 if (i >= N) {
13272 list.add(new Intent(intent));
13273 }
13274 }
13275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013276 // Figure out who all will receive this broadcast.
13277 List receivers = null;
13278 List<BroadcastFilter> registeredReceivers = null;
13279 try {
13280 if (intent.getComponent() != null) {
13281 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013282 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070013283 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013284 if (ai != null) {
13285 receivers = new ArrayList();
13286 ResolveInfo ri = new ResolveInfo();
Amith Yamasani742a6712011-05-04 14:49:28 -070013287 ri.activityInfo = getActivityInfoForUser(ai, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 receivers.add(ri);
13289 }
13290 } else {
Amith Yamasani742a6712011-05-04 14:49:28 -070013291 // TODO: Apply userId
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 // Need to resolve the intent to interested receivers...
13293 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13294 == 0) {
13295 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013296 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013297 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013298 }
Mihai Preda074edef2009-05-18 17:13:31 +020013299 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013300 }
13301 } catch (RemoteException ex) {
13302 // pm is in same process, this will never happen.
13303 }
13304
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013305 final boolean replacePending =
13306 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13307
Joe Onorato8a9b2202010-02-26 18:56:32 -080013308 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013309 + " replacePending=" + replacePending);
13310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013311 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13312 if (!ordered && NR > 0) {
13313 // If we are not serializing this broadcast, then send the
13314 // registered receivers separately so they don't wait for the
13315 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080013316 final BroadcastQueue queue = broadcastQueueForIntent(intent);
13317 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013318 callerPackage, callingPid, callingUid, requiredPermission,
13319 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013320 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013321 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080013322 TAG, "Enqueueing parallel broadcast " + r);
13323 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013324 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013325 queue.enqueueParallelBroadcastLocked(r);
13326 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013328 registeredReceivers = null;
13329 NR = 0;
13330 }
13331
13332 // Merge into one list.
13333 int ir = 0;
13334 if (receivers != null) {
13335 // A special case for PACKAGE_ADDED: do not allow the package
13336 // being added to see this broadcast. This prevents them from
13337 // using this as a back door to get run as soon as they are
13338 // installed. Maybe in the future we want to have a special install
13339 // broadcast or such for apps, but we'd like to deliberately make
13340 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013341 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013342 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13343 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13344 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013345 Uri data = intent.getData();
13346 if (data != null) {
13347 String pkgName = data.getSchemeSpecificPart();
13348 if (pkgName != null) {
13349 skipPackages = new String[] { pkgName };
13350 }
13351 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013352 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013353 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070013354 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013355 if (skipPackages != null && (skipPackages.length > 0)) {
13356 for (String skipPackage : skipPackages) {
13357 if (skipPackage != null) {
13358 int NT = receivers.size();
13359 for (int it=0; it<NT; it++) {
13360 ResolveInfo curt = (ResolveInfo)receivers.get(it);
13361 if (curt.activityInfo.packageName.equals(skipPackage)) {
13362 receivers.remove(it);
13363 it--;
13364 NT--;
13365 }
13366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013367 }
13368 }
13369 }
13370
13371 int NT = receivers != null ? receivers.size() : 0;
13372 int it = 0;
13373 ResolveInfo curt = null;
13374 BroadcastFilter curr = null;
13375 while (it < NT && ir < NR) {
13376 if (curt == null) {
13377 curt = (ResolveInfo)receivers.get(it);
13378 }
13379 if (curr == null) {
13380 curr = registeredReceivers.get(ir);
13381 }
13382 if (curr.getPriority() >= curt.priority) {
13383 // Insert this broadcast record into the final list.
13384 receivers.add(it, curr);
13385 ir++;
13386 curr = null;
13387 it++;
13388 NT++;
13389 } else {
13390 // Skip to the next ResolveInfo in the final list.
13391 it++;
13392 curt = null;
13393 }
13394 }
13395 }
13396 while (ir < NR) {
13397 if (receivers == null) {
13398 receivers = new ArrayList();
13399 }
13400 receivers.add(registeredReceivers.get(ir));
13401 ir++;
13402 }
13403
13404 if ((receivers != null && receivers.size() > 0)
13405 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013406 BroadcastQueue queue = broadcastQueueForIntent(intent);
13407 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013409 receivers, resultTo, resultCode, resultData, map, ordered,
13410 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013411 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013412 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080013413 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013414 if (DEBUG_BROADCAST) {
13415 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013416 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013417 }
Christopher Tatef46723b2012-01-26 14:19:24 -080013418 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013419 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013420 queue.enqueueOrderedBroadcastLocked(r);
13421 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013423 }
13424
13425 return BROADCAST_SUCCESS;
13426 }
13427
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013428 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013429 // Refuse possible leaked file descriptors
13430 if (intent != null && intent.hasFileDescriptors() == true) {
13431 throw new IllegalArgumentException("File descriptors passed in Intent");
13432 }
13433
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013434 int flags = intent.getFlags();
13435
13436 if (!mProcessesReady) {
13437 // if the caller really truly claims to know what they're doing, go
13438 // ahead and allow the broadcast without launching any receivers
13439 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13440 intent = new Intent(intent);
13441 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13442 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13443 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13444 + " before boot completion");
13445 throw new IllegalStateException("Cannot broadcast before boot completed");
13446 }
13447 }
13448
13449 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13450 throw new IllegalArgumentException(
13451 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13452 }
13453
13454 return intent;
13455 }
13456
13457 public final int broadcastIntent(IApplicationThread caller,
13458 Intent intent, String resolvedType, IIntentReceiver resultTo,
13459 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013460 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013461 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013462 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013464 final ProcessRecord callerApp = getRecordForAppLocked(caller);
13465 final int callingPid = Binder.getCallingPid();
13466 final int callingUid = Binder.getCallingUid();
13467 final long origId = Binder.clearCallingIdentity();
13468 int res = broadcastIntentLocked(callerApp,
13469 callerApp != null ? callerApp.info.packageName : null,
13470 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070013471 resultCode, resultData, map, requiredPermission, serialized, sticky,
13472 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013473 Binder.restoreCallingIdentity(origId);
13474 return res;
13475 }
13476 }
13477
13478 int broadcastIntentInPackage(String packageName, int uid,
13479 Intent intent, String resolvedType, IIntentReceiver resultTo,
13480 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013481 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013482 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013483 intent = verifyBroadcastLocked(intent);
13484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013485 final long origId = Binder.clearCallingIdentity();
13486 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13487 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013488 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013489 Binder.restoreCallingIdentity(origId);
13490 return res;
13491 }
13492 }
13493
Amith Yamasani742a6712011-05-04 14:49:28 -070013494 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13495 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013496 // Refuse possible leaked file descriptors
13497 if (intent != null && intent.hasFileDescriptors() == true) {
13498 throw new IllegalArgumentException("File descriptors passed in Intent");
13499 }
13500
13501 synchronized(this) {
13502 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13503 != PackageManager.PERMISSION_GRANTED) {
13504 String msg = "Permission Denial: unbroadcastIntent() from pid="
13505 + Binder.getCallingPid()
13506 + ", uid=" + Binder.getCallingUid()
13507 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013508 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013509 throw new SecurityException(msg);
13510 }
13511 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13512 if (list != null) {
13513 int N = list.size();
13514 int i;
13515 for (i=0; i<N; i++) {
13516 if (intent.filterEquals(list.get(i))) {
13517 list.remove(i);
13518 break;
13519 }
13520 }
13521 }
13522 }
13523 }
13524
13525 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13526 String resultData, Bundle resultExtras, boolean resultAbort,
13527 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013528 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13529 if (r == null) {
13530 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 return false;
13532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013533
Christopher Tatef46723b2012-01-26 14:19:24 -080013534 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13535 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013536 }
13537
13538 public void finishReceiver(IBinder who, int resultCode, String resultData,
13539 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013540 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013541
13542 // Refuse possible leaked file descriptors
13543 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13544 throw new IllegalArgumentException("File descriptors passed in Bundle");
13545 }
13546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013547 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080013548 try {
13549 boolean doNext = false;
13550 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013551
Christopher Tatef46723b2012-01-26 14:19:24 -080013552 synchronized(this) {
13553 r = broadcastRecordForReceiverLocked(who);
13554 if (r != null) {
13555 doNext = r.queue.finishReceiverLocked(r, resultCode,
13556 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013558 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013559
Christopher Tatef46723b2012-01-26 14:19:24 -080013560 if (doNext) {
13561 r.queue.processNextBroadcast(false);
13562 }
13563 trimApplications();
13564 } finally {
13565 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070013566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013567 }
13568
13569 private final void processCurBroadcastLocked(BroadcastRecord r,
13570 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013571 if (DEBUG_BROADCAST) Slog.v(TAG,
13572 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013573 if (app.thread == null) {
13574 throw new RemoteException();
13575 }
13576 r.receiver = app.thread.asBinder();
13577 r.curApp = app;
13578 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013579 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013580
13581 // Tell the application to launch this receiver.
13582 r.intent.setComponent(r.curComponent);
13583
13584 boolean started = false;
13585 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013586 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013587 "Delivering to component " + r.curComponent
13588 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070013589 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013590 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040013591 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013592 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013593 if (DEBUG_BROADCAST) Slog.v(TAG,
13594 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013595 started = true;
13596 } finally {
13597 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013598 if (DEBUG_BROADCAST) Slog.v(TAG,
13599 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013600 r.receiver = null;
13601 r.curApp = null;
13602 app.curReceiver = null;
13603 }
13604 }
13605
13606 }
13607
Jeff Brown4d94a762010-09-23 11:33:28 -070013608 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013609 Intent intent, int resultCode, String data, Bundle extras,
13610 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070013611 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013612 if (app != null && app.thread != null) {
13613 // If we have an app thread, do the call through that so it is
13614 // correctly ordered with other one-way calls.
13615 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013616 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013617 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013618 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013619 }
13620 }
13621
Jeff Brown4d94a762010-09-23 11:33:28 -070013622 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013623 BroadcastFilter filter, boolean ordered) {
13624 boolean skip = false;
13625 if (filter.requiredPermission != null) {
13626 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013627 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013628 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013629 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013630 + r.intent.toString()
13631 + " from " + r.callerPackage + " (pid="
13632 + r.callingPid + ", uid=" + r.callingUid + ")"
13633 + " requires " + filter.requiredPermission
13634 + " due to registered receiver " + filter);
13635 skip = true;
13636 }
13637 }
13638 if (r.requiredPermission != null) {
13639 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013640 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013641 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013642 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013643 + r.intent.toString()
13644 + " to " + filter.receiverList.app
13645 + " (pid=" + filter.receiverList.pid
13646 + ", uid=" + filter.receiverList.uid + ")"
13647 + " requires " + r.requiredPermission
13648 + " due to sender " + r.callerPackage
13649 + " (uid " + r.callingUid + ")");
13650 skip = true;
13651 }
13652 }
13653
13654 if (!skip) {
13655 // If this is not being sent as an ordered broadcast, then we
13656 // don't want to touch the fields that keep track of the current
13657 // state of ordered broadcasts.
13658 if (ordered) {
13659 r.receiver = filter.receiverList.receiver.asBinder();
13660 r.curFilter = filter;
13661 filter.receiverList.curBroadcast = r;
13662 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013663 if (filter.receiverList.app != null) {
13664 // Bump hosting application to no longer be in background
13665 // scheduling class. Note that we can't do that if there
13666 // isn't an app... but we can only be in that case for
13667 // things that directly call the IActivityManager API, which
13668 // are already core system stuff so don't matter for this.
13669 r.curApp = filter.receiverList.app;
13670 filter.receiverList.app.curReceiver = r;
13671 updateOomAdjLocked();
13672 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013673 }
13674 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013675 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013676 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013677 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013678 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013679 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013680 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013681 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013682 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013683 if (ordered) {
13684 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
13685 }
13686 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013687 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013688 if (ordered) {
13689 r.receiver = null;
13690 r.curFilter = null;
13691 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013692 if (filter.receiverList.app != null) {
13693 filter.receiverList.app.curReceiver = null;
13694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013695 }
13696 }
13697 }
13698 }
13699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013700 // =========================================================
13701 // INSTRUMENTATION
13702 // =========================================================
13703
13704 public boolean startInstrumentation(ComponentName className,
13705 String profileFile, int flags, Bundle arguments,
13706 IInstrumentationWatcher watcher) {
13707 // Refuse possible leaked file descriptors
13708 if (arguments != null && arguments.hasFileDescriptors()) {
13709 throw new IllegalArgumentException("File descriptors passed in Bundle");
13710 }
13711
13712 synchronized(this) {
13713 InstrumentationInfo ii = null;
13714 ApplicationInfo ai = null;
13715 try {
13716 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013717 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013718 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013719 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013720 } catch (PackageManager.NameNotFoundException e) {
13721 }
13722 if (ii == null) {
13723 reportStartInstrumentationFailure(watcher, className,
13724 "Unable to find instrumentation info for: " + className);
13725 return false;
13726 }
13727 if (ai == null) {
13728 reportStartInstrumentationFailure(watcher, className,
13729 "Unable to find instrumentation target package: " + ii.targetPackage);
13730 return false;
13731 }
13732
13733 int match = mContext.getPackageManager().checkSignatures(
13734 ii.targetPackage, ii.packageName);
13735 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13736 String msg = "Permission Denial: starting instrumentation "
13737 + className + " from pid="
13738 + Binder.getCallingPid()
13739 + ", uid=" + Binder.getCallingPid()
13740 + " not allowed because package " + ii.packageName
13741 + " does not have a signature matching the target "
13742 + ii.targetPackage;
13743 reportStartInstrumentationFailure(watcher, className, msg);
13744 throw new SecurityException(msg);
13745 }
13746
13747 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013748 // Instrumentation can kill and relaunch even persistent processes
13749 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013750 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013751 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013752 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013753 app.instrumentationProfileFile = profileFile;
13754 app.instrumentationArguments = arguments;
13755 app.instrumentationWatcher = watcher;
13756 app.instrumentationResultClass = className;
13757 Binder.restoreCallingIdentity(origId);
13758 }
13759
13760 return true;
13761 }
13762
13763 /**
13764 * Report errors that occur while attempting to start Instrumentation. Always writes the
13765 * error to the logs, but if somebody is watching, send the report there too. This enables
13766 * the "am" command to report errors with more information.
13767 *
13768 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13769 * @param cn The component name of the instrumentation.
13770 * @param report The error report.
13771 */
13772 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13773 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013774 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013775 try {
13776 if (watcher != null) {
13777 Bundle results = new Bundle();
13778 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13779 results.putString("Error", report);
13780 watcher.instrumentationStatus(cn, -1, results);
13781 }
13782 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013783 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013784 }
13785 }
13786
13787 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13788 if (app.instrumentationWatcher != null) {
13789 try {
13790 // NOTE: IInstrumentationWatcher *must* be oneway here
13791 app.instrumentationWatcher.instrumentationFinished(
13792 app.instrumentationClass,
13793 resultCode,
13794 results);
13795 } catch (RemoteException e) {
13796 }
13797 }
13798 app.instrumentationWatcher = null;
13799 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013800 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013801 app.instrumentationProfileFile = null;
13802 app.instrumentationArguments = null;
13803
Christopher Tate3dacd842011-08-19 14:56:15 -070013804 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013805 }
13806
13807 public void finishInstrumentation(IApplicationThread target,
13808 int resultCode, Bundle results) {
13809 // Refuse possible leaked file descriptors
13810 if (results != null && results.hasFileDescriptors()) {
13811 throw new IllegalArgumentException("File descriptors passed in Intent");
13812 }
13813
13814 synchronized(this) {
13815 ProcessRecord app = getRecordForAppLocked(target);
13816 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013817 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013818 return;
13819 }
13820 final long origId = Binder.clearCallingIdentity();
13821 finishInstrumentationLocked(app, resultCode, results);
13822 Binder.restoreCallingIdentity(origId);
13823 }
13824 }
13825
13826 // =========================================================
13827 // CONFIGURATION
13828 // =========================================================
13829
13830 public ConfigurationInfo getDeviceConfigurationInfo() {
13831 ConfigurationInfo config = new ConfigurationInfo();
13832 synchronized (this) {
13833 config.reqTouchScreen = mConfiguration.touchscreen;
13834 config.reqKeyboardType = mConfiguration.keyboard;
13835 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013836 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13837 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013838 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13839 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013840 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13841 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013842 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13843 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013844 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013845 }
13846 return config;
13847 }
13848
13849 public Configuration getConfiguration() {
13850 Configuration ci;
13851 synchronized(this) {
13852 ci = new Configuration(mConfiguration);
13853 }
13854 return ci;
13855 }
13856
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013857 public void updatePersistentConfiguration(Configuration values) {
13858 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13859 "updateConfiguration()");
13860 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13861 "updateConfiguration()");
13862 if (values == null) {
13863 throw new NullPointerException("Configuration must not be null");
13864 }
13865
13866 synchronized(this) {
13867 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013868 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013869 Binder.restoreCallingIdentity(origId);
13870 }
13871 }
13872
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013873 public void updateConfiguration(Configuration values) {
13874 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13875 "updateConfiguration()");
13876
13877 synchronized(this) {
13878 if (values == null && mWindowManager != null) {
13879 // sentinel: fetch the current configuration from the window manager
13880 values = mWindowManager.computeNewConfiguration();
13881 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013882
13883 if (mWindowManager != null) {
13884 mProcessList.applyDisplaySize(mWindowManager);
13885 }
13886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013887 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013888 if (values != null) {
13889 Settings.System.clearConfiguration(values);
13890 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013891 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013892 Binder.restoreCallingIdentity(origId);
13893 }
13894 }
13895
13896 /**
13897 * Do either or both things: (1) change the current configuration, and (2)
13898 * make sure the given activity is running with the (now) current
13899 * configuration. Returns true if the activity has been left running, or
13900 * false if <var>starting</var> is being destroyed to match the new
13901 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013902 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013903 */
13904 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013905 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013906 int changes = 0;
13907
13908 boolean kept = true;
13909
13910 if (values != null) {
13911 Configuration newConfig = new Configuration(mConfiguration);
13912 changes = newConfig.updateFrom(values);
13913 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013914 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013915 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013916 }
13917
Doug Zongker2bec3d42009-12-04 12:52:44 -080013918 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013919
Dianne Hackborn813075a62011-11-14 17:45:19 -080013920 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013921 saveLocaleLocked(values.locale,
13922 !values.locale.equals(mConfiguration.locale),
13923 values.userSetLocale);
13924 }
13925
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013926 mConfigurationSeq++;
13927 if (mConfigurationSeq <= 0) {
13928 mConfigurationSeq = 1;
13929 }
13930 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013931 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013932 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013933
13934 final Configuration configCopy = new Configuration(mConfiguration);
13935
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013936 AttributeCache ac = AttributeCache.instance();
13937 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013938 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013940
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013941 // Make sure all resources in our process are updated
13942 // right now, so that anyone who is going to retrieve
13943 // resource values after we return will be sure to get
13944 // the new ones. This is especially important during
13945 // boot, where the first config change needs to guarantee
13946 // all resources have that config before following boot
13947 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013948 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013949
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013950 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013951 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013952 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013953 mHandler.sendMessage(msg);
13954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013955
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013956 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13957 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013958 try {
13959 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013960 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013961 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013962 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013963 }
13964 } catch (Exception e) {
13965 }
13966 }
13967 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013968 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13969 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013970 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013971 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013972 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13973 broadcastIntentLocked(null, null,
13974 new Intent(Intent.ACTION_LOCALE_CHANGED),
13975 null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013976 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013978 }
13979 }
13980
13981 if (changes != 0 && starting == null) {
13982 // If the configuration changed, and the caller is not already
13983 // in the process of starting an activity, then find the top
13984 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013985 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013986 }
13987
13988 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013989 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013990 // And we need to make sure at this point that all other activities
13991 // are made visible with the correct configuration.
13992 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013993 }
13994
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013995 if (values != null && mWindowManager != null) {
13996 mWindowManager.setNewConfiguration(mConfiguration);
13997 }
13998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013999 return kept;
14000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014001
14002 /**
14003 * Save the locale. You must be inside a synchronized (this) block.
14004 */
14005 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14006 if(isDiff) {
14007 SystemProperties.set("user.language", l.getLanguage());
14008 SystemProperties.set("user.region", l.getCountry());
14009 }
14010
14011 if(isPersist) {
14012 SystemProperties.set("persist.sys.language", l.getLanguage());
14013 SystemProperties.set("persist.sys.country", l.getCountry());
14014 SystemProperties.set("persist.sys.localevar", l.getVariant());
14015 }
14016 }
14017
14018 // =========================================================
14019 // LIFETIME MANAGEMENT
14020 // =========================================================
14021
Christopher Tatef46723b2012-01-26 14:19:24 -080014022 // Returns which broadcast queue the app is the current [or imminent] receiver
14023 // on, or 'null' if the app is not an active broadcast recipient.
14024 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14025 BroadcastRecord r = app.curReceiver;
14026 if (r != null) {
14027 return r.queue;
14028 }
14029
14030 // It's not the current receiver, but it might be starting up to become one
14031 synchronized (this) {
14032 for (BroadcastQueue queue : mBroadcastQueues) {
14033 r = queue.mPendingBroadcast;
14034 if (r != null && r.curApp == app) {
14035 // found it; report which queue it's in
14036 return queue;
14037 }
14038 }
14039 }
14040
14041 return null;
14042 }
14043
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014044 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014045 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014046 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014047 // This adjustment has already been computed. If we are calling
14048 // from the top, we may have already computed our adjustment with
14049 // an earlier hidden adjustment that isn't really for us... if
14050 // so, use the new hidden adjustment.
14051 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014052 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014053 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014054 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014055 }
14056
14057 if (app.thread == null) {
14058 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014059 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014060 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014061 }
14062
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014063 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14064 app.adjSource = null;
14065 app.adjTarget = null;
14066 app.empty = false;
14067 app.hidden = false;
14068
14069 final int activitiesSize = app.activities.size();
14070
Dianne Hackborn7d608422011-08-07 16:24:18 -070014071 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014072 // The max adjustment doesn't allow this app to be anything
14073 // below foreground, so it is not worth doing work for it.
14074 app.adjType = "fixed";
14075 app.adjSeq = mAdjSeq;
14076 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014077 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014078 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014079 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014080 // System process can do UI, and when they do we want to have
14081 // them trim their memory after the user leaves the UI. To
14082 // facilitate this, here we need to determine whether or not it
14083 // is currently showing UI.
14084 app.systemNoUi = true;
14085 if (app == TOP_APP) {
14086 app.systemNoUi = false;
14087 } else if (activitiesSize > 0) {
14088 for (int j = 0; j < activitiesSize; j++) {
14089 final ActivityRecord r = app.activities.get(j);
14090 if (r.visible) {
14091 app.systemNoUi = false;
14092 break;
14093 }
14094 }
14095 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014096 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014097 }
14098
14099 final boolean hadForegroundActivities = app.foregroundActivities;
14100
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014101 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014102 app.keeping = false;
14103 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014104
The Android Open Source Project4df24232009-03-05 14:34:35 -080014105 // Determine the importance of the process, starting with most
14106 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014107 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014108 int schedGroup;
Christopher Tatef46723b2012-01-26 14:19:24 -080014109 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014110 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014111 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014112 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014113 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014114 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014115 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014116 } else if (app.instrumentationClass != null) {
14117 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014118 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014119 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014120 app.adjType = "instrumentation";
Christopher Tatef46723b2012-01-26 14:19:24 -080014121 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014122 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080014123 // counts as being in the foreground for OOM killer purposes.
14124 // It's placed in a sched group based on the nature of the
14125 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014126 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080014127 schedGroup = (queue == mFgBroadcastQueue)
14128 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014129 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014130 } else if (app.executingServices.size() > 0) {
14131 // An app that is currently executing a service callback also
14132 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014133 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014134 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014135 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014136 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014137 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014138 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014139 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014140 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014141 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014142 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014143 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014144 // A very not-needed process. If this is lower in the lru list,
14145 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014146 adj = hiddenAdj;
14147 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014148 app.hidden = true;
14149 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014150 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014151 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014152
14153 // Examine all activities if not already foreground.
14154 if (!app.foregroundActivities && activitiesSize > 0) {
14155 for (int j = 0; j < activitiesSize; j++) {
14156 final ActivityRecord r = app.activities.get(j);
14157 if (r.visible) {
14158 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014159 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14160 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014161 app.adjType = "visible";
14162 }
14163 schedGroup = Process.THREAD_GROUP_DEFAULT;
14164 app.hidden = false;
14165 app.foregroundActivities = true;
14166 break;
14167 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
14168 || r.state == ActivityState.STOPPING) {
14169 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014170 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14171 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014172 app.adjType = "stopping";
14173 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080014174 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014175 app.foregroundActivities = true;
14176 }
14177 }
14178 }
14179
Dianne Hackborn7d608422011-08-07 16:24:18 -070014180 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014181 if (app.foregroundServices) {
14182 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014183 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014184 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014185 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014186 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014187 } else if (app.forcingToForeground != null) {
14188 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014189 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014190 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014191 app.adjType = "force-foreground";
14192 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014193 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014194 }
14195 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014196
Dianne Hackborn7d608422011-08-07 16:24:18 -070014197 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014198 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014199 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014200 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014201 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014202 app.adjType = "heavy";
14203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014204
Dianne Hackborn7d608422011-08-07 16:24:18 -070014205 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014206 // This process is hosting what we currently consider to be the
14207 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014208 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014209 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014210 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080014211 app.adjType = "home";
14212 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014213
Dianne Hackbornf35fe232011-11-01 19:25:20 -070014214 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
14215 && app.activities.size() > 0) {
14216 // This was the previous process that showed UI to the user.
14217 // We want to try to keep it around more aggressively, to give
14218 // a good experience around switching between two apps.
14219 adj = ProcessList.PREVIOUS_APP_ADJ;
14220 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14221 app.hidden = false;
14222 app.adjType = "previous";
14223 }
14224
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014225 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14226 + " reason=" + app.adjType);
14227
The Android Open Source Project4df24232009-03-05 14:34:35 -080014228 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014229 // there are applications dependent on our services or providers, but
14230 // this gives us a baseline and makes sure we don't get into an
14231 // infinite recursion.
14232 app.adjSeq = mAdjSeq;
14233 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014234
Christopher Tate6fa95972009-06-05 18:43:55 -070014235 if (mBackupTarget != null && app == mBackupTarget.app) {
14236 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070014237 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014238 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014239 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014240 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014241 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070014242 }
14243 }
14244
Dianne Hackborn7d608422011-08-07 16:24:18 -070014245 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014246 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014247 final long now = SystemClock.uptimeMillis();
14248 // This process is more important if the top activity is
14249 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070014250 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014251 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014252 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014253 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014254 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014255 // If this process has shown some UI, let it immediately
14256 // go to the LRU list because it may be pretty heavy with
14257 // UI stuff. We'll tag it with a label just to help
14258 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014259 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014260 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014261 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014262 } else {
14263 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14264 // This service has seen some activity within
14265 // recent memory, so we will keep its process ahead
14266 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014267 if (adj > ProcessList.SERVICE_ADJ) {
14268 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014269 app.adjType = "started-services";
14270 app.hidden = false;
14271 }
14272 }
14273 // If we have let the service slide into the background
14274 // state, still have some text describing what it is doing
14275 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014276 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014277 app.adjType = "started-bg-services";
14278 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014279 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014280 // Don't kill this process because it is doing work; it
14281 // has said it is doing work.
14282 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014283 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014284 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014285 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014286 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014287 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014288 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014289 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014290 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014291 // XXX should compute this based on the max of
14292 // all connected clients.
14293 ConnectionRecord cr = clist.get(i);
14294 if (cr.binding.client == app) {
14295 // Binding to ourself is not interesting.
14296 continue;
14297 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014298 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014299 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014300 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014301 int myHiddenAdj = hiddenAdj;
14302 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014303 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014304 myHiddenAdj = client.hiddenAdj;
14305 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014306 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014307 }
14308 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014309 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014310 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014311 String adjType = null;
14312 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14313 // Not doing bind OOM management, so treat
14314 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014315 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014316 // If this process has shown some UI, let it immediately
14317 // go to the LRU list because it may be pretty heavy with
14318 // UI stuff. We'll tag it with a label just to help
14319 // debug and understand what is going on.
14320 if (adj > clientAdj) {
14321 adjType = "bound-bg-ui-services";
14322 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014323 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014324 clientAdj = adj;
14325 } else {
14326 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14327 // This service has not seen activity within
14328 // recent memory, so allow it to drop to the
14329 // LRU list if there is no other reason to keep
14330 // it around. We'll also tag it with a label just
14331 // to help debug and undertand what is going on.
14332 if (adj > clientAdj) {
14333 adjType = "bound-bg-services";
14334 }
14335 clientAdj = adj;
14336 }
14337 }
14338 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014339 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014340 // If this process has recently shown UI, and
14341 // the process that is binding to it is less
14342 // important than being visible, then we don't
14343 // care about the binding as much as we care
14344 // about letting this process get into the LRU
14345 // list to be killed and restarted if needed for
14346 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014347 if (app.hasShownUi && app != mHomeProcess
14348 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014349 adjType = "bound-bg-ui-services";
14350 } else {
14351 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14352 |Context.BIND_IMPORTANT)) != 0) {
14353 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014354 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14355 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14356 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14357 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14358 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014359 adj = clientAdj;
14360 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014361 app.pendingUiClean = true;
14362 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14363 adj = ProcessList.VISIBLE_APP_ADJ;
14364 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014365 }
14366 if (!client.hidden) {
14367 app.hidden = false;
14368 }
14369 if (client.keeping) {
14370 app.keeping = true;
14371 }
14372 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014373 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014374 }
14375 if (adjType != null) {
14376 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014377 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14378 .REASON_SERVICE_IN_USE;
14379 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014380 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014381 app.adjTarget = s.name;
14382 }
14383 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14384 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14385 schedGroup = Process.THREAD_GROUP_DEFAULT;
14386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014387 }
14388 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014389 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14390 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014391 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014392 (a.visible || a.state == ActivityState.RESUMED
14393 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014394 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014395 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14396 schedGroup = Process.THREAD_GROUP_DEFAULT;
14397 }
14398 app.hidden = false;
14399 app.adjType = "service";
14400 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14401 .REASON_SERVICE_IN_USE;
14402 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014403 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014404 app.adjTarget = s.name;
14405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014407 }
14408 }
14409 }
14410 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014411
Dianne Hackborn287952c2010-09-22 22:34:31 -070014412 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014413 // would like to avoid killing it unless it would prevent the current
14414 // application from running. By default we put the process in
14415 // with the rest of the background processes; as we scan through
14416 // its services we may bump it up from there.
14417 if (adj > hiddenAdj) {
14418 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014419 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014420 app.adjType = "bg-services";
14421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014422 }
14423
Dianne Hackborn7d608422011-08-07 16:24:18 -070014424 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014425 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014426 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014427 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014428 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014429 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014430 if (cpr.clients.size() != 0) {
14431 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014432 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014433 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070014434 if (client == app) {
14435 // Being our own client is not interesting.
14436 continue;
14437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014438 int myHiddenAdj = hiddenAdj;
14439 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014440 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014441 myHiddenAdj = client.hiddenAdj;
14442 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014443 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014444 }
14445 }
14446 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014447 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014448 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014449 if (app.hasShownUi && app != mHomeProcess
14450 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014451 app.adjType = "bg-ui-provider";
14452 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014453 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14454 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014455 app.adjType = "provider";
14456 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014457 if (!client.hidden) {
14458 app.hidden = false;
14459 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014460 if (client.keeping) {
14461 app.keeping = true;
14462 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070014463 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14464 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014465 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014466 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014467 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014468 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014469 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14470 schedGroup = Process.THREAD_GROUP_DEFAULT;
14471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014472 }
14473 }
14474 // If the provider has external (non-framework) process
14475 // dependencies, ensure that its adjustment is at least
14476 // FOREGROUND_APP_ADJ.
14477 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014478 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14479 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014480 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014481 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014482 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014483 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014484 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014485 }
14486 }
14487 }
14488 }
14489
14490 app.curRawAdj = adj;
14491
Joe Onorato8a9b2202010-02-26 18:56:32 -080014492 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014493 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14494 if (adj > app.maxAdj) {
14495 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014496 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014497 schedGroup = Process.THREAD_GROUP_DEFAULT;
14498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014499 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014500 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014501 app.keeping = true;
14502 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014503
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014504 if (app.hasAboveClient) {
14505 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14506 // then we need to drop its adjustment to be lower than the service's
14507 // in order to honor the request. We want to drop it by one adjustment
14508 // level... but there is special meaning applied to various levels so
14509 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014510 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014511 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014512 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14513 adj = ProcessList.VISIBLE_APP_ADJ;
14514 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14515 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14516 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14517 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014518 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014519 adj++;
14520 }
14521 }
14522
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014523 if (adj == ProcessList.SERVICE_ADJ) {
14524 if (doingAll) {
14525 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14526 mNewNumServiceProcs++;
14527 }
14528 if (app.serviceb) {
14529 adj = ProcessList.SERVICE_B_ADJ;
14530 }
14531 } else {
14532 app.serviceb = false;
14533 }
14534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014535 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014536 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014537
14538 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014539 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14540 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014541 }
14542
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014543 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014544 }
14545
14546 /**
14547 * Ask a given process to GC right now.
14548 */
14549 final void performAppGcLocked(ProcessRecord app) {
14550 try {
14551 app.lastRequestedGc = SystemClock.uptimeMillis();
14552 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014553 if (app.reportLowMemory) {
14554 app.reportLowMemory = false;
14555 app.thread.scheduleLowMemory();
14556 } else {
14557 app.thread.processInBackground();
14558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014559 }
14560 } catch (Exception e) {
14561 // whatever.
14562 }
14563 }
14564
14565 /**
14566 * Returns true if things are idle enough to perform GCs.
14567 */
Josh Bartel7f208742010-02-25 11:01:44 -060014568 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080014569 boolean processingBroadcasts = false;
14570 for (BroadcastQueue q : mBroadcastQueues) {
14571 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14572 processingBroadcasts = true;
14573 }
14574 }
14575 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014576 && (mSleeping || (mMainStack.mResumedActivity != null &&
14577 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014578 }
14579
14580 /**
14581 * Perform GCs on all processes that are waiting for it, but only
14582 * if things are idle.
14583 */
14584 final void performAppGcsLocked() {
14585 final int N = mProcessesToGc.size();
14586 if (N <= 0) {
14587 return;
14588 }
Josh Bartel7f208742010-02-25 11:01:44 -060014589 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014590 while (mProcessesToGc.size() > 0) {
14591 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014592 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014593 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14594 <= SystemClock.uptimeMillis()) {
14595 // To avoid spamming the system, we will GC processes one
14596 // at a time, waiting a few seconds between each.
14597 performAppGcLocked(proc);
14598 scheduleAppGcsLocked();
14599 return;
14600 } else {
14601 // It hasn't been long enough since we last GCed this
14602 // process... put it in the list to wait for its time.
14603 addProcessToGcListLocked(proc);
14604 break;
14605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014606 }
14607 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014608
14609 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014610 }
14611 }
14612
14613 /**
14614 * If all looks good, perform GCs on all processes waiting for them.
14615 */
14616 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014617 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014618 performAppGcsLocked();
14619 return;
14620 }
14621 // Still not idle, wait some more.
14622 scheduleAppGcsLocked();
14623 }
14624
14625 /**
14626 * Schedule the execution of all pending app GCs.
14627 */
14628 final void scheduleAppGcsLocked() {
14629 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014630
14631 if (mProcessesToGc.size() > 0) {
14632 // Schedule a GC for the time to the next process.
14633 ProcessRecord proc = mProcessesToGc.get(0);
14634 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14635
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014636 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014637 long now = SystemClock.uptimeMillis();
14638 if (when < (now+GC_TIMEOUT)) {
14639 when = now + GC_TIMEOUT;
14640 }
14641 mHandler.sendMessageAtTime(msg, when);
14642 }
14643 }
14644
14645 /**
14646 * Add a process to the array of processes waiting to be GCed. Keeps the
14647 * list in sorted order by the last GC time. The process can't already be
14648 * on the list.
14649 */
14650 final void addProcessToGcListLocked(ProcessRecord proc) {
14651 boolean added = false;
14652 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14653 if (mProcessesToGc.get(i).lastRequestedGc <
14654 proc.lastRequestedGc) {
14655 added = true;
14656 mProcessesToGc.add(i+1, proc);
14657 break;
14658 }
14659 }
14660 if (!added) {
14661 mProcessesToGc.add(0, proc);
14662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014663 }
14664
14665 /**
14666 * Set up to ask a process to GC itself. This will either do it
14667 * immediately, or put it on the list of processes to gc the next
14668 * time things are idle.
14669 */
14670 final void scheduleAppGcLocked(ProcessRecord app) {
14671 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014672 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014673 return;
14674 }
14675 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014676 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014677 scheduleAppGcsLocked();
14678 }
14679 }
14680
Dianne Hackborn287952c2010-09-22 22:34:31 -070014681 final void checkExcessivePowerUsageLocked(boolean doKills) {
14682 updateCpuStatsNow();
14683
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014684 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014685 boolean doWakeKills = doKills;
14686 boolean doCpuKills = doKills;
14687 if (mLastPowerCheckRealtime == 0) {
14688 doWakeKills = false;
14689 }
14690 if (mLastPowerCheckUptime == 0) {
14691 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014692 }
14693 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014694 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014695 }
14696 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014697 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14698 final long curUptime = SystemClock.uptimeMillis();
14699 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14700 mLastPowerCheckRealtime = curRealtime;
14701 mLastPowerCheckUptime = curUptime;
14702 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14703 doWakeKills = false;
14704 }
14705 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14706 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014707 }
14708 int i = mLruProcesses.size();
14709 while (i > 0) {
14710 i--;
14711 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014712 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014713 long wtime;
14714 synchronized (stats) {
14715 wtime = stats.getProcessWakeTime(app.info.uid,
14716 app.pid, curRealtime);
14717 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014718 long wtimeUsed = wtime - app.lastWakeTime;
14719 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14720 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014721 StringBuilder sb = new StringBuilder(128);
14722 sb.append("Wake for ");
14723 app.toShortString(sb);
14724 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014725 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014726 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014727 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014728 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014729 sb.append((wtimeUsed*100)/realtimeSince);
14730 sb.append("%)");
14731 Slog.i(TAG, sb.toString());
14732 sb.setLength(0);
14733 sb.append("CPU for ");
14734 app.toShortString(sb);
14735 sb.append(": over ");
14736 TimeUtils.formatDuration(uptimeSince, sb);
14737 sb.append(" used ");
14738 TimeUtils.formatDuration(cputimeUsed, sb);
14739 sb.append(" (");
14740 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014741 sb.append("%)");
14742 Slog.i(TAG, sb.toString());
14743 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014744 // If a process has held a wake lock for more
14745 // than 50% of the time during this period,
14746 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014747 if (doWakeKills && realtimeSince > 0
14748 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14749 synchronized (stats) {
14750 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14751 realtimeSince, wtimeUsed);
14752 }
14753 Slog.w(TAG, "Excessive wake lock in " + app.processName
14754 + " (pid " + app.pid + "): held " + wtimeUsed
14755 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014756 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14757 app.processName, app.setAdj, "excessive wake lock");
14758 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014759 } else if (doCpuKills && uptimeSince > 0
14760 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14761 synchronized (stats) {
14762 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14763 uptimeSince, cputimeUsed);
14764 }
14765 Slog.w(TAG, "Excessive CPU in " + app.processName
14766 + " (pid " + app.pid + "): used " + cputimeUsed
14767 + " during " + uptimeSince);
14768 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14769 app.processName, app.setAdj, "excessive cpu");
14770 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014771 } else {
14772 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014773 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014774 }
14775 }
14776 }
14777 }
14778
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014779 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014780 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014781 app.hiddenAdj = hiddenAdj;
14782
14783 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014784 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014785 }
14786
Dianne Hackborn287952c2010-09-22 22:34:31 -070014787 final boolean wasKeeping = app.keeping;
14788
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014789 boolean success = true;
14790
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014791 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014792
Jeff Brown10e89712011-07-08 18:52:57 -070014793 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014794 if (false) {
14795 // Removing for now. Forcing GCs is not so useful anymore
14796 // with Dalvik, and the new memory level hint facility is
14797 // better for what we need to do these days.
14798 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14799 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14800 // If this app is transitioning from foreground to
14801 // non-foreground, have it do a gc.
14802 scheduleAppGcLocked(app);
14803 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14804 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14805 // Likewise do a gc when an app is moving in to the
14806 // background (such as a service stopping).
14807 scheduleAppGcLocked(app);
14808 }
Jeff Brown10e89712011-07-08 18:52:57 -070014809 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014810
Jeff Brown10e89712011-07-08 18:52:57 -070014811 if (wasKeeping && !app.keeping) {
14812 // This app is no longer something we want to keep. Note
14813 // its current wake lock time to later know to kill it if
14814 // it is not behaving well.
14815 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14816 synchronized (stats) {
14817 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14818 app.pid, SystemClock.elapsedRealtime());
14819 }
14820 app.lastCpuTime = app.curCpuTime;
14821 }
14822
14823 app.setRawAdj = app.curRawAdj;
14824 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014825
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014826 if (app.curAdj != app.setAdj) {
14827 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014828 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014829 TAG, "Set " + app.pid + " " + app.processName +
14830 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014831 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014832 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014833 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014834 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014835 }
14836 }
14837 if (app.setSchedGroup != app.curSchedGroup) {
14838 app.setSchedGroup = app.curSchedGroup;
14839 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14840 "Setting process group of " + app.processName
14841 + " to " + app.curSchedGroup);
14842 if (app.waitingToKill != null &&
14843 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14844 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14845 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14846 app.processName, app.setAdj, app.waitingToKill);
14847 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014848 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014849 } else {
14850 if (true) {
14851 long oldId = Binder.clearCallingIdentity();
14852 try {
14853 Process.setProcessGroup(app.pid, app.curSchedGroup);
14854 } catch (Exception e) {
14855 Slog.w(TAG, "Failed setting process group of " + app.pid
14856 + " to " + app.curSchedGroup);
14857 e.printStackTrace();
14858 } finally {
14859 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014860 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014861 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014862 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014863 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014864 app.thread.setSchedulingGroup(app.curSchedGroup);
14865 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014866 }
14867 }
14868 }
14869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014870 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014871 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014872 }
14873
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014874 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014875 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014876 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborncbb722e2012-02-07 18:33:49 -080014877 for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) {
14878 ActivityRecord r = mMainStack.mPausingActivities.get(i);
14879 if (r.app != null) {
14880 resumedActivity = r;
14881 break;
14882 }
14883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014884 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014885 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014886 }
14887 }
14888 return resumedActivity;
14889 }
14890
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014891 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014892 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014893 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14894 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014895 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14896 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014897
14898 mAdjSeq++;
14899
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014900 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014901 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14902 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014903 if (nowHidden != wasHidden) {
14904 // Changed to/from hidden state, so apps after it in the LRU
14905 // list may also be changed.
14906 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014907 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014908 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014909 }
14910
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014911 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014912 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014913 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14914
14915 if (false) {
14916 RuntimeException e = new RuntimeException();
14917 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014918 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014919 }
14920
14921 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014922 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014923
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014924 // Let's determine how many processes we have running vs.
14925 // how many slots we have for background processes; we may want
14926 // to put multiple processes in a slot of there are enough of
14927 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014928 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014929 int factor = (mLruProcesses.size()-4)/numSlots;
14930 if (factor < 1) factor = 1;
14931 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014932 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014933
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014934 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014935 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014936 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014937 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014938 while (i > 0) {
14939 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014940 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014941 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014942 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14943 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014944 && app.curAdj == curHiddenAdj) {
14945 step++;
14946 if (step >= factor) {
14947 step = 0;
14948 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014949 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014950 }
14951 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014952 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014953 numHidden++;
14954 if (numHidden > mProcessLimit) {
14955 Slog.i(TAG, "No longer want " + app.processName
14956 + " (pid " + app.pid + "): hidden #" + numHidden);
14957 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14958 app.processName, app.setAdj, "too many background");
14959 app.killedBackground = true;
14960 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014961 }
14962 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080014963 if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14964 // If this is an isolated process, and there are no
14965 // services running in it, then the process is no longer
14966 // needed. We agressively kill these because we can by
14967 // definition not re-use the same process again, and it is
14968 // good to avoid having whatever code was running in them
14969 // left sitting around after no longer needed.
14970 Slog.i(TAG, "Isolated process " + app.processName
14971 + " (pid " + app.pid + ") no longer needed");
14972 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14973 app.processName, app.setAdj, "isolated not needed");
14974 app.killedBackground = true;
14975 Process.killProcessQuiet(app.pid);
14976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014977 }
14978 }
14979
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014980 mNumServiceProcs = mNewNumServiceProcs;
14981
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014982 // Now determine the memory trimming level of background processes.
14983 // Unfortunately we need to start at the back of the list to do this
14984 // properly. We only do this if the number of background apps we
14985 // are managing to keep around is less than half the maximum we desire;
14986 // if we are keeping a good number around, we'll let them use whatever
14987 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014988 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014989 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014990 factor = numHidden/3;
14991 int minFactor = 2;
14992 if (mHomeProcess != null) minFactor++;
14993 if (mPreviousProcess != null) minFactor++;
14994 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014995 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014996 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014997 for (i=0; i<N; i++) {
14998 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014999 if (app.curAdj >= ProcessList.HOME_APP_ADJ
15000 && app.curAdj != ProcessList.SERVICE_B_ADJ
15001 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015002 if (app.trimMemoryLevel < curLevel && app.thread != null) {
15003 try {
15004 app.thread.scheduleTrimMemory(curLevel);
15005 } catch (RemoteException e) {
15006 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080015007 if (false) {
15008 // For now we won't do this; our memory trimming seems
15009 // to be good enough at this point that destroying
15010 // activities causes more harm than good.
15011 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15012 && app != mHomeProcess && app != mPreviousProcess) {
15013 // For these apps we will also finish their activities
15014 // to help them free memory.
15015 mMainStack.destroyActivitiesLocked(app, false, "trim");
15016 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015017 }
15018 }
15019 app.trimMemoryLevel = curLevel;
15020 step++;
15021 if (step >= factor) {
15022 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015023 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15024 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015025 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015026 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15027 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015028 break;
15029 }
15030 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070015031 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015032 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015033 && app.thread != null) {
15034 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015035 app.thread.scheduleTrimMemory(
15036 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015037 } catch (RemoteException e) {
15038 }
15039 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015040 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070015041 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015042 && app.pendingUiClean) {
15043 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15044 && app.thread != null) {
15045 try {
15046 app.thread.scheduleTrimMemory(
15047 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15048 } catch (RemoteException e) {
15049 }
15050 }
15051 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15052 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015053 } else {
15054 app.trimMemoryLevel = 0;
15055 }
15056 }
15057 } else {
15058 final int N = mLruProcesses.size();
15059 for (i=0; i<N; i++) {
15060 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070015061 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070015062 && app.pendingUiClean) {
15063 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15064 && app.thread != null) {
15065 try {
15066 app.thread.scheduleTrimMemory(
15067 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15068 } catch (RemoteException e) {
15069 }
15070 }
15071 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15072 app.pendingUiClean = false;
15073 } else {
15074 app.trimMemoryLevel = 0;
15075 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015076 }
15077 }
15078
15079 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070015080 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015082 }
15083
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070015084 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015085 synchronized (this) {
15086 int i;
15087
15088 // First remove any unused application processes whose package
15089 // has been removed.
15090 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15091 final ProcessRecord app = mRemovedProcesses.get(i);
15092 if (app.activities.size() == 0
15093 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080015094 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015095 TAG, "Exiting empty application process "
15096 + app.processName + " ("
15097 + (app.thread != null ? app.thread.asBinder() : null)
15098 + ")\n");
15099 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070015100 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
15101 app.processName, app.setAdj, "empty");
15102 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015103 } else {
15104 try {
15105 app.thread.scheduleExit();
15106 } catch (Exception e) {
15107 // Ignore exceptions.
15108 }
15109 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070015110 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015111 mRemovedProcesses.remove(i);
15112
15113 if (app.persistent) {
15114 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080015115 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015116 }
15117 }
15118 }
15119 }
15120
Dianne Hackbornce86ba82011-07-13 19:33:41 -070015121 // Now update the oom adj for all processes.
15122 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015123 }
15124 }
15125
15126 /** This method sends the specified signal to each of the persistent apps */
15127 public void signalPersistentProcesses(int sig) throws RemoteException {
15128 if (sig != Process.SIGNAL_USR1) {
15129 throw new SecurityException("Only SIGNAL_USR1 is allowed");
15130 }
15131
15132 synchronized (this) {
15133 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15134 != PackageManager.PERMISSION_GRANTED) {
15135 throw new SecurityException("Requires permission "
15136 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15137 }
15138
Dianne Hackborndd71fc82009-12-16 19:24:32 -080015139 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15140 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015141 if (r.thread != null && r.persistent) {
15142 Process.sendSignal(r.pid, sig);
15143 }
15144 }
15145 }
15146 }
15147
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015148 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15149 if (proc == null || proc == mProfileProc) {
15150 proc = mProfileProc;
15151 path = mProfileFile;
15152 profileType = mProfileType;
15153 clearProfilerLocked();
15154 }
15155 if (proc == null) {
15156 return;
15157 }
15158 try {
15159 proc.thread.profilerControl(false, path, null, profileType);
15160 } catch (RemoteException e) {
15161 throw new IllegalStateException("Process disappeared");
15162 }
15163 }
15164
15165 private void clearProfilerLocked() {
15166 if (mProfileFd != null) {
15167 try {
15168 mProfileFd.close();
15169 } catch (IOException e) {
15170 }
15171 }
15172 mProfileApp = null;
15173 mProfileProc = null;
15174 mProfileFile = null;
15175 mProfileType = 0;
15176 mAutoStopProfiler = false;
15177 }
15178
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015179 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070015180 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015181
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015182 try {
15183 synchronized (this) {
15184 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15185 // its own permission.
15186 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15187 != PackageManager.PERMISSION_GRANTED) {
15188 throw new SecurityException("Requires permission "
15189 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015190 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015191
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015192 if (start && fd == null) {
15193 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015194 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015195
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015196 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015197 if (process != null) {
15198 try {
15199 int pid = Integer.parseInt(process);
15200 synchronized (mPidsSelfLocked) {
15201 proc = mPidsSelfLocked.get(pid);
15202 }
15203 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015204 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015205
15206 if (proc == null) {
15207 HashMap<String, SparseArray<ProcessRecord>> all
15208 = mProcessNames.getMap();
15209 SparseArray<ProcessRecord> procs = all.get(process);
15210 if (procs != null && procs.size() > 0) {
15211 proc = procs.valueAt(0);
15212 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015213 }
15214 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015215
15216 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015217 throw new IllegalArgumentException("Unknown process: " + process);
15218 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015219
15220 if (start) {
15221 stopProfilerLocked(null, null, 0);
15222 setProfileApp(proc.info, proc.processName, path, fd, false);
15223 mProfileProc = proc;
15224 mProfileType = profileType;
15225 try {
15226 fd = fd.dup();
15227 } catch (IOException e) {
15228 fd = null;
15229 }
15230 proc.thread.profilerControl(start, path, fd, profileType);
15231 fd = null;
15232 mProfileFd = null;
15233 } else {
15234 stopProfilerLocked(proc, path, profileType);
15235 if (fd != null) {
15236 try {
15237 fd.close();
15238 } catch (IOException e) {
15239 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015240 }
15241 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015242
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015243 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015244 }
15245 } catch (RemoteException e) {
15246 throw new IllegalStateException("Process disappeared");
15247 } finally {
15248 if (fd != null) {
15249 try {
15250 fd.close();
15251 } catch (IOException e) {
15252 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015253 }
15254 }
15255 }
Andy McFadden824c5102010-07-09 16:26:57 -070015256
15257 public boolean dumpHeap(String process, boolean managed,
15258 String path, ParcelFileDescriptor fd) throws RemoteException {
15259
15260 try {
15261 synchronized (this) {
15262 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15263 // its own permission (same as profileControl).
15264 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15265 != PackageManager.PERMISSION_GRANTED) {
15266 throw new SecurityException("Requires permission "
15267 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15268 }
15269
15270 if (fd == null) {
15271 throw new IllegalArgumentException("null fd");
15272 }
15273
15274 ProcessRecord proc = null;
15275 try {
15276 int pid = Integer.parseInt(process);
15277 synchronized (mPidsSelfLocked) {
15278 proc = mPidsSelfLocked.get(pid);
15279 }
15280 } catch (NumberFormatException e) {
15281 }
15282
15283 if (proc == null) {
15284 HashMap<String, SparseArray<ProcessRecord>> all
15285 = mProcessNames.getMap();
15286 SparseArray<ProcessRecord> procs = all.get(process);
15287 if (procs != null && procs.size() > 0) {
15288 proc = procs.valueAt(0);
15289 }
15290 }
15291
15292 if (proc == null || proc.thread == null) {
15293 throw new IllegalArgumentException("Unknown process: " + process);
15294 }
15295
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080015296 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15297 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070015298 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15299 throw new SecurityException("Process not debuggable: " + proc);
15300 }
15301 }
15302
15303 proc.thread.dumpHeap(managed, path, fd);
15304 fd = null;
15305 return true;
15306 }
15307 } catch (RemoteException e) {
15308 throw new IllegalStateException("Process disappeared");
15309 } finally {
15310 if (fd != null) {
15311 try {
15312 fd.close();
15313 } catch (IOException e) {
15314 }
15315 }
15316 }
15317 }
15318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015319 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15320 public void monitor() {
15321 synchronized (this) { }
15322 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015323
15324 public void onCoreSettingsChange(Bundle settings) {
15325 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15326 ProcessRecord processRecord = mLruProcesses.get(i);
15327 try {
15328 if (processRecord.thread != null) {
15329 processRecord.thread.setCoreSettings(settings);
15330 }
15331 } catch (RemoteException re) {
15332 /* ignore */
15333 }
15334 }
15335 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015336
15337 // Multi-user methods
15338
Amith Yamasani742a6712011-05-04 14:49:28 -070015339 private int mCurrentUserId;
15340 private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15341
15342 public boolean switchUser(int userId) {
15343 final int callingUid = Binder.getCallingUid();
15344 if (callingUid != 0 && callingUid != Process.myUid()) {
15345 Slog.e(TAG, "Trying to switch user from unauthorized app");
15346 return false;
15347 }
15348 if (mCurrentUserId == userId)
15349 return true;
15350
15351 synchronized (this) {
15352 // Check if user is already logged in, otherwise check if user exists first before
15353 // adding to the list of logged in users.
15354 if (mLoggedInUsers.indexOfKey(userId) < 0) {
15355 if (!userExists(userId)) {
15356 return false;
15357 }
15358 mLoggedInUsers.append(userId, userId);
15359 }
15360
15361 mCurrentUserId = userId;
15362 boolean haveActivities = mMainStack.switchUser(userId);
15363 if (!haveActivities) {
15364 startHomeActivityLocked(userId);
15365 }
15366 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015367 return true;
15368 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015369
15370 private boolean userExists(int userId) {
15371 try {
15372 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
15373 for (UserInfo user : users) {
15374 if (user.id == userId) {
15375 return true;
15376 }
15377 }
15378 } catch (RemoteException re) {
15379 // Won't happen, in same process
15380 }
15381
15382 return false;
15383 }
15384
15385
15386 private int applyUserId(int uid, int userId) {
15387 return UserId.getUid(userId, uid);
15388 }
15389
15390 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015391 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070015392 ApplicationInfo newInfo = new ApplicationInfo(info);
15393 newInfo.uid = applyUserId(info.uid, userId);
15394 if (newInfo.uid >= Process.FIRST_APPLICATION_UID) {
15395 newInfo.dataDir = USER_DATA_DIR + userId + "/"
15396 + info.packageName;
15397 }
15398 return newInfo;
15399 }
15400
15401 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015402 if (aInfo == null || aInfo.applicationInfo.uid < Process.FIRST_APPLICATION_UID
Amith Yamasani742a6712011-05-04 14:49:28 -070015403 || userId < 1) {
15404 return aInfo;
15405 }
15406
15407 ActivityInfo info = new ActivityInfo(aInfo);
15408 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15409 return info;
15410 }
15411
15412 static class ServiceMap {
15413
15414 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15415 = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15416 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15417 mServicesByIntentPerUser = new SparseArray<
15418 HashMap<Intent.FilterComparison, ServiceRecord>>();
15419
15420 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15421 // TODO: Deal with global services
15422 if (DEBUG_MU)
15423 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15424 return getServices(callingUser).get(name);
15425 }
15426
15427 ServiceRecord getServiceByName(ComponentName name) {
15428 return getServiceByName(name, -1);
15429 }
15430
15431 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15432 // TODO: Deal with global services
15433 if (DEBUG_MU)
15434 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15435 return getServicesByIntent(callingUser).get(filter);
15436 }
15437
15438 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15439 return getServiceByIntent(filter, -1);
15440 }
15441
15442 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15443 // TODO: Deal with global services
15444 getServices(callingUser).put(name, value);
15445 }
15446
15447 void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15448 ServiceRecord value) {
15449 // TODO: Deal with global services
15450 getServicesByIntent(callingUser).put(filter, value);
15451 }
15452
15453 void removeServiceByName(ComponentName name, int callingUser) {
15454 // TODO: Deal with global services
15455 ServiceRecord removed = getServices(callingUser).remove(name);
15456 if (DEBUG_MU)
15457 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15458 + " removed=" + removed);
15459 }
15460
15461 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15462 // TODO: Deal with global services
15463 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15464 if (DEBUG_MU)
15465 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15466 + " removed=" + removed);
15467 }
15468
15469 Collection<ServiceRecord> getAllServices(int callingUser) {
15470 // TODO: Deal with global services
15471 return getServices(callingUser).values();
15472 }
15473
15474 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15475 HashMap map = mServicesByNamePerUser.get(callingUser);
15476 if (map == null) {
15477 map = new HashMap<ComponentName, ServiceRecord>();
15478 mServicesByNamePerUser.put(callingUser, map);
15479 }
15480 return map;
15481 }
15482
15483 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15484 int callingUser) {
15485 HashMap map = mServicesByIntentPerUser.get(callingUser);
15486 if (map == null) {
15487 map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15488 mServicesByIntentPerUser.put(callingUser, map);
15489 }
15490 return map;
15491 }
15492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015493}