blob: cd630905292e1716d7d74a16b9883232cf702e43 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700123import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.DataInputStream;
125import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.File;
127import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700130import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200131import java.io.IOException;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700132import java.io.InputStream;
Dan Egnora455d192010-03-12 08:52:28 -0800133import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700135import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.lang.IllegalStateException;
137import java.lang.ref.WeakReference;
138import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700139import java.util.Collections;
140import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141import java.util.HashMap;
142import java.util.HashSet;
143import java.util.Iterator;
144import java.util.List;
145import java.util.Locale;
146import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700147import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700148import java.util.concurrent.atomic.AtomicBoolean;
149import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700151public final class ActivityManagerService extends ActivityManagerNative
152 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final String TAG = "ActivityManager";
154 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400155 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 static final boolean DEBUG_SWITCH = localLOGV || false;
157 static final boolean DEBUG_TASKS = localLOGV || false;
158 static final boolean DEBUG_PAUSE = localLOGV || false;
159 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
160 static final boolean DEBUG_TRANSITION = localLOGV || false;
161 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700162 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700164 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_VISBILITY = localLOGV || false;
166 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700167 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800168 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700170 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700171 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700172 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700173 static final boolean DEBUG_POWER = localLOGV || false;
174 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 static final boolean VALIDATE_TOKENS = false;
176 static final boolean SHOW_ACTIVITY_START_TIME = true;
177
178 // Control over CPU and battery monitoring.
179 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
180 static final boolean MONITOR_CPU_USAGE = true;
181 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
182 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
183 static final boolean MONITOR_THREAD_CPU_USAGE = false;
184
Dianne Hackborn1655be42009-05-08 14:29:01 -0700185 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700186 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700187
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800188 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 // Maximum number of recent tasks that we can remember.
191 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700192
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700193 // Amount of time after a call to stopAppSwitches() during which we will
194 // prevent further untrusted switches from happening.
195 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196
197 // How long we wait for a launched process to attach to the activity manager
198 // before we decide it's never going to come up for real.
199 static final int PROC_START_TIMEOUT = 10*1000;
200
Jeff Brown3f9dd282011-07-08 20:02:19 -0700201 // How long we wait for a launched process to attach to the activity manager
202 // before we decide it's never going to come up for real, when the process was
203 // started with a wrapper for instrumentation (such as Valgrind) because it
204 // could take much longer than usual.
205 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 // How long to wait after going idle before forcing apps to GC.
208 static final int GC_TIMEOUT = 5*1000;
209
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700210 // The minimum amount of time between successive GC requests for a process.
211 static final int GC_MIN_INTERVAL = 60*1000;
212
Dianne Hackborn287952c2010-09-22 22:34:31 -0700213 // The rate at which we check for apps using excessive power -- 15 mins.
214 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
215
216 // The minimum sample duration we will allow before deciding we have
217 // enough data on wake locks to start killing things.
218 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
219
220 // The minimum sample duration we will allow before deciding we have
221 // enough data on CPU usage to start killing things.
222 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 // How long we allow a receiver to run before giving up on it.
225 static final int BROADCAST_TIMEOUT = 10*1000;
226
227 // How long we wait for a service to finish executing.
228 static final int SERVICE_TIMEOUT = 20*1000;
229
230 // How long a service needs to be running until restarting its process
231 // is no longer considered to be a relaunch of the service.
232 static final int SERVICE_RESTART_DURATION = 5*1000;
233
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700234 // How long a service needs to be running until it will start back at
235 // SERVICE_RESTART_DURATION after being killed.
236 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
237
238 // Multiplying factor to increase restart duration time by, for each time
239 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
240 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
241
242 // The minimum amount of time between restarting services that we allow.
243 // That is, when multiple services are restarting, we won't allow each
244 // to restart less than this amount of time from the last one.
245 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 // Maximum amount of time for there to be no activity on a service before
248 // we consider it non-essential and allow its process to go on the
249 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700250 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251
252 // How long we wait until we timeout on key dispatching.
253 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 // How long we wait until we timeout on key dispatching during instrumentation.
256 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
257
Dan Egnor42471dd2010-01-07 17:25:22 -0800258 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259
260 static final String[] EMPTY_STRING_ARRAY = new String[0];
261
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700262 public ActivityStack mMainStack;
263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700265 * Description of a request to start a new activity, which has been held
266 * due to app switches being disabled.
267 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700268 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700269 ActivityRecord r;
270 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700271 Uri[] grantedUriPermissions;
272 int grantedMode;
273 boolean onlyIfNeeded;
274 }
275
276 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
277 = new ArrayList<PendingActivityLaunch>();
278
279 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 * List of all active broadcasts that are to be executed immediately
281 * (without waiting for another broadcast to finish). Currently this only
282 * contains broadcasts to registered receivers, to avoid spinning up
283 * a bunch of processes to execute IntentReceiver components.
284 */
285 final ArrayList<BroadcastRecord> mParallelBroadcasts
286 = new ArrayList<BroadcastRecord>();
287
288 /**
289 * List of all active broadcasts that are to be executed one at a time.
290 * The object at the top of the list is the currently activity broadcasts;
291 * those after it are waiting for the top to finish..
292 */
293 final ArrayList<BroadcastRecord> mOrderedBroadcasts
294 = new ArrayList<BroadcastRecord>();
295
296 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800297 * Historical data of past broadcasts, for debugging.
298 */
Dianne Hackborn28695e02011-11-02 21:59:51 -0700299 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800300 final BroadcastRecord[] mBroadcastHistory
301 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
302
303 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 * Set when we current have a BROADCAST_INTENT_MSG in flight.
305 */
306 boolean mBroadcastsScheduled = false;
307
308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * Activity we have told the window manager to have key focus.
310 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700311 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700312 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 * List of intents that were used to start the most recent tasks.
314 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700315 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316
317 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700318 * Process management.
319 */
320 final ProcessList mProcessList = new ProcessList();
321
322 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 * All of the applications we currently have running organized by name.
324 * The keys are strings of the application package name (as
325 * returned by the package manager), and the keys are ApplicationRecord
326 * objects.
327 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700328 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329
330 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700331 * The currently running heavy-weight process, if any.
332 */
333 ProcessRecord mHeavyWeightProcess = null;
334
335 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 * The last time that various processes have crashed.
337 */
338 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
339
340 /**
341 * Set of applications that we consider to be bad, and will reject
342 * incoming broadcasts from (which the user has no control over).
343 * Processes are added to this set when they have crashed twice within
344 * a minimum amount of time; they are removed from it when they are
345 * later restarted (hopefully due to some user action). The value is the
346 * time it was added to the list.
347 */
348 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
349
350 /**
351 * All of the processes we currently have running organized by pid.
352 * The keys are the pid running the application.
353 *
354 * <p>NOTE: This object is protected by its own lock, NOT the global
355 * activity manager lock!
356 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700357 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358
359 /**
360 * All of the processes that have been forced to be foreground. The key
361 * is the pid of the caller who requested it (we hold a death
362 * link on it).
363 */
364 abstract class ForegroundToken implements IBinder.DeathRecipient {
365 int pid;
366 IBinder token;
367 }
368 final SparseArray<ForegroundToken> mForegroundProcesses
369 = new SparseArray<ForegroundToken>();
370
371 /**
372 * List of records for processes that someone had tried to start before the
373 * system was ready. We don't start them at that point, but ensure they
374 * are started by the time booting is complete.
375 */
376 final ArrayList<ProcessRecord> mProcessesOnHold
377 = new ArrayList<ProcessRecord>();
378
379 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 * List of persistent applications that are in the process
381 * of being started.
382 */
383 final ArrayList<ProcessRecord> mPersistentStartingProcesses
384 = new ArrayList<ProcessRecord>();
385
386 /**
387 * Processes that are being forcibly torn down.
388 */
389 final ArrayList<ProcessRecord> mRemovedProcesses
390 = new ArrayList<ProcessRecord>();
391
392 /**
393 * List of running applications, sorted by recent usage.
394 * The first entry in the list is the least recently used.
395 * It contains ApplicationRecord objects. This list does NOT include
396 * any persistent application records (since we never want to exit them).
397 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800398 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 = new ArrayList<ProcessRecord>();
400
401 /**
402 * List of processes that should gc as soon as things are idle.
403 */
404 final ArrayList<ProcessRecord> mProcessesToGc
405 = new ArrayList<ProcessRecord>();
406
407 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800408 * This is the process holding what we currently consider to be
409 * the "home" activity.
410 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700411 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800412
413 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700414 * This is the process holding the activity the user last visited that
415 * is in a different process from the one they are currently in.
416 */
417 ProcessRecord mPreviousProcess;
418
419 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400420 * Packages that the user has asked to have run in screen size
421 * compatibility mode instead of filling the screen.
422 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700423 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400424
425 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 * Set of PendingResultRecord objects that are currently active.
427 */
428 final HashSet mPendingResultRecords = new HashSet();
429
430 /**
431 * Set of IntentSenderRecord objects that are currently active.
432 */
433 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
434 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
435
436 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800437 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700438 * already logged DropBox entries for. Guarded by itself. If
439 * something (rogue user app) forces this over
440 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
441 */
442 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
443 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
444
445 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700446 * Strict Mode background batched logging state.
447 *
448 * The string buffer is guarded by itself, and its lock is also
449 * used to determine if another batched write is already
450 * in-flight.
451 */
452 private final StringBuilder mStrictModeBuffer = new StringBuilder();
453
454 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700455 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
456 */
457 private boolean mPendingBroadcastTimeoutMessage;
458
459 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 * Intent broadcast that we have tried to start, but are
461 * waiting for its application's process to be created. We only
462 * need one (instead of a list) because we always process broadcasts
463 * one at a time, so no others can be started while waiting for this
464 * one.
465 */
466 BroadcastRecord mPendingBroadcast = null;
467
468 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700469 * The receiver index that is pending, to restart the broadcast if needed.
470 */
471 int mPendingBroadcastRecvIndex;
472
473 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 * Keeps track of all IIntentReceivers that have been registered for
475 * broadcasts. Hash keys are the receiver IBinder, hash value is
476 * a ReceiverList.
477 */
478 final HashMap mRegisteredReceivers = new HashMap();
479
480 /**
481 * Resolver for broadcast intents to registered receivers.
482 * Holds BroadcastFilter (subclass of IntentFilter).
483 */
484 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
485 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
486 @Override
487 protected boolean allowFilterResult(
488 BroadcastFilter filter, List<BroadcastFilter> dest) {
489 IBinder target = filter.receiverList.receiver.asBinder();
490 for (int i=dest.size()-1; i>=0; i--) {
491 if (dest.get(i).receiverList.receiver.asBinder() == target) {
492 return false;
493 }
494 }
495 return true;
496 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700497
498 @Override
499 protected String packageForFilter(BroadcastFilter filter) {
500 return filter.packageName;
501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 };
503
504 /**
505 * State of all active sticky broadcasts. Keys are the action of the
506 * sticky Intent, values are an ArrayList of all broadcasted intents with
507 * that action (which should usually be one).
508 */
509 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
510 new HashMap<String, ArrayList<Intent>>();
511
512 /**
513 * All currently running services.
514 */
515 final HashMap<ComponentName, ServiceRecord> mServices =
516 new HashMap<ComponentName, ServiceRecord>();
517
518 /**
519 * All currently running services indexed by the Intent used to start them.
520 */
521 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
522 new HashMap<Intent.FilterComparison, ServiceRecord>();
523
524 /**
525 * All currently bound service connections. Keys are the IBinder of
526 * the client's IServiceConnection.
527 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700528 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
529 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530
531 /**
532 * List of services that we have been asked to start,
533 * but haven't yet been able to. It is used to hold start requests
534 * while waiting for their corresponding application thread to get
535 * going.
536 */
537 final ArrayList<ServiceRecord> mPendingServices
538 = new ArrayList<ServiceRecord>();
539
540 /**
541 * List of services that are scheduled to restart following a crash.
542 */
543 final ArrayList<ServiceRecord> mRestartingServices
544 = new ArrayList<ServiceRecord>();
545
546 /**
547 * List of services that are in the process of being stopped.
548 */
549 final ArrayList<ServiceRecord> mStoppingServices
550 = new ArrayList<ServiceRecord>();
551
552 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700553 * Backup/restore process management
554 */
555 String mBackupAppName = null;
556 BackupRecord mBackupTarget = null;
557
558 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 * List of PendingThumbnailsRecord objects of clients who are still
560 * waiting to receive all of the thumbnails for a task.
561 */
562 final ArrayList mPendingThumbnails = new ArrayList();
563
564 /**
565 * List of HistoryRecord objects that have been finished and must
566 * still report back to a pending thumbnail receiver.
567 */
568 final ArrayList mCancelledThumbnails = new ArrayList();
569
570 /**
571 * All of the currently running global content providers. Keys are a
572 * string containing the provider name and values are a
573 * ContentProviderRecord object containing the data about it. Note
574 * that a single provider may be published under multiple names, so
575 * there may be multiple entries here for a single one in mProvidersByClass.
576 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700577 final HashMap<String, ContentProviderRecord> mProvidersByName
578 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579
580 /**
581 * All of the currently running global content providers. Keys are a
582 * string containing the provider's implementation class and values are a
583 * ContentProviderRecord object containing the data about it.
584 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700585 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
586 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587
588 /**
589 * List of content providers who have clients waiting for them. The
590 * application is currently being launched and the provider will be
591 * removed from this list once it is published.
592 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700593 final ArrayList<ContentProviderRecord> mLaunchingProviders
594 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595
596 /**
597 * Global set of specific Uri permissions that have been granted.
598 */
599 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
600 = new SparseArray<HashMap<Uri, UriPermission>>();
601
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800602 CoreSettingsObserver mCoreSettingsObserver;
603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 /**
605 * Thread-local storage used to carry caller permissions over through
606 * indirect content-provider access.
607 * @see #ActivityManagerService.openContentUri()
608 */
609 private class Identity {
610 public int pid;
611 public int uid;
612
613 Identity(int _pid, int _uid) {
614 pid = _pid;
615 uid = _uid;
616 }
617 }
618 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
619
620 /**
621 * All information we have collected about the runtime performance of
622 * any user id that can impact battery performance.
623 */
624 final BatteryStatsService mBatteryStatsService;
625
626 /**
627 * information about component usage
628 */
629 final UsageStatsService mUsageStatsService;
630
631 /**
632 * Current configuration information. HistoryRecord objects are given
633 * a reference to this object to indicate which configuration they are
634 * currently running in, so this object must be kept immutable.
635 */
636 Configuration mConfiguration = new Configuration();
637
638 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800639 * Current sequencing integer of the configuration, for skipping old
640 * configurations.
641 */
642 int mConfigurationSeq = 0;
643
644 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700645 * Hardware-reported OpenGLES version.
646 */
647 final int GL_ES_VERSION;
648
649 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 * List of initialization arguments to pass to all processes when binding applications to them.
651 * For example, references to the commonly used services.
652 */
653 HashMap<String, IBinder> mAppBindArgs;
654
655 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700656 * Temporary to avoid allocations. Protected by main lock.
657 */
658 final StringBuilder mStringBuilder = new StringBuilder(256);
659
660 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 * Used to control how we initialize the service.
662 */
663 boolean mStartRunning = false;
664 ComponentName mTopComponent;
665 String mTopAction;
666 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700667 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 boolean mSystemReady = false;
669 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700670 boolean mWaitingUpdate = false;
671 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700672 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700673 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674
675 Context mContext;
676
677 int mFactoryTest;
678
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700679 boolean mCheckedForSetup;
680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700682 * The time at which we will allow normal application switches again,
683 * after a call to {@link #stopAppSwitches()}.
684 */
685 long mAppSwitchesAllowedTime;
686
687 /**
688 * This is set to true after the first switch after mAppSwitchesAllowedTime
689 * is set; any switches after that will clear the time.
690 */
691 boolean mDidAppSwitch;
692
693 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700694 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700695 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700696 long mLastPowerCheckRealtime;
697
698 /**
699 * Last time (in uptime) at which we checked for power usage.
700 */
701 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700702
703 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 * Set while we are wanting to sleep, to prevent any
705 * activities from being started/resumed.
706 */
707 boolean mSleeping = false;
708
709 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700710 * Set if we are shutting down the system, similar to sleeping.
711 */
712 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713
714 /**
715 * Task identifier that activities are currently being started
716 * in. Incremented each time a new task is created.
717 * todo: Replace this with a TokenSpace class that generates non-repeating
718 * integers that won't wrap.
719 */
720 int mCurTask = 1;
721
722 /**
723 * Current sequence id for oom_adj computation traversal.
724 */
725 int mAdjSeq = 0;
726
727 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700728 * Current sequence id for process LRU updating.
729 */
730 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731
732 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700733 * Keep track of the number of service processes we last found, to
734 * determine on the next iteration which should be B services.
735 */
736 int mNumServiceProcs = 0;
737 int mNewNumServiceProcs = 0;
738
739 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 * System monitoring: number of processes that died since the last
741 * N procs were started.
742 */
743 int[] mProcDeaths = new int[20];
744
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700745 /**
746 * This is set if we had to do a delayed dexopt of an app before launching
747 * it, to increasing the ANR timeouts in that case.
748 */
749 boolean mDidDexOpt;
750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 String mDebugApp = null;
752 boolean mWaitForDebugger = false;
753 boolean mDebugTransient = false;
754 String mOrigDebugApp = null;
755 boolean mOrigWaitForDebugger = false;
756 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700757 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700758 String mProfileApp = null;
759 ProcessRecord mProfileProc = null;
760 String mProfileFile;
761 ParcelFileDescriptor mProfileFd;
762 int mProfileType = 0;
763 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700765 final RemoteCallbackList<IActivityWatcher> mWatchers
766 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700767
768 final RemoteCallbackList<IProcessObserver> mProcessObservers
769 = new RemoteCallbackList<IProcessObserver>();
770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 /**
772 * Callback of last caller to {@link #requestPss}.
773 */
774 Runnable mRequestPssCallback;
775
776 /**
777 * Remaining processes for which we are waiting results from the last
778 * call to {@link #requestPss}.
779 */
780 final ArrayList<ProcessRecord> mRequestPssList
781 = new ArrayList<ProcessRecord>();
782
783 /**
784 * Runtime statistics collection thread. This object's lock is used to
785 * protect all related state.
786 */
787 final Thread mProcessStatsThread;
788
789 /**
790 * Used to collect process stats when showing not responding dialog.
791 * Protected by mProcessStatsThread.
792 */
793 final ProcessStats mProcessStats = new ProcessStats(
794 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700795 final AtomicLong mLastCpuTime = new AtomicLong(0);
796 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 long mLastWriteTime = 0;
799
800 /**
801 * Set to true after the system has finished booting.
802 */
803 boolean mBooted = false;
804
Dianne Hackborn7d608422011-08-07 16:24:18 -0700805 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700806 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807
808 WindowManagerService mWindowManager;
809
810 static ActivityManagerService mSelf;
811 static ActivityThread mSystemThread;
812
813 private final class AppDeathRecipient implements IBinder.DeathRecipient {
814 final ProcessRecord mApp;
815 final int mPid;
816 final IApplicationThread mAppThread;
817
818 AppDeathRecipient(ProcessRecord app, int pid,
819 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 TAG, "New death recipient " + this
822 + " for thread " + thread.asBinder());
823 mApp = app;
824 mPid = pid;
825 mAppThread = thread;
826 }
827
828 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800829 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 TAG, "Death received in " + this
831 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 synchronized(ActivityManagerService.this) {
833 appDiedLocked(mApp, mPid, mAppThread);
834 }
835 }
836 }
837
838 static final int SHOW_ERROR_MSG = 1;
839 static final int SHOW_NOT_RESPONDING_MSG = 2;
840 static final int SHOW_FACTORY_ERROR_MSG = 3;
841 static final int UPDATE_CONFIGURATION_MSG = 4;
842 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
843 static final int WAIT_FOR_DEBUGGER_MSG = 6;
844 static final int BROADCAST_INTENT_MSG = 7;
845 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 static final int SERVICE_TIMEOUT_MSG = 12;
847 static final int UPDATE_TIME_ZONE = 13;
848 static final int SHOW_UID_ERROR_MSG = 14;
849 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700851 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700852 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800853 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700854 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
855 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700856 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700857 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700858 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700859 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700860 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700861 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
862 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700863 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864
865 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700866 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700867 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868
869 final Handler mHandler = new Handler() {
870 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800871 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 //}
873
874 public void handleMessage(Message msg) {
875 switch (msg.what) {
876 case SHOW_ERROR_MSG: {
877 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 synchronized (ActivityManagerService.this) {
879 ProcessRecord proc = (ProcessRecord)data.get("app");
880 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800881 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 return;
883 }
884 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700885 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800886 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 d.show();
888 proc.crashDialog = d;
889 } else {
890 // The device is asleep, so just pretend that the user
891 // saw a crash dialog and hit "force quit".
892 res.set(0);
893 }
894 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700895
896 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 } break;
898 case SHOW_NOT_RESPONDING_MSG: {
899 synchronized (ActivityManagerService.this) {
900 HashMap data = (HashMap) msg.obj;
901 ProcessRecord proc = (ProcessRecord)data.get("app");
902 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800903 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 return;
905 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800906
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700907 Intent intent = new Intent("android.intent.action.ANR");
908 if (!mProcessesReady) {
909 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
910 }
911 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800912 null, null, 0, null, null, null,
913 false, false, MY_PID, Process.SYSTEM_UID);
914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700916 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 d.show();
918 proc.anrDialog = d;
919 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700920
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700921 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700923 case SHOW_STRICT_MODE_VIOLATION_MSG: {
924 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
925 synchronized (ActivityManagerService.this) {
926 ProcessRecord proc = (ProcessRecord) data.get("app");
927 if (proc == null) {
928 Slog.e(TAG, "App not found when showing strict mode dialog.");
929 break;
930 }
931 if (proc.crashDialog != null) {
932 Slog.e(TAG, "App already has strict mode dialog: " + proc);
933 return;
934 }
935 AppErrorResult res = (AppErrorResult) data.get("result");
936 if (!mSleeping && !mShuttingDown) {
937 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
938 d.show();
939 proc.crashDialog = d;
940 } else {
941 // The device is asleep, so just pretend that the user
942 // saw a crash dialog and hit "force quit".
943 res.set(0);
944 }
945 }
946 ensureBootCompleted();
947 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 case SHOW_FACTORY_ERROR_MSG: {
949 Dialog d = new FactoryErrorDialog(
950 mContext, msg.getData().getCharSequence("msg"));
951 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700952 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 } break;
954 case UPDATE_CONFIGURATION_MSG: {
955 final ContentResolver resolver = mContext.getContentResolver();
956 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
957 } break;
958 case GC_BACKGROUND_PROCESSES_MSG: {
959 synchronized (ActivityManagerService.this) {
960 performAppGcsIfAppropriateLocked();
961 }
962 } break;
963 case WAIT_FOR_DEBUGGER_MSG: {
964 synchronized (ActivityManagerService.this) {
965 ProcessRecord app = (ProcessRecord)msg.obj;
966 if (msg.arg1 != 0) {
967 if (!app.waitedForDebugger) {
968 Dialog d = new AppWaitingForDebuggerDialog(
969 ActivityManagerService.this,
970 mContext, app);
971 app.waitDialog = d;
972 app.waitedForDebugger = true;
973 d.show();
974 }
975 } else {
976 if (app.waitDialog != null) {
977 app.waitDialog.dismiss();
978 app.waitDialog = null;
979 }
980 }
981 }
982 } break;
983 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800984 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 TAG, "Received BROADCAST_INTENT_MSG");
986 processNextBroadcast(true);
987 } break;
988 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700989 synchronized (ActivityManagerService.this) {
990 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700994 if (mDidDexOpt) {
995 mDidDexOpt = false;
996 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
997 nmsg.obj = msg.obj;
998 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
999 return;
1000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 serviceTimeout((ProcessRecord)msg.obj);
1002 } break;
1003 case UPDATE_TIME_ZONE: {
1004 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001005 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1006 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 if (r.thread != null) {
1008 try {
1009 r.thread.updateTimeZone();
1010 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001011 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 }
1013 }
1014 }
1015 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001016 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001017 case CLEAR_DNS_CACHE: {
1018 synchronized (ActivityManagerService.this) {
1019 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1020 ProcessRecord r = mLruProcesses.get(i);
1021 if (r.thread != null) {
1022 try {
1023 r.thread.clearDnsCache();
1024 } catch (RemoteException ex) {
1025 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1026 }
1027 }
1028 }
1029 }
1030 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001031 case UPDATE_HTTP_PROXY: {
1032 ProxyProperties proxy = (ProxyProperties)msg.obj;
1033 String host = "";
1034 String port = "";
1035 String exclList = "";
1036 if (proxy != null) {
1037 host = proxy.getHost();
1038 port = Integer.toString(proxy.getPort());
1039 exclList = proxy.getExclusionList();
1040 }
1041 synchronized (ActivityManagerService.this) {
1042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1043 ProcessRecord r = mLruProcesses.get(i);
1044 if (r.thread != null) {
1045 try {
1046 r.thread.setHttpProxy(host, port, exclList);
1047 } catch (RemoteException ex) {
1048 Slog.w(TAG, "Failed to update http proxy for: " +
1049 r.info.processName);
1050 }
1051 }
1052 }
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case SHOW_UID_ERROR_MSG: {
1056 // XXX This is a temporary dialog, no need to localize.
1057 AlertDialog d = new BaseErrorDialog(mContext);
1058 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1059 d.setCancelable(false);
1060 d.setTitle("System UIDs Inconsistent");
1061 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 +02001062 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1064 mUidAlert = d;
1065 d.show();
1066 } break;
1067 case IM_FEELING_LUCKY_MSG: {
1068 if (mUidAlert != null) {
1069 mUidAlert.dismiss();
1070 mUidAlert = null;
1071 }
1072 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001074 if (mDidDexOpt) {
1075 mDidDexOpt = false;
1076 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1077 nmsg.obj = msg.obj;
1078 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1079 return;
1080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 ProcessRecord app = (ProcessRecord)msg.obj;
1082 synchronized (ActivityManagerService.this) {
1083 processStartTimedOutLocked(app);
1084 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001085 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001086 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1087 synchronized (ActivityManagerService.this) {
1088 doPendingActivityLaunchesLocked(true);
1089 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001090 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001091 case KILL_APPLICATION_MSG: {
1092 synchronized (ActivityManagerService.this) {
1093 int uid = msg.arg1;
1094 boolean restart = (msg.arg2 == 1);
1095 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001096 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001097 }
1098 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001099 case FINALIZE_PENDING_INTENT_MSG: {
1100 ((PendingIntentRecord)msg.obj).completeFinalize();
1101 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001102 case POST_HEAVY_NOTIFICATION_MSG: {
1103 INotificationManager inm = NotificationManager.getService();
1104 if (inm == null) {
1105 return;
1106 }
1107
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001108 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001109 ProcessRecord process = root.app;
1110 if (process == null) {
1111 return;
1112 }
1113
1114 try {
1115 Context context = mContext.createPackageContext(process.info.packageName, 0);
1116 String text = mContext.getString(R.string.heavy_weight_notification,
1117 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1118 Notification notification = new Notification();
1119 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1120 notification.when = 0;
1121 notification.flags = Notification.FLAG_ONGOING_EVENT;
1122 notification.tickerText = text;
1123 notification.defaults = 0; // please be quiet
1124 notification.sound = null;
1125 notification.vibrate = null;
1126 notification.setLatestEventInfo(context, text,
1127 mContext.getText(R.string.heavy_weight_notification_detail),
1128 PendingIntent.getActivity(mContext, 0, root.intent,
1129 PendingIntent.FLAG_CANCEL_CURRENT));
1130
1131 try {
1132 int[] outId = new int[1];
1133 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1134 notification, outId);
1135 } catch (RuntimeException e) {
1136 Slog.w(ActivityManagerService.TAG,
1137 "Error showing notification for heavy-weight app", e);
1138 } catch (RemoteException e) {
1139 }
1140 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001141 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001142 }
1143 } break;
1144 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1145 INotificationManager inm = NotificationManager.getService();
1146 if (inm == null) {
1147 return;
1148 }
1149 try {
1150 inm.cancelNotification("android",
1151 R.string.heavy_weight_notification);
1152 } catch (RuntimeException e) {
1153 Slog.w(ActivityManagerService.TAG,
1154 "Error canceling notification for service", e);
1155 } catch (RemoteException e) {
1156 }
1157 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001158 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1159 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001160 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001161 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001162 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1163 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001164 }
1165 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001166 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1167 synchronized (ActivityManagerService.this) {
1168 ActivityRecord ar = (ActivityRecord)msg.obj;
1169 if (mCompatModeDialog != null) {
1170 if (mCompatModeDialog.mAppInfo.packageName.equals(
1171 ar.info.applicationInfo.packageName)) {
1172 return;
1173 }
1174 mCompatModeDialog.dismiss();
1175 mCompatModeDialog = null;
1176 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001177 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001178 if (mCompatModePackages.getPackageAskCompatModeLocked(
1179 ar.packageName)) {
1180 int mode = mCompatModePackages.computeCompatModeLocked(
1181 ar.info.applicationInfo);
1182 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1183 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1184 mCompatModeDialog = new CompatModeDialog(
1185 ActivityManagerService.this, mContext,
1186 ar.info.applicationInfo);
1187 mCompatModeDialog.show();
1188 }
1189 }
1190 }
1191 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001192 break;
1193 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001194 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001195 final int pid = msg.arg1;
1196 final int uid = msg.arg2;
1197 final boolean foregroundActivities = (Boolean) msg.obj;
1198 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001199 break;
1200 }
1201 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001202 final int pid = msg.arg1;
1203 final int uid = msg.arg2;
1204 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001205 break;
1206 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001207 case REPORT_MEM_USAGE: {
1208 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1209 if (!isDebuggable) {
1210 return;
1211 }
1212 synchronized (ActivityManagerService.this) {
1213 long now = SystemClock.uptimeMillis();
1214 if (now < (mLastMemUsageReportTime+10000)) {
1215 // Don't report more than every 10 seconds to somewhat
1216 // avoid spamming.
1217 return;
1218 }
1219 mLastMemUsageReportTime = now;
1220 }
1221 Thread thread = new Thread() {
1222 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001223 StringBuilder dropBuilder = new StringBuilder(1024);
1224 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001225 try {
1226 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1227 "procrank", });
1228 final InputStreamReader converter = new InputStreamReader(
1229 proc.getInputStream());
1230 BufferedReader in = new BufferedReader(converter);
1231 String line;
1232 while (true) {
1233 line = in.readLine();
1234 if (line == null) {
1235 break;
1236 }
1237 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001238 logBuilder.append(line);
1239 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001240 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001241 dropBuilder.append(line);
1242 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001243 }
1244 converter.close();
1245 } catch (IOException e) {
1246 }
1247 StringWriter sw = new StringWriter();
1248 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001249 StringWriter catSw = new StringWriter();
1250 PrintWriter catPw = new PrintWriter(catSw);
1251 dumpApplicationMemoryUsage(null, pw, " ", new String[] { }, true, catPw);
1252 String memUsage = sw.toString();
1253 dropBuilder.append('\n');
1254 dropBuilder.append(memUsage);
1255 dropBuilder.append(catSw.toString());
1256 logBuilder.append(memUsage);
1257 addErrorToDropBox("watchdog", null, "system_server", null,
1258 null, "Low on memory -- no more background processes",
1259 dropBuilder.toString(), null, null);
1260 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001261 synchronized (ActivityManagerService.this) {
1262 long now = SystemClock.uptimeMillis();
1263 if (mLastMemUsageReportTime < now) {
1264 mLastMemUsageReportTime = now;
1265 }
1266 }
1267 }
1268 };
1269 thread.start();
1270 break;
1271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 }
1273 }
1274 };
1275
1276 public static void setSystemProcess() {
1277 try {
1278 ActivityManagerService m = mSelf;
1279
1280 ServiceManager.addService("activity", m);
1281 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001282 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 if (MONITOR_CPU_USAGE) {
1284 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 ServiceManager.addService("permission", new PermissionController(m));
1287
1288 ApplicationInfo info =
1289 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001290 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001291 mSystemThread.installSystemApplicationInfo(info);
1292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 synchronized (mSelf) {
1294 ProcessRecord app = mSelf.newProcessRecordLocked(
1295 mSystemThread.getApplicationThread(), info,
1296 info.processName);
1297 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001298 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001299 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1301 synchronized (mSelf.mPidsSelfLocked) {
1302 mSelf.mPidsSelfLocked.put(app.pid, app);
1303 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001304 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 }
1306 } catch (PackageManager.NameNotFoundException e) {
1307 throw new RuntimeException(
1308 "Unable to find android system package", e);
1309 }
1310 }
1311
1312 public void setWindowManager(WindowManagerService wm) {
1313 mWindowManager = wm;
1314 }
1315
1316 public static final Context main(int factoryTest) {
1317 AThread thr = new AThread();
1318 thr.start();
1319
1320 synchronized (thr) {
1321 while (thr.mService == null) {
1322 try {
1323 thr.wait();
1324 } catch (InterruptedException e) {
1325 }
1326 }
1327 }
1328
1329 ActivityManagerService m = thr.mService;
1330 mSelf = m;
1331 ActivityThread at = ActivityThread.systemMain();
1332 mSystemThread = at;
1333 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001334 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 m.mContext = context;
1336 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001337 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338
1339 m.mBatteryStatsService.publish(context);
1340 m.mUsageStatsService.publish(context);
1341
1342 synchronized (thr) {
1343 thr.mReady = true;
1344 thr.notifyAll();
1345 }
1346
1347 m.startRunning(null, null, null, null);
1348
1349 return context;
1350 }
1351
1352 public static ActivityManagerService self() {
1353 return mSelf;
1354 }
1355
1356 static class AThread extends Thread {
1357 ActivityManagerService mService;
1358 boolean mReady = false;
1359
1360 public AThread() {
1361 super("ActivityManager");
1362 }
1363
1364 public void run() {
1365 Looper.prepare();
1366
1367 android.os.Process.setThreadPriority(
1368 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001369 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370
1371 ActivityManagerService m = new ActivityManagerService();
1372
1373 synchronized (this) {
1374 mService = m;
1375 notifyAll();
1376 }
1377
1378 synchronized (this) {
1379 while (!mReady) {
1380 try {
1381 wait();
1382 } catch (InterruptedException e) {
1383 }
1384 }
1385 }
1386
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001387 // For debug builds, log event loop stalls to dropbox for analysis.
1388 if (StrictMode.conditionallyEnableDebugLogging()) {
1389 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1390 }
1391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 Looper.loop();
1393 }
1394 }
1395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 static class MemBinder extends Binder {
1397 ActivityManagerService mActivityManagerService;
1398 MemBinder(ActivityManagerService activityManagerService) {
1399 mActivityManagerService = activityManagerService;
1400 }
1401
1402 @Override
1403 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001404 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1405 != PackageManager.PERMISSION_GRANTED) {
1406 pw.println("Permission Denial: can't dump meminfo from from pid="
1407 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1408 + " without permission " + android.Manifest.permission.DUMP);
1409 return;
1410 }
1411
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001412 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 }
1414 }
1415
Chet Haase9c1e23b2011-03-24 10:51:31 -07001416 static class GraphicsBinder extends Binder {
1417 ActivityManagerService mActivityManagerService;
1418 GraphicsBinder(ActivityManagerService activityManagerService) {
1419 mActivityManagerService = activityManagerService;
1420 }
1421
1422 @Override
1423 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001424 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1425 != PackageManager.PERMISSION_GRANTED) {
1426 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1427 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1428 + " without permission " + android.Manifest.permission.DUMP);
1429 return;
1430 }
1431
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001432 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001433 }
1434 }
1435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 static class CpuBinder extends Binder {
1437 ActivityManagerService mActivityManagerService;
1438 CpuBinder(ActivityManagerService activityManagerService) {
1439 mActivityManagerService = activityManagerService;
1440 }
1441
1442 @Override
1443 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001444 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1445 != PackageManager.PERMISSION_GRANTED) {
1446 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1447 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1448 + " without permission " + android.Manifest.permission.DUMP);
1449 return;
1450 }
1451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001453 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1454 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1455 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 }
1457 }
1458 }
1459
1460 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001461 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 File dataDir = Environment.getDataDirectory();
1464 File systemDir = new File(dataDir, "system");
1465 systemDir.mkdirs();
1466 mBatteryStatsService = new BatteryStatsService(new File(
1467 systemDir, "batterystats.bin").toString());
1468 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001469 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001470 mOnBattery = DEBUG_POWER ? true
1471 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001472 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001474 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001475 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476
Jack Palevichb90d28c2009-07-22 15:35:24 -07001477 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1478 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1479
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001480 mConfiguration.setToDefaults();
1481 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 mProcessStats.init();
1483
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001484 mCompatModePackages = new CompatModePackages(this, systemDir);
1485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 // Add ourself to the Watchdog monitors.
1487 Watchdog.getInstance().addMonitor(this);
1488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 mProcessStatsThread = new Thread("ProcessStats") {
1490 public void run() {
1491 while (true) {
1492 try {
1493 try {
1494 synchronized(this) {
1495 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001496 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001498 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 // + ", write delay=" + nextWriteDelay);
1500 if (nextWriteDelay < nextCpuDelay) {
1501 nextCpuDelay = nextWriteDelay;
1502 }
1503 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001504 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 this.wait(nextCpuDelay);
1506 }
1507 }
1508 } catch (InterruptedException e) {
1509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 updateCpuStatsNow();
1511 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001512 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 }
1514 }
1515 }
1516 };
1517 mProcessStatsThread.start();
1518 }
1519
1520 @Override
1521 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1522 throws RemoteException {
1523 try {
1524 return super.onTransact(code, data, reply, flags);
1525 } catch (RuntimeException e) {
1526 // The activity manager only throws security exceptions, so let's
1527 // log all others.
1528 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001529 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 }
1531 throw e;
1532 }
1533 }
1534
1535 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001536 final long now = SystemClock.uptimeMillis();
1537 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1538 return;
1539 }
1540 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1541 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 mProcessStatsThread.notify();
1543 }
1544 }
1545 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 void updateCpuStatsNow() {
1548 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001549 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 final long now = SystemClock.uptimeMillis();
1551 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001554 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1555 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 haveNewCpuStats = true;
1557 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001558 //Slog.i(TAG, mProcessStats.printCurrentState());
1559 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 // + mProcessStats.getTotalCpuPercent() + "%");
1561
Joe Onorato8a9b2202010-02-26 18:56:32 -08001562 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if ("true".equals(SystemProperties.get("events.cpu"))) {
1564 int user = mProcessStats.getLastUserTime();
1565 int system = mProcessStats.getLastSystemTime();
1566 int iowait = mProcessStats.getLastIoWaitTime();
1567 int irq = mProcessStats.getLastIrqTime();
1568 int softIrq = mProcessStats.getLastSoftIrqTime();
1569 int idle = mProcessStats.getLastIdleTime();
1570
1571 int total = user + system + iowait + irq + softIrq + idle;
1572 if (total == 0) total = 1;
1573
Doug Zongker2bec3d42009-12-04 12:52:44 -08001574 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 ((user+system+iowait+irq+softIrq) * 100) / total,
1576 (user * 100) / total,
1577 (system * 100) / total,
1578 (iowait * 100) / total,
1579 (irq * 100) / total,
1580 (softIrq * 100) / total);
1581 }
1582 }
1583
Amith Yamasanie43530a2009-08-21 13:11:37 -07001584 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001585 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001586 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 synchronized(mPidsSelfLocked) {
1588 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001589 if (mOnBattery) {
1590 int perc = bstats.startAddingCpuLocked();
1591 int totalUTime = 0;
1592 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001593 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001595 ProcessStats.Stats st = mProcessStats.getStats(i);
1596 if (!st.working) {
1597 continue;
1598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001600 int otherUTime = (st.rel_utime*perc)/100;
1601 int otherSTime = (st.rel_stime*perc)/100;
1602 totalUTime += otherUTime;
1603 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 if (pr != null) {
1605 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001606 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1607 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001608 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001609 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001610 } else {
1611 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001612 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001613 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001614 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1615 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001616 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001618 }
1619 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001620 bstats.finishAddingCpuLocked(perc, totalUTime,
1621 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 }
1623 }
1624 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1627 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001628 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 }
1630 }
1631 }
1632 }
1633
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001634 @Override
1635 public void batteryNeedsCpuUpdate() {
1636 updateCpuStatsNow();
1637 }
1638
1639 @Override
1640 public void batteryPowerChanged(boolean onBattery) {
1641 // When plugging in, update the CPU stats first before changing
1642 // the plug state.
1643 updateCpuStatsNow();
1644 synchronized (this) {
1645 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001646 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001647 }
1648 }
1649 }
1650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 /**
1652 * Initialize the application bind args. These are passed to each
1653 * process when the bindApplication() IPC is sent to the process. They're
1654 * lazily setup to make sure the services are running when they're asked for.
1655 */
1656 private HashMap<String, IBinder> getCommonServicesLocked() {
1657 if (mAppBindArgs == null) {
1658 mAppBindArgs = new HashMap<String, IBinder>();
1659
1660 // Setup the application init args
1661 mAppBindArgs.put("package", ServiceManager.getService("package"));
1662 mAppBindArgs.put("window", ServiceManager.getService("window"));
1663 mAppBindArgs.put(Context.ALARM_SERVICE,
1664 ServiceManager.getService(Context.ALARM_SERVICE));
1665 }
1666 return mAppBindArgs;
1667 }
1668
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001669 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001670 if (mFocusedActivity != r) {
1671 mFocusedActivity = r;
Dianne Hackbornbe707852011-11-11 14:32:10 -08001672 mWindowManager.setFocusedApp(r.appToken, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 }
1674 }
1675
Dianne Hackborn906497c2010-05-10 15:57:38 -07001676 private final void updateLruProcessInternalLocked(ProcessRecord app,
1677 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001679 int lrui = mLruProcesses.indexOf(app);
1680 if (lrui >= 0) mLruProcesses.remove(lrui);
1681
1682 int i = mLruProcesses.size()-1;
1683 int skipTop = 0;
1684
Dianne Hackborn906497c2010-05-10 15:57:38 -07001685 app.lruSeq = mLruSeq;
1686
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001687 // compute the new weight for this process.
1688 if (updateActivityTime) {
1689 app.lastActivityTime = SystemClock.uptimeMillis();
1690 }
1691 if (app.activities.size() > 0) {
1692 // If this process has activities, we more strongly want to keep
1693 // it around.
1694 app.lruWeight = app.lastActivityTime;
1695 } else if (app.pubProviders.size() > 0) {
1696 // If this process contains content providers, we want to keep
1697 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001698 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001699 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001700 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001701 } else {
1702 // If this process doesn't have activities, we less strongly
1703 // want to keep it around, and generally want to avoid getting
1704 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001705 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001706 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001707 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001708 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001709
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001710 while (i >= 0) {
1711 ProcessRecord p = mLruProcesses.get(i);
1712 // If this app shouldn't be in front of the first N background
1713 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001714 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001715 skipTop--;
1716 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001717 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001718 mLruProcesses.add(i+1, app);
1719 break;
1720 }
1721 i--;
1722 }
1723 if (i < 0) {
1724 mLruProcesses.add(0, app);
1725 }
1726
Dianne Hackborn906497c2010-05-10 15:57:38 -07001727 // If the app is currently using a content provider or service,
1728 // bump those processes as well.
1729 if (app.connections.size() > 0) {
1730 for (ConnectionRecord cr : app.connections) {
1731 if (cr.binding != null && cr.binding.service != null
1732 && cr.binding.service.app != null
1733 && cr.binding.service.app.lruSeq != mLruSeq) {
1734 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1735 updateActivityTime, i+1);
1736 }
1737 }
1738 }
1739 if (app.conProviders.size() > 0) {
1740 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001741 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1742 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001743 updateActivityTime, i+1);
1744 }
1745 }
1746 }
1747
Joe Onorato8a9b2202010-02-26 18:56:32 -08001748 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 if (oomAdj) {
1750 updateOomAdjLocked();
1751 }
1752 }
1753
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001754 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001755 boolean oomAdj, boolean updateActivityTime) {
1756 mLruSeq++;
1757 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1758 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001759
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001760 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001761 String processName, int uid) {
1762 if (uid == Process.SYSTEM_UID) {
1763 // The system gets to run in any process. If there are multiple
1764 // processes with the same uid, just pick the first (this
1765 // should never happen).
1766 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1767 processName);
1768 return procs != null ? procs.valueAt(0) : null;
1769 }
1770 ProcessRecord proc = mProcessNames.get(processName, uid);
1771 return proc;
1772 }
1773
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001774 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001775 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001776 try {
1777 if (pm.performDexOpt(packageName)) {
1778 mDidDexOpt = true;
1779 }
1780 } catch (RemoteException e) {
1781 }
1782 }
1783
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001784 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 int transit = mWindowManager.getPendingAppTransition();
1786 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1787 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1788 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1789 }
1790
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001791 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001793 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1795 // We don't have to do anything more if:
1796 // (1) There is an existing application record; and
1797 // (2) The caller doesn't think it is dead, OR there is no thread
1798 // object attached to it so we know it couldn't have crashed; and
1799 // (3) There is a pid assigned to it, so it is either starting or
1800 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001801 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 + " app=" + app + " knownToBeDead=" + knownToBeDead
1803 + " thread=" + (app != null ? app.thread : null)
1804 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001805 if (app != null && app.pid > 0) {
1806 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001807 // We already have the app running, or are waiting for it to
1808 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001809 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001810 // If this is a new package in the process, add the package to the list
1811 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001812 return app;
1813 } else {
1814 // An application record is attached to a previous process,
1815 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001816 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001817 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001818 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 String hostingNameStr = hostingName != null
1822 ? hostingName.flattenToShortString() : null;
1823
1824 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1825 // If we are in the background, then check to see if this process
1826 // is bad. If so, we will just silently fail.
1827 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001828 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1829 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001830 return null;
1831 }
1832 } else {
1833 // When the user is explicitly starting a process, then clear its
1834 // crash count so that we won't make it bad until they see at
1835 // least one crash dialog again, and make the process good again
1836 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001837 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1838 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 mProcessCrashTimes.remove(info.processName, info.uid);
1840 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001841 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 info.processName);
1843 mBadProcesses.remove(info.processName, info.uid);
1844 if (app != null) {
1845 app.bad = false;
1846 }
1847 }
1848 }
1849
1850 if (app == null) {
1851 app = newProcessRecordLocked(null, info, processName);
1852 mProcessNames.put(processName, info.uid, app);
1853 } else {
1854 // If this is a new package in the process, add the package to the list
1855 app.addPackage(info.packageName);
1856 }
1857
1858 // If the system is not ready yet, then hold off on starting this
1859 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001860 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001861 && !isAllowedWhileBooting(info)
1862 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 if (!mProcessesOnHold.contains(app)) {
1864 mProcessesOnHold.add(app);
1865 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001866 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 return app;
1868 }
1869
1870 startProcessLocked(app, hostingType, hostingNameStr);
1871 return (app.pid != 0) ? app : null;
1872 }
1873
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001874 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1875 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1876 }
1877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 private final void startProcessLocked(ProcessRecord app,
1879 String hostingType, String hostingNameStr) {
1880 if (app.pid > 0 && app.pid != MY_PID) {
1881 synchronized (mPidsSelfLocked) {
1882 mPidsSelfLocked.remove(app.pid);
1883 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1884 }
1885 app.pid = 0;
1886 }
1887
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001888 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1889 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 mProcessesOnHold.remove(app);
1891
1892 updateCpuStats();
1893
1894 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1895 mProcDeaths[0] = 0;
1896
1897 try {
1898 int uid = app.info.uid;
1899 int[] gids = null;
1900 try {
1901 gids = mContext.getPackageManager().getPackageGids(
1902 app.info.packageName);
1903 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001904 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001905 }
1906 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1907 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1908 && mTopComponent != null
1909 && app.processName.equals(mTopComponent.getPackageName())) {
1910 uid = 0;
1911 }
1912 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1913 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1914 uid = 0;
1915 }
1916 }
1917 int debugFlags = 0;
1918 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1919 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001920 // Also turn on CheckJNI for debuggable apps. It's quite
1921 // awkward to turn on otherwise.
1922 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001924 // Run the app in safe mode if its manifest requests so or the
1925 // system is booted in safe mode.
1926 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1927 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001928 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001930 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1931 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1932 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001933 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1934 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1935 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 if ("1".equals(SystemProperties.get("debug.assert"))) {
1937 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1938 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001939
1940 // Start the process. It will either succeed and return a result containing
1941 // the PID of the new process, or else throw a RuntimeException.
1942 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001943 app.processName, uid, uid, gids, debugFlags,
1944 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1947 synchronized (bs) {
1948 if (bs.isOnBattery()) {
1949 app.batteryStats.incStartsLocked();
1950 }
1951 }
1952
Jeff Brown3f9dd282011-07-08 20:02:19 -07001953 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 app.processName, hostingType,
1955 hostingNameStr != null ? hostingNameStr : "");
1956
1957 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001958 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 }
1960
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001961 StringBuilder buf = mStringBuilder;
1962 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001963 buf.append("Start proc ");
1964 buf.append(app.processName);
1965 buf.append(" for ");
1966 buf.append(hostingType);
1967 if (hostingNameStr != null) {
1968 buf.append(" ");
1969 buf.append(hostingNameStr);
1970 }
1971 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001972 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001973 buf.append(" uid=");
1974 buf.append(uid);
1975 buf.append(" gids={");
1976 if (gids != null) {
1977 for (int gi=0; gi<gids.length; gi++) {
1978 if (gi != 0) buf.append(", ");
1979 buf.append(gids[gi]);
1980
1981 }
1982 }
1983 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001984 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001985 app.pid = startResult.pid;
1986 app.usingWrapper = startResult.usingWrapper;
1987 app.removed = false;
1988 synchronized (mPidsSelfLocked) {
1989 this.mPidsSelfLocked.put(startResult.pid, app);
1990 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1991 msg.obj = app;
1992 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1993 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001994 }
1995 } catch (RuntimeException e) {
1996 // XXX do better error recovery.
1997 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001998 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 }
2000 }
2001
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002002 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 if (resumed) {
2004 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2005 } else {
2006 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2007 }
2008 }
2009
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002010 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002011 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2012 && mTopAction == null) {
2013 // We are running in factory test mode, but unable to find
2014 // the factory test app, so just sit around displaying the
2015 // error message and don't try to start anything.
2016 return false;
2017 }
2018 Intent intent = new Intent(
2019 mTopAction,
2020 mTopData != null ? Uri.parse(mTopData) : null);
2021 intent.setComponent(mTopComponent);
2022 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2023 intent.addCategory(Intent.CATEGORY_HOME);
2024 }
2025 ActivityInfo aInfo =
2026 intent.resolveActivityInfo(mContext.getPackageManager(),
2027 STOCK_PM_FLAGS);
2028 if (aInfo != null) {
2029 intent.setComponent(new ComponentName(
2030 aInfo.applicationInfo.packageName, aInfo.name));
2031 // Don't do this if the home app is currently being
2032 // instrumented.
2033 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2034 aInfo.applicationInfo.uid);
2035 if (app == null || app.instrumentationClass == null) {
2036 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002037 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002038 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002039 }
2040 }
2041
2042
2043 return true;
2044 }
2045
2046 /**
2047 * Starts the "new version setup screen" if appropriate.
2048 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002049 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002050 // Only do this once per boot.
2051 if (mCheckedForSetup) {
2052 return;
2053 }
2054
2055 // We will show this screen if the current one is a different
2056 // version than the last one shown, and we are not running in
2057 // low-level factory test mode.
2058 final ContentResolver resolver = mContext.getContentResolver();
2059 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2060 Settings.Secure.getInt(resolver,
2061 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2062 mCheckedForSetup = true;
2063
2064 // See if we should be showing the platform update setup UI.
2065 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2066 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2067 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2068
2069 // We don't allow third party apps to replace this.
2070 ResolveInfo ri = null;
2071 for (int i=0; ris != null && i<ris.size(); i++) {
2072 if ((ris.get(i).activityInfo.applicationInfo.flags
2073 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2074 ri = ris.get(i);
2075 break;
2076 }
2077 }
2078
2079 if (ri != null) {
2080 String vers = ri.activityInfo.metaData != null
2081 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2082 : null;
2083 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2084 vers = ri.activityInfo.applicationInfo.metaData.getString(
2085 Intent.METADATA_SETUP_VERSION);
2086 }
2087 String lastVers = Settings.Secure.getString(
2088 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2089 if (vers != null && !vers.equals(lastVers)) {
2090 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2091 intent.setComponent(new ComponentName(
2092 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002093 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002094 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002095 }
2096 }
2097 }
2098 }
2099
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002100 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002101 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002102 }
2103
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002104 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002105 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002106 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2107 }
2108 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002109
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002110 public void setFrontActivityScreenCompatMode(int mode) {
2111 synchronized (this) {
2112 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2113 }
2114 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002115
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002116 public int getPackageScreenCompatMode(String packageName) {
2117 synchronized (this) {
2118 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2119 }
2120 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002121
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002122 public void setPackageScreenCompatMode(String packageName, int mode) {
2123 synchronized (this) {
2124 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002125 }
2126 }
2127
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002128 public boolean getPackageAskScreenCompat(String packageName) {
2129 synchronized (this) {
2130 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2131 }
2132 }
2133
2134 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2135 synchronized (this) {
2136 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2137 }
2138 }
2139
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002140 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002141 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002142
2143 final int identHash = System.identityHashCode(r);
2144 updateUsageStats(r, true);
2145
2146 int i = mWatchers.beginBroadcast();
2147 while (i > 0) {
2148 i--;
2149 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2150 if (w != null) {
2151 try {
2152 w.activityResuming(identHash);
2153 } catch (RemoteException e) {
2154 }
2155 }
2156 }
2157 mWatchers.finishBroadcast();
2158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159
Jeff Sharkeya4620792011-05-20 15:29:23 -07002160 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2161 int i = mProcessObservers.beginBroadcast();
2162 while (i > 0) {
2163 i--;
2164 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2165 if (observer != null) {
2166 try {
2167 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2168 } catch (RemoteException e) {
2169 }
2170 }
2171 }
2172 mProcessObservers.finishBroadcast();
2173 }
2174
2175 private void dispatchProcessDied(int pid, int uid) {
2176 int i = mProcessObservers.beginBroadcast();
2177 while (i > 0) {
2178 i--;
2179 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2180 if (observer != null) {
2181 try {
2182 observer.onProcessDied(pid, uid);
2183 } catch (RemoteException e) {
2184 }
2185 }
2186 }
2187 mProcessObservers.finishBroadcast();
2188 }
2189
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002190 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002191 final int N = mPendingActivityLaunches.size();
2192 if (N <= 0) {
2193 return;
2194 }
2195 for (int i=0; i<N; i++) {
2196 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002197 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002198 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2199 doResume && i == (N-1));
2200 }
2201 mPendingActivityLaunches.clear();
2202 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002203
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002204 public final int startActivity(IApplicationThread caller,
2205 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2206 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002207 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2208 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002209 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002210 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002211 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2212 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002213 }
2214
2215 public final WaitResult startActivityAndWait(IApplicationThread caller,
2216 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2217 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002218 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2219 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002220 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002221 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002222 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002223 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2224 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002225 return res;
2226 }
2227
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002228 public final int startActivityWithConfig(IApplicationThread caller,
2229 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2230 int grantedMode, IBinder resultTo,
2231 String resultWho, int requestCode, boolean onlyIfNeeded,
2232 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002233 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002234 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002235 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002236 }
2237
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002238 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002239 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002240 IBinder resultTo, String resultWho, int requestCode,
2241 int flagsMask, int flagsValues) {
2242 // Refuse possible leaked file descriptors
2243 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2244 throw new IllegalArgumentException("File descriptors passed in Intent");
2245 }
2246
2247 IIntentSender sender = intent.getTarget();
2248 if (!(sender instanceof PendingIntentRecord)) {
2249 throw new IllegalArgumentException("Bad PendingIntent object");
2250 }
2251
2252 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002253
2254 synchronized (this) {
2255 // If this is coming from the currently resumed activity, it is
2256 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002257 if (mMainStack.mResumedActivity != null
2258 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002259 Binder.getCallingUid()) {
2260 mAppSwitchesAllowedTime = 0;
2261 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002262 }
2263
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002264 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002265 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2266 }
2267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 public boolean startNextMatchingActivity(IBinder callingActivity,
2269 Intent intent) {
2270 // Refuse possible leaked file descriptors
2271 if (intent != null && intent.hasFileDescriptors() == true) {
2272 throw new IllegalArgumentException("File descriptors passed in Intent");
2273 }
2274
2275 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002276 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2277 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 return false;
2279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 if (r.app == null || r.app.thread == null) {
2281 // The caller is not running... d'oh!
2282 return false;
2283 }
2284 intent = new Intent(intent);
2285 // The caller is not allowed to change the data.
2286 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2287 // And we are resetting to find the next component...
2288 intent.setComponent(null);
2289
2290 ActivityInfo aInfo = null;
2291 try {
2292 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002293 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002295 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296
2297 // Look for the original activity in the list...
2298 final int N = resolves != null ? resolves.size() : 0;
2299 for (int i=0; i<N; i++) {
2300 ResolveInfo rInfo = resolves.get(i);
2301 if (rInfo.activityInfo.packageName.equals(r.packageName)
2302 && rInfo.activityInfo.name.equals(r.info.name)) {
2303 // We found the current one... the next matching is
2304 // after it.
2305 i++;
2306 if (i<N) {
2307 aInfo = resolves.get(i).activityInfo;
2308 }
2309 break;
2310 }
2311 }
2312 } catch (RemoteException e) {
2313 }
2314
2315 if (aInfo == null) {
2316 // Nobody who is next!
2317 return false;
2318 }
2319
2320 intent.setComponent(new ComponentName(
2321 aInfo.applicationInfo.packageName, aInfo.name));
2322 intent.setFlags(intent.getFlags()&~(
2323 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2324 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2325 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2326 Intent.FLAG_ACTIVITY_NEW_TASK));
2327
2328 // Okay now we need to start the new activity, replacing the
2329 // currently running activity. This is a little tricky because
2330 // we want to start the new one as if the current one is finished,
2331 // but not finish the current one first so that there is no flicker.
2332 // And thus...
2333 final boolean wasFinishing = r.finishing;
2334 r.finishing = true;
2335
2336 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002337 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 final String resultWho = r.resultWho;
2339 final int requestCode = r.requestCode;
2340 r.resultTo = null;
2341 if (resultTo != null) {
2342 resultTo.removeResultsLocked(r, resultWho, requestCode);
2343 }
2344
2345 final long origId = Binder.clearCallingIdentity();
2346 // XXX we are not dealing with propagating grantedUriPermissions...
2347 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002348 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002349 r.resolvedType, null, 0, aInfo,
2350 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002351 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 Binder.restoreCallingIdentity(origId);
2353
2354 r.finishing = wasFinishing;
2355 if (res != START_SUCCESS) {
2356 return false;
2357 }
2358 return true;
2359 }
2360 }
2361
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002362 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 Intent intent, String resolvedType, IBinder resultTo,
2364 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002365
2366 // This is so super not safe, that only the system (or okay root)
2367 // can do it.
2368 final int callingUid = Binder.getCallingUid();
2369 if (callingUid != 0 && callingUid != Process.myUid()) {
2370 throw new SecurityException(
2371 "startActivityInPackage only available to the system");
2372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002374 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002375 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2376 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002377 }
2378
2379 public final int startActivities(IApplicationThread caller,
2380 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2381 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2382 }
2383
2384 public final int startActivitiesInPackage(int uid,
2385 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2386
2387 // This is so super not safe, that only the system (or okay root)
2388 // can do it.
2389 final int callingUid = Binder.getCallingUid();
2390 if (callingUid != 0 && callingUid != Process.myUid()) {
2391 throw new SecurityException(
2392 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 }
2394
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002395 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 }
2397
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002398 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002400 // Quick case: check if the top-most recent task is the same.
2401 if (N > 0 && mRecentTasks.get(0) == task) {
2402 return;
2403 }
2404 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 for (int i=0; i<N; i++) {
2406 TaskRecord tr = mRecentTasks.get(i);
2407 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2408 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2409 mRecentTasks.remove(i);
2410 i--;
2411 N--;
2412 if (task.intent == null) {
2413 // If the new recent task we are adding is not fully
2414 // specified, then replace it with the existing recent task.
2415 task = tr;
2416 }
2417 }
2418 }
2419 if (N >= MAX_RECENT_TASKS) {
2420 mRecentTasks.remove(N-1);
2421 }
2422 mRecentTasks.add(0, task);
2423 }
2424
2425 public void setRequestedOrientation(IBinder token,
2426 int requestedOrientation) {
2427 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002428 ActivityRecord r = mMainStack.isInStackLocked(token);
2429 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 return;
2431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002432 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002433 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002435 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002436 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 if (config != null) {
2438 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002439 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002440 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 }
2442 }
2443 Binder.restoreCallingIdentity(origId);
2444 }
2445 }
2446
2447 public int getRequestedOrientation(IBinder token) {
2448 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002449 ActivityRecord r = mMainStack.isInStackLocked(token);
2450 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2452 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002453 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454 }
2455 }
2456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 /**
2458 * This is the internal entry point for handling Activity.finish().
2459 *
2460 * @param token The Binder token referencing the Activity we want to finish.
2461 * @param resultCode Result code, if any, from this Activity.
2462 * @param resultData Result data (Intent), if any, from this Activity.
2463 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002464 * @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 -08002465 */
2466 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2467 // Refuse possible leaked file descriptors
2468 if (resultData != null && resultData.hasFileDescriptors() == true) {
2469 throw new IllegalArgumentException("File descriptors passed in Intent");
2470 }
2471
2472 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002473 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002475 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 if (next != null) {
2477 // ask watcher if this is allowed
2478 boolean resumeOK = true;
2479 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002480 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002482 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 }
2484
2485 if (!resumeOK) {
2486 return false;
2487 }
2488 }
2489 }
2490 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002491 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002492 resultData, "app-request");
2493 Binder.restoreCallingIdentity(origId);
2494 return res;
2495 }
2496 }
2497
Dianne Hackborn860755f2010-06-03 18:47:52 -07002498 public final void finishHeavyWeightApp() {
2499 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2500 != PackageManager.PERMISSION_GRANTED) {
2501 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2502 + Binder.getCallingPid()
2503 + ", uid=" + Binder.getCallingUid()
2504 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2505 Slog.w(TAG, msg);
2506 throw new SecurityException(msg);
2507 }
2508
2509 synchronized(this) {
2510 if (mHeavyWeightProcess == null) {
2511 return;
2512 }
2513
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002514 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002515 mHeavyWeightProcess.activities);
2516 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002517 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002518 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002519 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002520 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002521 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002522 null, "finish-heavy");
2523 }
2524 }
2525 }
2526
2527 mHeavyWeightProcess = null;
2528 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2529 }
2530 }
2531
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002532 public void crashApplication(int uid, int initialPid, String packageName,
2533 String message) {
2534 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2535 != PackageManager.PERMISSION_GRANTED) {
2536 String msg = "Permission Denial: crashApplication() from pid="
2537 + Binder.getCallingPid()
2538 + ", uid=" + Binder.getCallingUid()
2539 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2540 Slog.w(TAG, msg);
2541 throw new SecurityException(msg);
2542 }
2543
2544 synchronized(this) {
2545 ProcessRecord proc = null;
2546
2547 // Figure out which process to kill. We don't trust that initialPid
2548 // still has any relation to current pids, so must scan through the
2549 // list.
2550 synchronized (mPidsSelfLocked) {
2551 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2552 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2553 if (p.info.uid != uid) {
2554 continue;
2555 }
2556 if (p.pid == initialPid) {
2557 proc = p;
2558 break;
2559 }
2560 for (String str : p.pkgList) {
2561 if (str.equals(packageName)) {
2562 proc = p;
2563 }
2564 }
2565 }
2566 }
2567
2568 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002569 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002570 + " initialPid=" + initialPid
2571 + " packageName=" + packageName);
2572 return;
2573 }
2574
2575 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002576 if (proc.pid == Process.myPid()) {
2577 Log.w(TAG, "crashApplication: trying to crash self!");
2578 return;
2579 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002580 long ident = Binder.clearCallingIdentity();
2581 try {
2582 proc.thread.scheduleCrash(message);
2583 } catch (RemoteException e) {
2584 }
2585 Binder.restoreCallingIdentity(ident);
2586 }
2587 }
2588 }
2589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 public final void finishSubActivity(IBinder token, String resultWho,
2591 int requestCode) {
2592 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002593 ActivityRecord self = mMainStack.isInStackLocked(token);
2594 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 return;
2596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597
2598 final long origId = Binder.clearCallingIdentity();
2599
2600 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002601 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2602 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 if (r.resultTo == self && r.requestCode == requestCode) {
2604 if ((r.resultWho == null && resultWho == null) ||
2605 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002606 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 Activity.RESULT_CANCELED, null, "request-sub");
2608 }
2609 }
2610 }
2611
2612 Binder.restoreCallingIdentity(origId);
2613 }
2614 }
2615
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002616 public boolean willActivityBeVisible(IBinder token) {
2617 synchronized(this) {
2618 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002619 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2620 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002621 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002622 return true;
2623 }
2624 if (r.fullscreen && !r.finishing) {
2625 return false;
2626 }
2627 }
2628 return true;
2629 }
2630 }
2631
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002632 public void overridePendingTransition(IBinder token, String packageName,
2633 int enterAnim, int exitAnim) {
2634 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002635 ActivityRecord self = mMainStack.isInStackLocked(token);
2636 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002637 return;
2638 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002639
2640 final long origId = Binder.clearCallingIdentity();
2641
2642 if (self.state == ActivityState.RESUMED
2643 || self.state == ActivityState.PAUSING) {
2644 mWindowManager.overridePendingAppTransition(packageName,
2645 enterAnim, exitAnim);
2646 }
2647
2648 Binder.restoreCallingIdentity(origId);
2649 }
2650 }
2651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 * Main function for removing an existing process from the activity manager
2654 * as a result of that process going away. Clears out all connections
2655 * to the process.
2656 */
2657 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002658 boolean restarting, boolean allowRestart) {
2659 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002660 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002661 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 }
2663
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002664 if (mProfileProc == app) {
2665 clearProfilerLocked();
2666 }
2667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002669 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2670 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2671 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002673 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2674 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675 }
2676
2677 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002678 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679
2680 boolean atTop = true;
2681 boolean hasVisibleActivities = false;
2682
2683 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002684 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002685 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 TAG, "Removing app " + app + " from history with " + i + " entries");
2687 while (i > 0) {
2688 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002689 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002690 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2692 if (r.app == app) {
2693 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002694 if (ActivityStack.DEBUG_ADD_REMOVE) {
2695 RuntimeException here = new RuntimeException("here");
2696 here.fillInStackTrace();
2697 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2698 + ": haveState=" + r.haveState
2699 + " stateNotNeeded=" + r.stateNotNeeded
2700 + " finishing=" + r.finishing
2701 + " state=" + r.state, here);
2702 }
2703 if (!r.finishing) {
2704 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2705 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002706 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002707 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002708 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002709 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002710 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002711 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002713 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714
2715 } else {
2716 // We have the current state for this activity, so
2717 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002718 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 TAG, "Keeping entry, setting app to null");
2720 if (r.visible) {
2721 hasVisibleActivities = true;
2722 }
2723 r.app = null;
2724 r.nowVisible = false;
2725 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002726 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2727 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002728 r.icicle = null;
2729 }
2730 }
2731
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002732 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 }
2734 atTop = false;
2735 }
2736
2737 app.activities.clear();
2738
2739 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002740 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002741 + " running instrumentation " + app.instrumentationClass);
2742 Bundle info = new Bundle();
2743 info.putString("shortMsg", "Process crashed.");
2744 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2745 }
2746
2747 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002748 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 // If there was nothing to resume, and we are not already
2750 // restarting this process, but there is a visible activity that
2751 // is hosted by the process... then make sure all visible
2752 // activities are running, taking care of restarting this
2753 // process.
2754 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002755 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 }
2757 }
2758 }
2759 }
2760
2761 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2762 IBinder threadBinder = thread.asBinder();
2763
2764 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002765 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2766 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2768 return i;
2769 }
2770 }
2771 return -1;
2772 }
2773
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002774 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 IApplicationThread thread) {
2776 if (thread == null) {
2777 return null;
2778 }
2779
2780 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002781 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002782 }
2783
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002784 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 IApplicationThread thread) {
2786
2787 mProcDeaths[0]++;
2788
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002789 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2790 synchronized (stats) {
2791 stats.noteProcessDiedLocked(app.info.uid, pid);
2792 }
2793
Magnus Edlund7bb25812010-02-24 15:45:06 +01002794 // Clean up already done if the process has been re-started.
2795 if (app.pid == pid && app.thread != null &&
2796 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002797 if (!app.killedBackground) {
2798 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2799 + ") has died.");
2800 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002801 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002802 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 TAG, "Dying app: " + app + ", pid: " + pid
2804 + ", thread: " + thread.asBinder());
2805 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002806 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807
2808 if (doLowMem) {
2809 // If there are no longer any background processes running,
2810 // and the app that died was not running instrumentation,
2811 // then tell everyone we are now low on memory.
2812 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002813 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2814 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002815 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 haveBg = true;
2817 break;
2818 }
2819 }
2820
2821 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002822 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002823 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002824 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2825 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002826 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002827 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2828 // The low memory report is overriding any current
2829 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002830 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002831 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002832 rec.lastRequestedGc = 0;
2833 } else {
2834 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002836 rec.reportLowMemory = true;
2837 rec.lastLowMemory = now;
2838 mProcessesToGc.remove(rec);
2839 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 }
2841 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002842 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002843 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002844 }
2845 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002846 } else if (app.pid != pid) {
2847 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002848 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002849 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002850 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002851 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002852 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 + thread.asBinder());
2854 }
2855 }
2856
Dan Egnor42471dd2010-01-07 17:25:22 -08002857 /**
2858 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002859 * @param clearTraces causes the dump file to be erased prior to the new
2860 * traces being written, if true; when false, the new traces will be
2861 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002862 * @param firstPids of dalvik VM processes to dump stack traces for first
2863 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002864 * @return file containing stack traces, or null if no dump file is configured
2865 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002866 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2867 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002868 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2869 if (tracesPath == null || tracesPath.length() == 0) {
2870 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002871 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002872
2873 File tracesFile = new File(tracesPath);
2874 try {
2875 File tracesDir = tracesFile.getParentFile();
2876 if (!tracesDir.exists()) tracesFile.mkdirs();
2877 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2878
Christopher Tate6ee412d2010-05-28 12:01:56 -07002879 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002880 tracesFile.createNewFile();
2881 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2882 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002883 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002884 return null;
2885 }
2886
2887 // Use a FileObserver to detect when traces finish writing.
2888 // The order of traces is considered important to maintain for legibility.
2889 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2890 public synchronized void onEvent(int event, String path) { notify(); }
2891 };
2892
2893 try {
2894 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002895
2896 // First collect all of the stacks of the most important pids.
2897 try {
2898 int num = firstPids.size();
2899 for (int i = 0; i < num; i++) {
2900 synchronized (observer) {
2901 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2902 observer.wait(200); // Wait for write-close, give up after 200msec
2903 }
2904 }
2905 } catch (InterruptedException e) {
2906 Log.wtf(TAG, e);
2907 }
2908
2909 // Next measure CPU usage.
2910 if (processStats != null) {
2911 processStats.init();
2912 System.gc();
2913 processStats.update();
2914 try {
2915 synchronized (processStats) {
2916 processStats.wait(500); // measure over 1/2 second.
2917 }
2918 } catch (InterruptedException e) {
2919 }
2920 processStats.update();
2921
2922 // We'll take the stack crawls of just the top apps using CPU.
2923 final int N = processStats.countWorkingStats();
2924 int numProcs = 0;
2925 for (int i=0; i<N && numProcs<5; i++) {
2926 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2927 if (lastPids.indexOfKey(stats.pid) >= 0) {
2928 numProcs++;
2929 try {
2930 synchronized (observer) {
2931 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2932 observer.wait(200); // Wait for write-close, give up after 200msec
2933 }
2934 } catch (InterruptedException e) {
2935 Log.wtf(TAG, e);
2936 }
2937
2938 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002939 }
2940 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002941
2942 return tracesFile;
2943
Dan Egnor42471dd2010-01-07 17:25:22 -08002944 } finally {
2945 observer.stopWatching();
2946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947 }
2948
Jeff Brown4d94a762010-09-23 11:33:28 -07002949 private final class AppNotResponding implements Runnable {
2950 private final ProcessRecord mApp;
2951 private final String mAnnotation;
2952
2953 public AppNotResponding(ProcessRecord app, String annotation) {
2954 mApp = app;
2955 mAnnotation = annotation;
2956 }
2957
2958 @Override
2959 public void run() {
2960 appNotResponding(mApp, null, null, mAnnotation);
2961 }
2962 }
2963
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002964 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2965 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002966 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2967 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2968
Dianne Hackborn287952c2010-09-22 22:34:31 -07002969 if (mController != null) {
2970 try {
2971 // 0 == continue, -1 = kill process immediately
2972 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2973 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2974 } catch (RemoteException e) {
2975 mController = null;
2976 }
2977 }
2978
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002979 long anrTime = SystemClock.uptimeMillis();
2980 if (MONITOR_CPU_USAGE) {
2981 updateCpuStatsNow();
2982 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002983
2984 synchronized (this) {
2985 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2986 if (mShuttingDown) {
2987 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2988 return;
2989 } else if (app.notResponding) {
2990 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2991 return;
2992 } else if (app.crashing) {
2993 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2994 return;
2995 }
2996
2997 // In case we come through here for the same app before completing
2998 // this one, mark as anring now so we will bail out.
2999 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003000
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003001 // Log the ANR to the event log.
3002 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3003 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003004
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003005 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003006 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003007
3008 int parentPid = app.pid;
3009 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003010 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003011
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003012 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003013
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003014 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3015 ProcessRecord r = mLruProcesses.get(i);
3016 if (r != null && r.thread != null) {
3017 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003018 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3019 if (r.persistent) {
3020 firstPids.add(pid);
3021 } else {
3022 lastPids.put(pid, Boolean.TRUE);
3023 }
3024 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 }
3027 }
3028
Dan Egnor42471dd2010-01-07 17:25:22 -08003029 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003030 StringBuilder info = mStringBuilder;
3031 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003032 info.append("ANR in ").append(app.processName);
3033 if (activity != null && activity.shortComponentName != null) {
3034 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003035 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003036 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003038 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003039 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003040 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003041 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003043
Dianne Hackborn287952c2010-09-22 22:34:31 -07003044 final ProcessStats processStats = new ProcessStats(true);
3045
3046 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3047
Dan Egnor42471dd2010-01-07 17:25:22 -08003048 String cpuInfo = null;
3049 if (MONITOR_CPU_USAGE) {
3050 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003051 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003052 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003053 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003054 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003055 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 }
3057
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003058 info.append(processStats.printCurrentState(anrTime));
3059
Joe Onorato8a9b2202010-02-26 18:56:32 -08003060 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003061 if (tracesFile == null) {
3062 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3063 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3064 }
3065
Jeff Sharkeya353d262011-10-28 11:12:06 -07003066 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3067 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003068
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003069 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003070 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003071 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3072 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003074 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3075 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 }
3077 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003078 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 }
3080 }
3081
Dan Egnor42471dd2010-01-07 17:25:22 -08003082 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3083 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3084 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003085
3086 synchronized (this) {
3087 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003088 Slog.w(TAG, "Killing " + app + ": background ANR");
3089 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3090 app.processName, app.setAdj, "background ANR");
3091 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003092 return;
3093 }
3094
3095 // Set the app's notResponding state, and look up the errorReportReceiver
3096 makeAppNotRespondingLocked(app,
3097 activity != null ? activity.shortComponentName : null,
3098 annotation != null ? "ANR " + annotation : "ANR",
3099 info.toString());
3100
3101 // Bring up the infamous App Not Responding dialog
3102 Message msg = Message.obtain();
3103 HashMap map = new HashMap();
3104 msg.what = SHOW_NOT_RESPONDING_MSG;
3105 msg.obj = map;
3106 map.put("app", app);
3107 if (activity != null) {
3108 map.put("activity", activity);
3109 }
3110
3111 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 }
3114
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003115 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3116 if (!mLaunchWarningShown) {
3117 mLaunchWarningShown = true;
3118 mHandler.post(new Runnable() {
3119 @Override
3120 public void run() {
3121 synchronized (ActivityManagerService.this) {
3122 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3123 d.show();
3124 mHandler.postDelayed(new Runnable() {
3125 @Override
3126 public void run() {
3127 synchronized (ActivityManagerService.this) {
3128 d.dismiss();
3129 mLaunchWarningShown = false;
3130 }
3131 }
3132 }, 4000);
3133 }
3134 }
3135 });
3136 }
3137 }
3138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003139 public boolean clearApplicationUserData(final String packageName,
3140 final IPackageDataObserver observer) {
3141 int uid = Binder.getCallingUid();
3142 int pid = Binder.getCallingPid();
3143 long callingId = Binder.clearCallingIdentity();
3144 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003145 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 int pkgUid = -1;
3147 synchronized(this) {
3148 try {
3149 pkgUid = pm.getPackageUid(packageName);
3150 } catch (RemoteException e) {
3151 }
3152 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003153 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 return false;
3155 }
3156 if (uid == pkgUid || checkComponentPermission(
3157 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003158 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003160 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 } else {
3162 throw new SecurityException(pid+" does not have permission:"+
3163 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3164 "for process:"+packageName);
3165 }
3166 }
3167
3168 try {
3169 //clear application user data
3170 pm.clearApplicationUserData(packageName, observer);
3171 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3172 Uri.fromParts("package", packageName, null));
3173 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003174 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3175 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 } catch (RemoteException e) {
3177 }
3178 } finally {
3179 Binder.restoreCallingIdentity(callingId);
3180 }
3181 return true;
3182 }
3183
Dianne Hackborn03abb812010-01-04 18:43:19 -08003184 public void killBackgroundProcesses(final String packageName) {
3185 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3186 != PackageManager.PERMISSION_GRANTED &&
3187 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3188 != PackageManager.PERMISSION_GRANTED) {
3189 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 + Binder.getCallingPid()
3191 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003192 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003193 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 throw new SecurityException(msg);
3195 }
3196
3197 long callingId = Binder.clearCallingIdentity();
3198 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003199 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003200 int pkgUid = -1;
3201 synchronized(this) {
3202 try {
3203 pkgUid = pm.getPackageUid(packageName);
3204 } catch (RemoteException e) {
3205 }
3206 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003207 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 return;
3209 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003210 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003211 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3212 }
3213 } finally {
3214 Binder.restoreCallingIdentity(callingId);
3215 }
3216 }
3217
3218 public void killAllBackgroundProcesses() {
3219 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3220 != PackageManager.PERMISSION_GRANTED) {
3221 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3222 + Binder.getCallingPid()
3223 + ", uid=" + Binder.getCallingUid()
3224 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3225 Slog.w(TAG, msg);
3226 throw new SecurityException(msg);
3227 }
3228
3229 long callingId = Binder.clearCallingIdentity();
3230 try {
3231 synchronized(this) {
3232 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3233 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3234 final int NA = apps.size();
3235 for (int ia=0; ia<NA; ia++) {
3236 ProcessRecord app = apps.valueAt(ia);
3237 if (app.persistent) {
3238 // we don't kill persistent processes
3239 continue;
3240 }
3241 if (app.removed) {
3242 procs.add(app);
3243 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3244 app.removed = true;
3245 procs.add(app);
3246 }
3247 }
3248 }
3249
3250 int N = procs.size();
3251 for (int i=0; i<N; i++) {
3252 removeProcessLocked(procs.get(i), false, true, "kill all background");
3253 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003254 }
3255 } finally {
3256 Binder.restoreCallingIdentity(callingId);
3257 }
3258 }
3259
3260 public void forceStopPackage(final String packageName) {
3261 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3262 != PackageManager.PERMISSION_GRANTED) {
3263 String msg = "Permission Denial: forceStopPackage() from pid="
3264 + Binder.getCallingPid()
3265 + ", uid=" + Binder.getCallingUid()
3266 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003267 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003268 throw new SecurityException(msg);
3269 }
3270
3271 long callingId = Binder.clearCallingIdentity();
3272 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003273 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003274 int pkgUid = -1;
3275 synchronized(this) {
3276 try {
3277 pkgUid = pm.getPackageUid(packageName);
3278 } catch (RemoteException e) {
3279 }
3280 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003281 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003282 return;
3283 }
3284 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003285 try {
3286 pm.setPackageStoppedState(packageName, true);
3287 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003288 } catch (IllegalArgumentException e) {
3289 Slog.w(TAG, "Failed trying to unstop package "
3290 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292 }
3293 } finally {
3294 Binder.restoreCallingIdentity(callingId);
3295 }
3296 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003297
3298 /*
3299 * The pkg name and uid have to be specified.
3300 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3301 */
3302 public void killApplicationWithUid(String pkg, int uid) {
3303 if (pkg == null) {
3304 return;
3305 }
3306 // Make sure the uid is valid.
3307 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003308 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003309 return;
3310 }
3311 int callerUid = Binder.getCallingUid();
3312 // Only the system server can kill an application
3313 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003314 // Post an aysnc message to kill the application
3315 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3316 msg.arg1 = uid;
3317 msg.arg2 = 0;
3318 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003319 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003320 } else {
3321 throw new SecurityException(callerUid + " cannot kill pkg: " +
3322 pkg);
3323 }
3324 }
3325
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003326 public void closeSystemDialogs(String reason) {
3327 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003329 if (reason != null) {
3330 intent.putExtra("reason", reason);
3331 }
3332
3333 final int uid = Binder.getCallingUid();
3334 final long origId = Binder.clearCallingIdentity();
3335 synchronized (this) {
3336 int i = mWatchers.beginBroadcast();
3337 while (i > 0) {
3338 i--;
3339 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3340 if (w != null) {
3341 try {
3342 w.closingSystemDialogs(reason);
3343 } catch (RemoteException e) {
3344 }
3345 }
3346 }
3347 mWatchers.finishBroadcast();
3348
Dianne Hackbornffa42482009-09-23 22:20:11 -07003349 mWindowManager.closeSystemDialogs(reason);
3350
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003351 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3352 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003353 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003354 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003355 Activity.RESULT_CANCELED, null, "close-sys");
3356 }
3357 }
3358
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003359 broadcastIntentLocked(null, null, intent, null,
3360 null, 0, null, null, null, false, false, -1, uid);
3361 }
3362 Binder.restoreCallingIdentity(origId);
3363 }
3364
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003365 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003366 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003367 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3368 for (int i=pids.length-1; i>=0; i--) {
3369 infos[i] = new Debug.MemoryInfo();
3370 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003371 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003372 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003373 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003374
Dianne Hackbornb437e092011-08-05 17:50:29 -07003375 public long[] getProcessPss(int[] pids) throws RemoteException {
3376 long[] pss = new long[pids.length];
3377 for (int i=pids.length-1; i>=0; i--) {
3378 pss[i] = Debug.getPss(pids[i]);
3379 }
3380 return pss;
3381 }
3382
Christopher Tate5e1ab332009-09-01 20:32:49 -07003383 public void killApplicationProcess(String processName, int uid) {
3384 if (processName == null) {
3385 return;
3386 }
3387
3388 int callerUid = Binder.getCallingUid();
3389 // Only the system server can kill an application
3390 if (callerUid == Process.SYSTEM_UID) {
3391 synchronized (this) {
3392 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003393 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003394 try {
3395 app.thread.scheduleSuicide();
3396 } catch (RemoteException e) {
3397 // If the other end already died, then our work here is done.
3398 }
3399 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003400 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003401 + processName + " / " + uid);
3402 }
3403 }
3404 } else {
3405 throw new SecurityException(callerUid + " cannot kill app process: " +
3406 processName);
3407 }
3408 }
3409
Dianne Hackborn03abb812010-01-04 18:43:19 -08003410 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003411 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3413 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003414 if (!mProcessesReady) {
3415 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 intent.putExtra(Intent.EXTRA_UID, uid);
3418 broadcastIntentLocked(null, null, intent,
3419 null, null, 0, null, null, null,
3420 false, false, MY_PID, Process.SYSTEM_UID);
3421 }
3422
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003423 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003424 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003425 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003426 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003427
Dianne Hackborn03abb812010-01-04 18:43:19 -08003428 // Remove all processes this package may have touched: all with the
3429 // same UID (except for the system or root user), and all whose name
3430 // matches the package name.
3431 final String procNamePrefix = packageName + ":";
3432 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3433 final int NA = apps.size();
3434 for (int ia=0; ia<NA; ia++) {
3435 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003436 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003437 // we don't kill persistent processes
3438 continue;
3439 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003440 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003441 if (doit) {
3442 procs.add(app);
3443 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003444 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3445 || app.processName.equals(packageName)
3446 || app.processName.startsWith(procNamePrefix)) {
3447 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003448 if (!doit) {
3449 return true;
3450 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003451 app.removed = true;
3452 procs.add(app);
3453 }
3454 }
3455 }
3456 }
3457
3458 int N = procs.size();
3459 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003460 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003461 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003462 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003463 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003464
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003465 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003466 boolean callerWillRestart, boolean purgeCache, boolean doit,
3467 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003468 int i;
3469 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 if (uid < 0) {
3472 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003473 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 } catch (RemoteException e) {
3475 }
3476 }
3477
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003478 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003479 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003480
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003481 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3482 while (badApps.hasNext()) {
3483 SparseArray<Long> ba = badApps.next();
3484 if (ba.get(uid) != null) {
3485 badApps.remove();
3486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 }
3488 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003489
3490 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003491 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003493 TaskRecord lastTask = null;
3494 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003495 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003496 final boolean samePackage = r.packageName.equals(name);
3497 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003498 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003499 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003500 if (r.finishing) {
3501 // If this activity is just finishing, then it is not
3502 // interesting as far as something to stop.
3503 continue;
3504 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003505 return true;
3506 }
3507 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003508 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003509 if (samePackage) {
3510 if (r.app != null) {
3511 r.app.removed = true;
3512 }
3513 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003515 lastTask = r.task;
3516 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3517 null, "force-stop")) {
3518 i--;
3519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 }
3521 }
3522
3523 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3524 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003525 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003526 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003527 if (!doit) {
3528 return true;
3529 }
3530 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003531 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 if (service.app != null) {
3533 service.app.removed = true;
3534 }
3535 service.app = null;
3536 services.add(service);
3537 }
3538 }
3539
3540 N = services.size();
3541 for (i=0; i<N; i++) {
3542 bringDownServiceLocked(services.get(i), true);
3543 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003544
3545 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3546 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3547 if (provider.info.packageName.equals(name)
3548 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3549 if (!doit) {
3550 return true;
3551 }
3552 didSomething = true;
3553 providers.add(provider);
3554 }
3555 }
3556
3557 N = providers.size();
3558 for (i=0; i<N; i++) {
3559 removeDyingProviderLocked(null, providers.get(i));
3560 }
3561
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003562 if (doit) {
3563 if (purgeCache) {
3564 AttributeCache ac = AttributeCache.instance();
3565 if (ac != null) {
3566 ac.removePackage(name);
3567 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003568 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003569 if (mBooted) {
3570 mMainStack.resumeTopActivityLocked(null);
3571 mMainStack.scheduleIdleLocked();
3572 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003573 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003574
3575 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003576 }
3577
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003578 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003579 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 final String name = app.processName;
3581 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003582 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003583 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 + "/" + uid + ")");
3585
3586 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003587 if (mHeavyWeightProcess == app) {
3588 mHeavyWeightProcess = null;
3589 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 boolean needRestart = false;
3592 if (app.pid > 0 && app.pid != MY_PID) {
3593 int pid = app.pid;
3594 synchronized (mPidsSelfLocked) {
3595 mPidsSelfLocked.remove(pid);
3596 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3597 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003598 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003599 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003600 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003601 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602
3603 if (app.persistent) {
3604 if (!callerWillRestart) {
3605 addAppLocked(app.info);
3606 } else {
3607 needRestart = true;
3608 }
3609 }
3610 } else {
3611 mRemovedProcesses.add(app);
3612 }
3613
3614 return needRestart;
3615 }
3616
3617 private final void processStartTimedOutLocked(ProcessRecord app) {
3618 final int pid = app.pid;
3619 boolean gone = false;
3620 synchronized (mPidsSelfLocked) {
3621 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3622 if (knownApp != null && knownApp.thread == null) {
3623 mPidsSelfLocked.remove(pid);
3624 gone = true;
3625 }
3626 }
3627
3628 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003629 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003630 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003631 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003633 if (mHeavyWeightProcess == app) {
3634 mHeavyWeightProcess = null;
3635 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3636 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003637 // Take care of any launching providers waiting for this process.
3638 checkAppInLaunchingProvidersLocked(app, true);
3639 // Take care of any services that are waiting for the process.
3640 for (int i=0; i<mPendingServices.size(); i++) {
3641 ServiceRecord sr = mPendingServices.get(i);
3642 if (app.info.uid == sr.appInfo.uid
3643 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003644 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003645 mPendingServices.remove(i);
3646 i--;
3647 bringDownServiceLocked(sr, true);
3648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003650 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3651 app.processName, app.setAdj, "start timeout");
3652 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003653 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003654 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003655 try {
3656 IBackupManager bm = IBackupManager.Stub.asInterface(
3657 ServiceManager.getService(Context.BACKUP_SERVICE));
3658 bm.agentDisconnected(app.info.packageName);
3659 } catch (RemoteException e) {
3660 // Can't happen; the backup manager is local
3661 }
3662 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003663 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003664 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003665 mPendingBroadcast.state = BroadcastRecord.IDLE;
3666 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003667 mPendingBroadcast = null;
3668 scheduleBroadcastsLocked();
3669 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003671 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 }
3673 }
3674
3675 private final boolean attachApplicationLocked(IApplicationThread thread,
3676 int pid) {
3677
3678 // Find the application record that is being attached... either via
3679 // the pid if we are running in multiple processes, or just pull the
3680 // next app record if we are emulating process with anonymous threads.
3681 ProcessRecord app;
3682 if (pid != MY_PID && pid >= 0) {
3683 synchronized (mPidsSelfLocked) {
3684 app = mPidsSelfLocked.get(pid);
3685 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003686 } else {
3687 app = null;
3688 }
3689
3690 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003691 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003693 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003695 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 } else {
3697 try {
3698 thread.scheduleExit();
3699 } catch (Exception e) {
3700 // Ignore exceptions.
3701 }
3702 }
3703 return false;
3704 }
3705
3706 // If this application record is still attached to a previous
3707 // process, clean it up now.
3708 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003709 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 }
3711
3712 // Tell the process all about itself.
3713
Joe Onorato8a9b2202010-02-26 18:56:32 -08003714 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003715 TAG, "Binding process pid " + pid + " to record " + app);
3716
3717 String processName = app.processName;
3718 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003719 AppDeathRecipient adr = new AppDeathRecipient(
3720 app, pid, thread);
3721 thread.asBinder().linkToDeath(adr, 0);
3722 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 } catch (RemoteException e) {
3724 app.resetPackageList();
3725 startProcessLocked(app, "link fail", processName);
3726 return false;
3727 }
3728
Doug Zongker2bec3d42009-12-04 12:52:44 -08003729 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003730
3731 app.thread = thread;
3732 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003733 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3734 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 app.forcingToForeground = null;
3736 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003737 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003738 app.debugging = false;
3739
3740 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3741
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003742 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003743 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003745 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003746 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003747 }
3748
Joe Onorato8a9b2202010-02-26 18:56:32 -08003749 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 TAG, "New app record " + app
3751 + " thread=" + thread.asBinder() + " pid=" + pid);
3752 try {
3753 int testMode = IApplicationThread.DEBUG_OFF;
3754 if (mDebugApp != null && mDebugApp.equals(processName)) {
3755 testMode = mWaitForDebugger
3756 ? IApplicationThread.DEBUG_WAIT
3757 : IApplicationThread.DEBUG_ON;
3758 app.debugging = true;
3759 if (mDebugTransient) {
3760 mDebugApp = mOrigDebugApp;
3761 mWaitForDebugger = mOrigWaitForDebugger;
3762 }
3763 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003764 String profileFile = app.instrumentationProfileFile;
3765 ParcelFileDescriptor profileFd = null;
3766 boolean profileAutoStop = false;
3767 if (mProfileApp != null && mProfileApp.equals(processName)) {
3768 mProfileProc = app;
3769 profileFile = mProfileFile;
3770 profileFd = mProfileFd;
3771 profileAutoStop = mAutoStopProfiler;
3772 }
3773
Christopher Tate181fafa2009-05-14 11:12:14 -07003774 // If the app is being launched for restore or full backup, set it up specially
3775 boolean isRestrictedBackupMode = false;
3776 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3777 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003778 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003779 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3780 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003781
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003782 ensurePackageDexOpt(app.instrumentationInfo != null
3783 ? app.instrumentationInfo.packageName
3784 : app.info.packageName);
3785 if (app.instrumentationClass != null) {
3786 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003787 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003788 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003789 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003790 ApplicationInfo appInfo = app.instrumentationInfo != null
3791 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003792 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003793 if (profileFd != null) {
3794 profileFd = profileFd.dup();
3795 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003796 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003797 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003799 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003800 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003801 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003802 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003803 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 } catch (Exception e) {
3805 // todo: Yikes! What should we do? For now we will try to
3806 // start another process, but that could easily get us in
3807 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003808 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003809
3810 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003811 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 startProcessLocked(app, "bind fail", processName);
3813 return false;
3814 }
3815
3816 // Remove this record from the list of starting applications.
3817 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003818 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3819 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003820 mProcessesOnHold.remove(app);
3821
3822 boolean badApp = false;
3823 boolean didSomething = false;
3824
3825 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003826 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003827 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3829 && processName.equals(hr.processName)) {
3830 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003831 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003832 didSomething = true;
3833 }
3834 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003835 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 + hr.intent.getComponent().flattenToShortString(), e);
3837 badApp = true;
3838 }
3839 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003840 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 }
3842 }
3843
3844 // Find any services that should be running in this process...
3845 if (!badApp && mPendingServices.size() > 0) {
3846 ServiceRecord sr = null;
3847 try {
3848 for (int i=0; i<mPendingServices.size(); i++) {
3849 sr = mPendingServices.get(i);
3850 if (app.info.uid != sr.appInfo.uid
3851 || !processName.equals(sr.processName)) {
3852 continue;
3853 }
3854
3855 mPendingServices.remove(i);
3856 i--;
3857 realStartServiceLocked(sr, app);
3858 didSomething = true;
3859 }
3860 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003861 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 + sr.shortName, e);
3863 badApp = true;
3864 }
3865 }
3866
3867 // Check if the next broadcast receiver is in this process...
3868 BroadcastRecord br = mPendingBroadcast;
3869 if (!badApp && br != null && br.curApp == app) {
3870 try {
3871 mPendingBroadcast = null;
3872 processCurBroadcastLocked(br, app);
3873 didSomething = true;
3874 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003875 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 + br.curComponent.flattenToShortString(), e);
3877 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003878 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3880 br.resultExtras, br.resultAbort, true);
3881 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003882 // We need to reset the state if we fails to start the receiver.
3883 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003884 }
3885 }
3886
Christopher Tate181fafa2009-05-14 11:12:14 -07003887 // Check whether the next backup agent is in this process...
3888 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003889 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003890 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003891 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003892 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3893 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3894 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003895 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003896 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003897 e.printStackTrace();
3898 }
3899 }
3900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 if (badApp) {
3902 // todo: Also need to kill application to deal with all
3903 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003904 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 return false;
3906 }
3907
3908 if (!didSomething) {
3909 updateOomAdjLocked();
3910 }
3911
3912 return true;
3913 }
3914
3915 public final void attachApplication(IApplicationThread thread) {
3916 synchronized (this) {
3917 int callingPid = Binder.getCallingPid();
3918 final long origId = Binder.clearCallingIdentity();
3919 attachApplicationLocked(thread, callingPid);
3920 Binder.restoreCallingIdentity(origId);
3921 }
3922 }
3923
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003924 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003926 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3927 if (stopProfiling) {
3928 synchronized (this) {
3929 if (mProfileProc == r.app) {
3930 if (mProfileFd != null) {
3931 try {
3932 mProfileFd.close();
3933 } catch (IOException e) {
3934 }
3935 clearProfilerLocked();
3936 }
3937 }
3938 }
3939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 Binder.restoreCallingIdentity(origId);
3941 }
3942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003944 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003945 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 mWindowManager.enableScreenAfterBoot();
3947 }
3948
Dianne Hackborn661cd522011-08-22 00:26:20 -07003949 public void showBootMessage(final CharSequence msg, final boolean always) {
3950 mWindowManager.showBootMessage(msg, always);
3951 }
3952
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003953 public void dismissKeyguardOnNextActivity() {
3954 synchronized (this) {
3955 mMainStack.dismissKeyguardOnNextActivityLocked();
3956 }
3957 }
3958
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003959 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003960 IntentFilter pkgFilter = new IntentFilter();
3961 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3962 pkgFilter.addDataScheme("package");
3963 mContext.registerReceiver(new BroadcastReceiver() {
3964 @Override
3965 public void onReceive(Context context, Intent intent) {
3966 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3967 if (pkgs != null) {
3968 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003969 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003970 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003971 setResultCode(Activity.RESULT_OK);
3972 return;
3973 }
3974 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003975 }
3976 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003977 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003978 }, pkgFilter);
3979
3980 synchronized (this) {
3981 // Ensure that any processes we had put on hold are now started
3982 // up.
3983 final int NP = mProcessesOnHold.size();
3984 if (NP > 0) {
3985 ArrayList<ProcessRecord> procs =
3986 new ArrayList<ProcessRecord>(mProcessesOnHold);
3987 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003988 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3989 + procs.get(ip));
3990 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003991 }
3992 }
3993
3994 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003995 // Start looking for apps that are abusing wake locks.
3996 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003997 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003998 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003999 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004000 broadcastIntentLocked(null, null,
4001 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4002 null, null, 0, null, null,
4003 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4004 false, false, MY_PID, Process.SYSTEM_UID);
4005 }
4006 }
4007 }
4008
4009 final void ensureBootCompleted() {
4010 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004011 boolean enableScreen;
4012 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004013 booting = mBooting;
4014 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004015 enableScreen = !mBooted;
4016 mBooted = true;
4017 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004018
4019 if (booting) {
4020 finishBooting();
4021 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004022
4023 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004024 enableScreenAfterBoot();
4025 }
4026 }
4027
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004028 public final void activityPaused(IBinder token) {
4029 final long origId = Binder.clearCallingIdentity();
4030 mMainStack.activityPaused(token, false);
4031 Binder.restoreCallingIdentity(origId);
4032 }
4033
4034 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4035 CharSequence description) {
4036 if (localLOGV) Slog.v(
4037 TAG, "Activity stopped: token=" + token);
4038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 // Refuse possible leaked file descriptors
4040 if (icicle != null && icicle.hasFileDescriptors()) {
4041 throw new IllegalArgumentException("File descriptors passed in Bundle");
4042 }
4043
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004044 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004045
4046 final long origId = Binder.clearCallingIdentity();
4047
4048 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004049 r = mMainStack.isInStackLocked(token);
4050 if (r != null) {
4051 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 }
4053 }
4054
4055 if (r != null) {
4056 sendPendingThumbnail(r, null, null, null, false);
4057 }
4058
4059 trimApplications();
4060
4061 Binder.restoreCallingIdentity(origId);
4062 }
4063
4064 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004065 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004066 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 }
4068
4069 public String getCallingPackage(IBinder token) {
4070 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004071 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004072 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 }
4074 }
4075
4076 public ComponentName getCallingActivity(IBinder token) {
4077 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004078 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 return r != null ? r.intent.getComponent() : null;
4080 }
4081 }
4082
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004083 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004084 ActivityRecord r = mMainStack.isInStackLocked(token);
4085 if (r == null) {
4086 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004088 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 }
4090
4091 public ComponentName getActivityClassForToken(IBinder token) {
4092 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004093 ActivityRecord r = mMainStack.isInStackLocked(token);
4094 if (r == null) {
4095 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004097 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 }
4099 }
4100
4101 public String getPackageForToken(IBinder token) {
4102 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004103 ActivityRecord r = mMainStack.isInStackLocked(token);
4104 if (r == null) {
4105 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004106 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004107 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004108 }
4109 }
4110
4111 public IIntentSender getIntentSender(int type,
4112 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004113 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004115 if (intents != null) {
4116 if (intents.length < 1) {
4117 throw new IllegalArgumentException("Intents array length must be >= 1");
4118 }
4119 for (int i=0; i<intents.length; i++) {
4120 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004121 if (intent != null) {
4122 if (intent.hasFileDescriptors()) {
4123 throw new IllegalArgumentException("File descriptors passed in Intent");
4124 }
4125 if (type == INTENT_SENDER_BROADCAST &&
4126 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4127 throw new IllegalArgumentException(
4128 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4129 }
4130 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004131 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004132 }
4133 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004134 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004135 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004136 }
4137 }
4138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004139 synchronized(this) {
4140 int callingUid = Binder.getCallingUid();
4141 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004142 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004143 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004144 .getPackageUid(packageName);
4145 if (uid != Binder.getCallingUid()) {
4146 String msg = "Permission Denial: getIntentSender() from pid="
4147 + Binder.getCallingPid()
4148 + ", uid=" + Binder.getCallingUid()
4149 + ", (need uid=" + uid + ")"
4150 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004151 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 throw new SecurityException(msg);
4153 }
4154 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004155
4156 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004157 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004159 } catch (RemoteException e) {
4160 throw new SecurityException(e);
4161 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004162 }
4163 }
4164
4165 IIntentSender getIntentSenderLocked(int type,
4166 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004167 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004168 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004169 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004170 activity = mMainStack.isInStackLocked(token);
4171 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004172 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004173 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004174 if (activity.finishing) {
4175 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004177 }
4178
4179 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4180 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4181 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4182 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4183 |PendingIntent.FLAG_UPDATE_CURRENT);
4184
4185 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4186 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004187 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004188 WeakReference<PendingIntentRecord> ref;
4189 ref = mIntentSenderRecords.get(key);
4190 PendingIntentRecord rec = ref != null ? ref.get() : null;
4191 if (rec != null) {
4192 if (!cancelCurrent) {
4193 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004194 if (rec.key.requestIntent != null) {
4195 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4196 }
4197 if (intents != null) {
4198 intents[intents.length-1] = rec.key.requestIntent;
4199 rec.key.allIntents = intents;
4200 rec.key.allResolvedTypes = resolvedTypes;
4201 } else {
4202 rec.key.allIntents = null;
4203 rec.key.allResolvedTypes = null;
4204 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 return rec;
4207 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004208 rec.canceled = true;
4209 mIntentSenderRecords.remove(key);
4210 }
4211 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 return rec;
4213 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004214 rec = new PendingIntentRecord(this, key, callingUid);
4215 mIntentSenderRecords.put(key, rec.ref);
4216 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4217 if (activity.pendingResults == null) {
4218 activity.pendingResults
4219 = new HashSet<WeakReference<PendingIntentRecord>>();
4220 }
4221 activity.pendingResults.add(rec.ref);
4222 }
4223 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 }
4225
4226 public void cancelIntentSender(IIntentSender sender) {
4227 if (!(sender instanceof PendingIntentRecord)) {
4228 return;
4229 }
4230 synchronized(this) {
4231 PendingIntentRecord rec = (PendingIntentRecord)sender;
4232 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004233 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 .getPackageUid(rec.key.packageName);
4235 if (uid != Binder.getCallingUid()) {
4236 String msg = "Permission Denial: cancelIntentSender() from pid="
4237 + Binder.getCallingPid()
4238 + ", uid=" + Binder.getCallingUid()
4239 + " is not allowed to cancel packges "
4240 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004241 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 throw new SecurityException(msg);
4243 }
4244 } catch (RemoteException e) {
4245 throw new SecurityException(e);
4246 }
4247 cancelIntentSenderLocked(rec, true);
4248 }
4249 }
4250
4251 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4252 rec.canceled = true;
4253 mIntentSenderRecords.remove(rec.key);
4254 if (cleanActivity && rec.key.activity != null) {
4255 rec.key.activity.pendingResults.remove(rec.ref);
4256 }
4257 }
4258
4259 public String getPackageForIntentSender(IIntentSender pendingResult) {
4260 if (!(pendingResult instanceof PendingIntentRecord)) {
4261 return null;
4262 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004263 try {
4264 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4265 return res.key.packageName;
4266 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 }
4268 return null;
4269 }
4270
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004271 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4272 if (!(pendingResult instanceof PendingIntentRecord)) {
4273 return false;
4274 }
4275 try {
4276 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4277 if (res.key.allIntents == null) {
4278 return false;
4279 }
4280 for (int i=0; i<res.key.allIntents.length; i++) {
4281 Intent intent = res.key.allIntents[i];
4282 if (intent.getPackage() != null && intent.getComponent() != null) {
4283 return false;
4284 }
4285 }
4286 return true;
4287 } catch (ClassCastException e) {
4288 }
4289 return false;
4290 }
4291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 public void setProcessLimit(int max) {
4293 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4294 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004295 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004296 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004297 mProcessLimitOverride = max;
4298 }
4299 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 }
4301
4302 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004303 synchronized (this) {
4304 return mProcessLimitOverride;
4305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 }
4307
4308 void foregroundTokenDied(ForegroundToken token) {
4309 synchronized (ActivityManagerService.this) {
4310 synchronized (mPidsSelfLocked) {
4311 ForegroundToken cur
4312 = mForegroundProcesses.get(token.pid);
4313 if (cur != token) {
4314 return;
4315 }
4316 mForegroundProcesses.remove(token.pid);
4317 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4318 if (pr == null) {
4319 return;
4320 }
4321 pr.forcingToForeground = null;
4322 pr.foregroundServices = false;
4323 }
4324 updateOomAdjLocked();
4325 }
4326 }
4327
4328 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4329 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4330 "setProcessForeground()");
4331 synchronized(this) {
4332 boolean changed = false;
4333
4334 synchronized (mPidsSelfLocked) {
4335 ProcessRecord pr = mPidsSelfLocked.get(pid);
4336 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004337 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 return;
4339 }
4340 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4341 if (oldToken != null) {
4342 oldToken.token.unlinkToDeath(oldToken, 0);
4343 mForegroundProcesses.remove(pid);
4344 pr.forcingToForeground = null;
4345 changed = true;
4346 }
4347 if (isForeground && token != null) {
4348 ForegroundToken newToken = new ForegroundToken() {
4349 public void binderDied() {
4350 foregroundTokenDied(this);
4351 }
4352 };
4353 newToken.pid = pid;
4354 newToken.token = token;
4355 try {
4356 token.linkToDeath(newToken, 0);
4357 mForegroundProcesses.put(pid, newToken);
4358 pr.forcingToForeground = token;
4359 changed = true;
4360 } catch (RemoteException e) {
4361 // If the process died while doing this, we will later
4362 // do the cleanup with the process death link.
4363 }
4364 }
4365 }
4366
4367 if (changed) {
4368 updateOomAdjLocked();
4369 }
4370 }
4371 }
4372
4373 // =========================================================
4374 // PERMISSIONS
4375 // =========================================================
4376
4377 static class PermissionController extends IPermissionController.Stub {
4378 ActivityManagerService mActivityManagerService;
4379 PermissionController(ActivityManagerService activityManagerService) {
4380 mActivityManagerService = activityManagerService;
4381 }
4382
4383 public boolean checkPermission(String permission, int pid, int uid) {
4384 return mActivityManagerService.checkPermission(permission, pid,
4385 uid) == PackageManager.PERMISSION_GRANTED;
4386 }
4387 }
4388
4389 /**
4390 * This can be called with or without the global lock held.
4391 */
4392 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004393 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004394 // We might be performing an operation on behalf of an indirect binder
4395 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4396 // client identity accordingly before proceeding.
4397 Identity tlsIdentity = sCallerIdentity.get();
4398 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004399 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4401 uid = tlsIdentity.uid;
4402 pid = tlsIdentity.pid;
4403 }
4404
4405 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004406 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 return PackageManager.PERMISSION_GRANTED;
4408 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004409 // If there is a uid that owns whatever is being accessed, it has
4410 // blanket access to it regardless of the permissions it requires.
4411 if (owningUid >= 0 && uid == owningUid) {
4412 return PackageManager.PERMISSION_GRANTED;
4413 }
4414 // If the target is not exported, then nobody else can get to it.
4415 if (!exported) {
4416 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 return PackageManager.PERMISSION_DENIED;
4418 }
4419 if (permission == null) {
4420 return PackageManager.PERMISSION_GRANTED;
4421 }
4422 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004423 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 .checkUidPermission(permission, uid);
4425 } catch (RemoteException e) {
4426 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004427 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 }
4429 return PackageManager.PERMISSION_DENIED;
4430 }
4431
4432 /**
4433 * As the only public entry point for permissions checking, this method
4434 * can enforce the semantic that requesting a check on a null global
4435 * permission is automatically denied. (Internally a null permission
4436 * string is used when calling {@link #checkComponentPermission} in cases
4437 * when only uid-based security is needed.)
4438 *
4439 * This can be called with or without the global lock held.
4440 */
4441 public int checkPermission(String permission, int pid, int uid) {
4442 if (permission == null) {
4443 return PackageManager.PERMISSION_DENIED;
4444 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004445 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 }
4447
4448 /**
4449 * Binder IPC calls go through the public entry point.
4450 * This can be called with or without the global lock held.
4451 */
4452 int checkCallingPermission(String permission) {
4453 return checkPermission(permission,
4454 Binder.getCallingPid(),
4455 Binder.getCallingUid());
4456 }
4457
4458 /**
4459 * This can be called with or without the global lock held.
4460 */
4461 void enforceCallingPermission(String permission, String func) {
4462 if (checkCallingPermission(permission)
4463 == PackageManager.PERMISSION_GRANTED) {
4464 return;
4465 }
4466
4467 String msg = "Permission Denial: " + func + " from pid="
4468 + Binder.getCallingPid()
4469 + ", uid=" + Binder.getCallingUid()
4470 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004471 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 throw new SecurityException(msg);
4473 }
4474
4475 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004476 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4477 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4478 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4479 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4480 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004482 // Is the component private from the target uid?
4483 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4484
4485 // Acceptable if the there is no read permission needed from the
4486 // target or the target is holding the read permission.
4487 if (!readPerm) {
4488 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004489 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004490 == PackageManager.PERMISSION_GRANTED)) {
4491 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 }
4493 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004494
4495 // Acceptable if the there is no write permission needed from the
4496 // target or the target is holding the read permission.
4497 if (!writePerm) {
4498 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004500 == PackageManager.PERMISSION_GRANTED)) {
4501 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 }
4503 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004504
4505 // Acceptable if there is a path permission matching the URI that
4506 // the target holds the permission on.
4507 PathPermission[] pps = pi.pathPermissions;
4508 if (pps != null && (!readPerm || !writePerm)) {
4509 final String path = uri.getPath();
4510 int i = pps.length;
4511 while (i > 0 && (!readPerm || !writePerm)) {
4512 i--;
4513 PathPermission pp = pps[i];
4514 if (!readPerm) {
4515 final String pprperm = pp.getReadPermission();
4516 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4517 + pprperm + " for " + pp.getPath()
4518 + ": match=" + pp.match(path)
4519 + " check=" + pm.checkUidPermission(pprperm, uid));
4520 if (pprperm != null && pp.match(path) &&
4521 (pm.checkUidPermission(pprperm, uid)
4522 == PackageManager.PERMISSION_GRANTED)) {
4523 readPerm = true;
4524 }
4525 }
4526 if (!writePerm) {
4527 final String ppwperm = pp.getWritePermission();
4528 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4529 + ppwperm + " for " + pp.getPath()
4530 + ": match=" + pp.match(path)
4531 + " check=" + pm.checkUidPermission(ppwperm, uid));
4532 if (ppwperm != null && pp.match(path) &&
4533 (pm.checkUidPermission(ppwperm, uid)
4534 == PackageManager.PERMISSION_GRANTED)) {
4535 writePerm = true;
4536 }
4537 }
4538 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 } catch (RemoteException e) {
4541 return false;
4542 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004543
4544 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 }
4546
4547 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4548 int modeFlags) {
4549 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004550 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 return true;
4552 }
4553 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4554 if (perms == null) return false;
4555 UriPermission perm = perms.get(uri);
4556 if (perm == null) return false;
4557 return (modeFlags&perm.modeFlags) == modeFlags;
4558 }
4559
4560 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4561 // Another redirected-binder-call permissions check as in
4562 // {@link checkComponentPermission}.
4563 Identity tlsIdentity = sCallerIdentity.get();
4564 if (tlsIdentity != null) {
4565 uid = tlsIdentity.uid;
4566 pid = tlsIdentity.pid;
4567 }
4568
4569 // Our own process gets to do everything.
4570 if (pid == MY_PID) {
4571 return PackageManager.PERMISSION_GRANTED;
4572 }
4573 synchronized(this) {
4574 return checkUriPermissionLocked(uri, uid, modeFlags)
4575 ? PackageManager.PERMISSION_GRANTED
4576 : PackageManager.PERMISSION_DENIED;
4577 }
4578 }
4579
Dianne Hackborn39792d22010-08-19 18:01:52 -07004580 /**
4581 * Check if the targetPkg can be granted permission to access uri by
4582 * the callingUid using the given modeFlags. Throws a security exception
4583 * if callingUid is not allowed to do this. Returns the uid of the target
4584 * if the URI permission grant should be performed; returns -1 if it is not
4585 * needed (for example targetPkg already has permission to access the URI).
4586 */
4587 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4588 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004589 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4590 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4591 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004592 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 }
4594
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004595 if (targetPkg != null) {
4596 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4597 "Checking grant " + targetPkg + " permission to " + uri);
4598 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004599
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004600 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601
4602 // If this is not a content: uri, we can't do anything with it.
4603 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004604 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004605 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004606 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 }
4608
4609 String name = uri.getAuthority();
4610 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004611 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 if (cpr != null) {
4613 pi = cpr.info;
4614 } else {
4615 try {
4616 pi = pm.resolveContentProvider(name,
4617 PackageManager.GET_URI_PERMISSION_PATTERNS);
4618 } catch (RemoteException ex) {
4619 }
4620 }
4621 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004622 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004623 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 }
4625
4626 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004627 if (targetPkg != null) {
4628 try {
4629 targetUid = pm.getPackageUid(targetPkg);
4630 if (targetUid < 0) {
4631 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4632 "Can't grant URI permission no uid for: " + targetPkg);
4633 return -1;
4634 }
4635 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004636 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004638 } else {
4639 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 }
4641
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004642 if (targetUid >= 0) {
4643 // First... does the target actually need this permission?
4644 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4645 // No need to grant the target this permission.
4646 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4647 "Target " + targetPkg + " already has full permission to " + uri);
4648 return -1;
4649 }
4650 } else {
4651 // First... there is no target package, so can anyone access it?
4652 boolean allowed = pi.exported;
4653 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4654 if (pi.readPermission != null) {
4655 allowed = false;
4656 }
4657 }
4658 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4659 if (pi.writePermission != null) {
4660 allowed = false;
4661 }
4662 }
4663 if (allowed) {
4664 return -1;
4665 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 }
4667
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004668 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004669 if (!pi.grantUriPermissions) {
4670 throw new SecurityException("Provider " + pi.packageName
4671 + "/" + pi.name
4672 + " does not allow granting of Uri permissions (uri "
4673 + uri + ")");
4674 }
4675 if (pi.uriPermissionPatterns != null) {
4676 final int N = pi.uriPermissionPatterns.length;
4677 boolean allowed = false;
4678 for (int i=0; i<N; i++) {
4679 if (pi.uriPermissionPatterns[i] != null
4680 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4681 allowed = true;
4682 break;
4683 }
4684 }
4685 if (!allowed) {
4686 throw new SecurityException("Provider " + pi.packageName
4687 + "/" + pi.name
4688 + " does not allow granting of permission to path of Uri "
4689 + uri);
4690 }
4691 }
4692
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004693 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004695 if (callingUid != Process.myUid()) {
4696 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4697 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4698 throw new SecurityException("Uid " + callingUid
4699 + " does not have permission to uri " + uri);
4700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 }
4702 }
4703
Dianne Hackborn39792d22010-08-19 18:01:52 -07004704 return targetUid;
4705 }
4706
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004707 public int checkGrantUriPermission(int callingUid, String targetPkg,
4708 Uri uri, int modeFlags) {
4709 synchronized(this) {
4710 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4711 }
4712 }
4713
Dianne Hackborn39792d22010-08-19 18:01:52 -07004714 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4715 Uri uri, int modeFlags, UriPermissionOwner owner) {
4716 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4717 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4718 if (modeFlags == 0) {
4719 return;
4720 }
4721
4722 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 // to the uri, and the target doesn't. Let's now give this to
4724 // the target.
4725
Joe Onorato8a9b2202010-02-26 18:56:32 -08004726 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004727 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 HashMap<Uri, UriPermission> targetUris
4730 = mGrantedUriPermissions.get(targetUid);
4731 if (targetUris == null) {
4732 targetUris = new HashMap<Uri, UriPermission>();
4733 mGrantedUriPermissions.put(targetUid, targetUris);
4734 }
4735
4736 UriPermission perm = targetUris.get(uri);
4737 if (perm == null) {
4738 perm = new UriPermission(targetUid, uri);
4739 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004742 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004743 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004745 } else {
4746 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4747 perm.readOwners.add(owner);
4748 owner.addReadPermission(perm);
4749 }
4750 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4751 perm.writeOwners.add(owner);
4752 owner.addWritePermission(perm);
4753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 }
4755 }
4756
Dianne Hackborn39792d22010-08-19 18:01:52 -07004757 void grantUriPermissionLocked(int callingUid,
4758 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004759 if (targetPkg == null) {
4760 throw new NullPointerException("targetPkg");
4761 }
4762
Dianne Hackborn39792d22010-08-19 18:01:52 -07004763 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4764 if (targetUid < 0) {
4765 return;
4766 }
4767
4768 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4769 }
4770
4771 /**
4772 * Like checkGrantUriPermissionLocked, but takes an Intent.
4773 */
4774 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4775 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004776 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004777 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004778 + " from " + intent + "; flags=0x"
4779 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4780
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004781 if (targetPkg == null) {
4782 throw new NullPointerException("targetPkg");
4783 }
4784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004785 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004786 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787 }
4788 Uri data = intent.getData();
4789 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004790 return -1;
4791 }
4792 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4793 intent.getFlags());
4794 }
4795
4796 /**
4797 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4798 */
4799 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4800 String targetPkg, Intent intent, UriPermissionOwner owner) {
4801 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4802 intent.getFlags(), owner);
4803 }
4804
4805 void grantUriPermissionFromIntentLocked(int callingUid,
4806 String targetPkg, Intent intent, UriPermissionOwner owner) {
4807 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4808 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004809 return;
4810 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004811
4812 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 }
4814
4815 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4816 Uri uri, int modeFlags) {
4817 synchronized(this) {
4818 final ProcessRecord r = getRecordForAppLocked(caller);
4819 if (r == null) {
4820 throw new SecurityException("Unable to find app for caller "
4821 + caller
4822 + " when granting permission to uri " + uri);
4823 }
4824 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004825 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004826 }
4827 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004828 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004829 }
4830
4831 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4832 null);
4833 }
4834 }
4835
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004836 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004837 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4838 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4839 HashMap<Uri, UriPermission> perms
4840 = mGrantedUriPermissions.get(perm.uid);
4841 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004842 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004843 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 perms.remove(perm.uri);
4845 if (perms.size() == 0) {
4846 mGrantedUriPermissions.remove(perm.uid);
4847 }
4848 }
4849 }
4850 }
4851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4853 int modeFlags) {
4854 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4855 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4856 if (modeFlags == 0) {
4857 return;
4858 }
4859
Joe Onorato8a9b2202010-02-26 18:56:32 -08004860 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004861 "Revoking all granted permissions to " + uri);
4862
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004863 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864
4865 final String authority = uri.getAuthority();
4866 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004867 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004868 if (cpr != null) {
4869 pi = cpr.info;
4870 } else {
4871 try {
4872 pi = pm.resolveContentProvider(authority,
4873 PackageManager.GET_URI_PERMISSION_PATTERNS);
4874 } catch (RemoteException ex) {
4875 }
4876 }
4877 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004878 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 return;
4880 }
4881
4882 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004883 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004884 // Right now, if you are not the original owner of the permission,
4885 // you are not allowed to revoke it.
4886 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4887 throw new SecurityException("Uid " + callingUid
4888 + " does not have permission to uri " + uri);
4889 //}
4890 }
4891
4892 // Go through all of the permissions and remove any that match.
4893 final List<String> SEGMENTS = uri.getPathSegments();
4894 if (SEGMENTS != null) {
4895 final int NS = SEGMENTS.size();
4896 int N = mGrantedUriPermissions.size();
4897 for (int i=0; i<N; i++) {
4898 HashMap<Uri, UriPermission> perms
4899 = mGrantedUriPermissions.valueAt(i);
4900 Iterator<UriPermission> it = perms.values().iterator();
4901 toploop:
4902 while (it.hasNext()) {
4903 UriPermission perm = it.next();
4904 Uri targetUri = perm.uri;
4905 if (!authority.equals(targetUri.getAuthority())) {
4906 continue;
4907 }
4908 List<String> targetSegments = targetUri.getPathSegments();
4909 if (targetSegments == null) {
4910 continue;
4911 }
4912 if (targetSegments.size() < NS) {
4913 continue;
4914 }
4915 for (int j=0; j<NS; j++) {
4916 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4917 continue toploop;
4918 }
4919 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004920 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004921 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 perm.clearModes(modeFlags);
4923 if (perm.modeFlags == 0) {
4924 it.remove();
4925 }
4926 }
4927 if (perms.size() == 0) {
4928 mGrantedUriPermissions.remove(
4929 mGrantedUriPermissions.keyAt(i));
4930 N--;
4931 i--;
4932 }
4933 }
4934 }
4935 }
4936
4937 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4938 int modeFlags) {
4939 synchronized(this) {
4940 final ProcessRecord r = getRecordForAppLocked(caller);
4941 if (r == null) {
4942 throw new SecurityException("Unable to find app for caller "
4943 + caller
4944 + " when revoking permission to uri " + uri);
4945 }
4946 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004947 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004948 return;
4949 }
4950
4951 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4952 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4953 if (modeFlags == 0) {
4954 return;
4955 }
4956
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004957 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958
4959 final String authority = uri.getAuthority();
4960 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004961 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 if (cpr != null) {
4963 pi = cpr.info;
4964 } else {
4965 try {
4966 pi = pm.resolveContentProvider(authority,
4967 PackageManager.GET_URI_PERMISSION_PATTERNS);
4968 } catch (RemoteException ex) {
4969 }
4970 }
4971 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004972 Slog.w(TAG, "No content provider found for permission revoke: "
4973 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004974 return;
4975 }
4976
4977 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4978 }
4979 }
4980
Dianne Hackborn7e269642010-08-25 19:50:20 -07004981 @Override
4982 public IBinder newUriPermissionOwner(String name) {
4983 synchronized(this) {
4984 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4985 return owner.getExternalTokenLocked();
4986 }
4987 }
4988
4989 @Override
4990 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4991 Uri uri, int modeFlags) {
4992 synchronized(this) {
4993 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4994 if (owner == null) {
4995 throw new IllegalArgumentException("Unknown owner: " + token);
4996 }
4997 if (fromUid != Binder.getCallingUid()) {
4998 if (Binder.getCallingUid() != Process.myUid()) {
4999 // Only system code can grant URI permissions on behalf
5000 // of other users.
5001 throw new SecurityException("nice try");
5002 }
5003 }
5004 if (targetPkg == null) {
5005 throw new IllegalArgumentException("null target");
5006 }
5007 if (uri == null) {
5008 throw new IllegalArgumentException("null uri");
5009 }
5010
5011 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5012 }
5013 }
5014
5015 @Override
5016 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5017 synchronized(this) {
5018 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5019 if (owner == null) {
5020 throw new IllegalArgumentException("Unknown owner: " + token);
5021 }
5022
5023 if (uri == null) {
5024 owner.removeUriPermissionsLocked(mode);
5025 } else {
5026 owner.removeUriPermissionLocked(uri, mode);
5027 }
5028 }
5029 }
5030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005031 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5032 synchronized (this) {
5033 ProcessRecord app =
5034 who != null ? getRecordForAppLocked(who) : null;
5035 if (app == null) return;
5036
5037 Message msg = Message.obtain();
5038 msg.what = WAIT_FOR_DEBUGGER_MSG;
5039 msg.obj = app;
5040 msg.arg1 = waiting ? 1 : 0;
5041 mHandler.sendMessage(msg);
5042 }
5043 }
5044
5045 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005046 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5047 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005048 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005049 outInfo.threshold = homeAppMem;
5050 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5051 outInfo.hiddenAppThreshold = hiddenAppMem;
5052 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005053 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005054 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5055 ProcessList.VISIBLE_APP_ADJ);
5056 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5057 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 }
5059
5060 // =========================================================
5061 // TASK MANAGEMENT
5062 // =========================================================
5063
5064 public List getTasks(int maxNum, int flags,
5065 IThumbnailReceiver receiver) {
5066 ArrayList list = new ArrayList();
5067
5068 PendingThumbnailsRecord pending = null;
5069 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005070 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071
5072 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005073 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005074 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5075 + ", receiver=" + receiver);
5076
5077 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5078 != PackageManager.PERMISSION_GRANTED) {
5079 if (receiver != null) {
5080 // If the caller wants to wait for pending thumbnails,
5081 // it ain't gonna get them.
5082 try {
5083 receiver.finished();
5084 } catch (RemoteException ex) {
5085 }
5086 }
5087 String msg = "Permission Denial: getTasks() from pid="
5088 + Binder.getCallingPid()
5089 + ", uid=" + Binder.getCallingUid()
5090 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005091 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005092 throw new SecurityException(msg);
5093 }
5094
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005095 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005096 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005097 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005098 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005099 TaskRecord curTask = null;
5100 int numActivities = 0;
5101 int numRunning = 0;
5102 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005103 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005104 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005105 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106
5107 // Initialize state for next task if needed.
5108 if (top == null ||
5109 (top.state == ActivityState.INITIALIZING
5110 && top.task == r.task)) {
5111 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005112 curTask = r.task;
5113 numActivities = numRunning = 0;
5114 }
5115
5116 // Add 'r' into the current task.
5117 numActivities++;
5118 if (r.app != null && r.app.thread != null) {
5119 numRunning++;
5120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005121
Joe Onorato8a9b2202010-02-26 18:56:32 -08005122 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 TAG, r.intent.getComponent().flattenToShortString()
5124 + ": task=" + r.task);
5125
5126 // If the next one is a different task, generate a new
5127 // TaskInfo entry for what we have.
5128 if (next == null || next.task != curTask) {
5129 ActivityManager.RunningTaskInfo ci
5130 = new ActivityManager.RunningTaskInfo();
5131 ci.id = curTask.taskId;
5132 ci.baseActivity = r.intent.getComponent();
5133 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005134 if (top.thumbHolder != null) {
5135 ci.description = top.thumbHolder.lastDescription;
5136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005137 ci.numActivities = numActivities;
5138 ci.numRunning = numRunning;
5139 //System.out.println(
5140 // "#" + maxNum + ": " + " descr=" + ci.description);
5141 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005142 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143 TAG, "State=" + top.state + "Idle=" + top.idle
5144 + " app=" + top.app
5145 + " thr=" + (top.app != null ? top.app.thread : null));
5146 if (top.state == ActivityState.RESUMED
5147 || top.state == ActivityState.PAUSING) {
5148 if (top.idle && top.app != null
5149 && top.app.thread != null) {
5150 topRecord = top;
5151 topThumbnail = top.app.thread;
5152 } else {
5153 top.thumbnailNeeded = true;
5154 }
5155 }
5156 if (pending == null) {
5157 pending = new PendingThumbnailsRecord(receiver);
5158 }
5159 pending.pendingRecords.add(top);
5160 }
5161 list.add(ci);
5162 maxNum--;
5163 top = null;
5164 }
5165 }
5166
5167 if (pending != null) {
5168 mPendingThumbnails.add(pending);
5169 }
5170 }
5171
Joe Onorato8a9b2202010-02-26 18:56:32 -08005172 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005173
5174 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005175 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005176 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005177 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005178 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005179 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005180 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 }
5182 }
5183
5184 if (pending == null && receiver != null) {
5185 // In this case all thumbnails were available and the client
5186 // is being asked to be told when the remaining ones come in...
5187 // which is unusually, since the top-most currently running
5188 // activity should never have a canned thumbnail! Oh well.
5189 try {
5190 receiver.finished();
5191 } catch (RemoteException ex) {
5192 }
5193 }
5194
5195 return list;
5196 }
5197
5198 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5199 int flags) {
5200 synchronized (this) {
5201 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5202 "getRecentTasks()");
5203
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005204 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005206 final int N = mRecentTasks.size();
5207 ArrayList<ActivityManager.RecentTaskInfo> res
5208 = new ArrayList<ActivityManager.RecentTaskInfo>(
5209 maxNum < N ? maxNum : N);
5210 for (int i=0; i<N && maxNum > 0; i++) {
5211 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005212 // Return the entry if desired by the caller. We always return
5213 // the first entry, because callers always expect this to be the
5214 // forground app. We may filter others if the caller has
5215 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5216 // we should exclude the entry.
5217 if (i == 0
5218 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 || (tr.intent == null)
5220 || ((tr.intent.getFlags()
5221 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5222 ActivityManager.RecentTaskInfo rti
5223 = new ActivityManager.RecentTaskInfo();
5224 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005225 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 rti.baseIntent = new Intent(
5227 tr.intent != null ? tr.intent : tr.affinityIntent);
5228 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005229 rti.description = tr.lastDescription;
5230
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005231 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5232 // Check whether this activity is currently available.
5233 try {
5234 if (rti.origActivity != null) {
5235 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5236 continue;
5237 }
5238 } else if (rti.baseIntent != null) {
5239 if (pm.queryIntentActivities(rti.baseIntent,
5240 null, 0) == null) {
5241 continue;
5242 }
5243 }
5244 } catch (RemoteException e) {
5245 // Will never happen.
5246 }
5247 }
5248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 res.add(rti);
5250 maxNum--;
5251 }
5252 }
5253 return res;
5254 }
5255 }
5256
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005257 private TaskRecord taskForIdLocked(int id) {
5258 final int N = mRecentTasks.size();
5259 for (int i=0; i<N; i++) {
5260 TaskRecord tr = mRecentTasks.get(i);
5261 if (tr.taskId == id) {
5262 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005263 }
5264 }
5265 return null;
5266 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005267
5268 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5269 synchronized (this) {
5270 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5271 "getTaskThumbnails()");
5272 TaskRecord tr = taskForIdLocked(id);
5273 if (tr != null) {
5274 return mMainStack.getTaskThumbnailsLocked(tr);
5275 }
5276 }
5277 return null;
5278 }
5279
5280 public boolean removeSubTask(int taskId, int subTaskIndex) {
5281 synchronized (this) {
5282 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5283 "removeSubTask()");
5284 long ident = Binder.clearCallingIdentity();
5285 try {
5286 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5287 } finally {
5288 Binder.restoreCallingIdentity(ident);
5289 }
5290 }
5291 }
5292
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005293 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005294 TaskRecord tr = root.task;
5295 Intent baseIntent = new Intent(
5296 tr.intent != null ? tr.intent : tr.affinityIntent);
5297 ComponentName component = baseIntent.getComponent();
5298 if (component == null) {
5299 Slog.w(TAG, "Now component for base intent of task: " + tr);
5300 return;
5301 }
5302
5303 // Find any running services associated with this app.
5304 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5305 for (ServiceRecord sr : mServices.values()) {
5306 if (sr.packageName.equals(component.getPackageName())) {
5307 services.add(sr);
5308 }
5309 }
5310
5311 // Take care of any running services associated with the app.
5312 for (int i=0; i<services.size(); i++) {
5313 ServiceRecord sr = services.get(i);
5314 if (sr.startRequested) {
5315 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005316 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005317 stopServiceLocked(sr);
5318 } else {
5319 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5320 sr.makeNextStartId(), baseIntent, -1));
5321 if (sr.app != null && sr.app.thread != null) {
5322 sendServiceArgsLocked(sr, false);
5323 }
5324 }
5325 }
5326 }
5327
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005328 if (killProcesses) {
5329 // Find any running processes associated with this app.
5330 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5331 SparseArray<ProcessRecord> appProcs
5332 = mProcessNames.getMap().get(component.getPackageName());
5333 if (appProcs != null) {
5334 for (int i=0; i<appProcs.size(); i++) {
5335 procs.add(appProcs.valueAt(i));
5336 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005337 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005338
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005339 // Kill the running processes.
5340 for (int i=0; i<procs.size(); i++) {
5341 ProcessRecord pr = procs.get(i);
5342 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5343 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5344 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5345 pr.processName, pr.setAdj, "remove task");
5346 Process.killProcessQuiet(pr.pid);
5347 } else {
5348 pr.waitingToKill = "remove task";
5349 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005350 }
5351 }
5352 }
5353
5354 public boolean removeTask(int taskId, int flags) {
5355 synchronized (this) {
5356 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5357 "removeTask()");
5358 long ident = Binder.clearCallingIdentity();
5359 try {
5360 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5361 if (r != null) {
5362 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005363 cleanUpRemovedTaskLocked(r,
5364 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005365 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005366 } else {
5367 TaskRecord tr = null;
5368 int i=0;
5369 while (i < mRecentTasks.size()) {
5370 TaskRecord t = mRecentTasks.get(i);
5371 if (t.taskId == taskId) {
5372 tr = t;
5373 break;
5374 }
5375 i++;
5376 }
5377 if (tr != null) {
5378 if (tr.numActivities <= 0) {
5379 // Caller is just removing a recent task that is
5380 // not actively running. That is easy!
5381 mRecentTasks.remove(i);
5382 } else {
5383 Slog.w(TAG, "removeTask: task " + taskId
5384 + " does not have activities to remove, "
5385 + " but numActivities=" + tr.numActivities
5386 + ": " + tr);
5387 }
5388 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005389 }
5390 } finally {
5391 Binder.restoreCallingIdentity(ident);
5392 }
5393 }
5394 return false;
5395 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005397 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5398 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005399 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 TaskRecord jt = startTask;
5401
5402 // First look backwards
5403 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005404 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 if (r.task != jt) {
5406 jt = r.task;
5407 if (affinity.equals(jt.affinity)) {
5408 return j;
5409 }
5410 }
5411 }
5412
5413 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005414 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 jt = startTask;
5416 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005417 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005418 if (r.task != jt) {
5419 if (affinity.equals(jt.affinity)) {
5420 return j;
5421 }
5422 jt = r.task;
5423 }
5424 }
5425
5426 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005427 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 return N-1;
5429 }
5430
5431 return -1;
5432 }
5433
5434 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005435 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005437 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005438 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5439 "moveTaskToFront()");
5440
5441 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005442 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5443 Binder.getCallingUid(), "Task to front")) {
5444 return;
5445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 final long origId = Binder.clearCallingIdentity();
5447 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005448 TaskRecord tr = taskForIdLocked(task);
5449 if (tr != null) {
5450 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5451 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005452 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005453 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5454 // Caller wants the home activity moved with it. To accomplish this,
5455 // we'll just move the home task to the top first.
5456 mMainStack.moveHomeToFrontLocked();
5457 }
5458 mMainStack.moveTaskToFrontLocked(tr, null);
5459 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005460 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005461 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5462 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005464 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5465 mMainStack.mUserLeaving = true;
5466 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005467 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5468 // Caller wants the home activity moved with it. To accomplish this,
5469 // we'll just move the home task to the top first.
5470 mMainStack.moveHomeToFrontLocked();
5471 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005472 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 return;
5474 }
5475 }
5476 } finally {
5477 Binder.restoreCallingIdentity(origId);
5478 }
5479 }
5480 }
5481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005482 public void moveTaskToBack(int task) {
5483 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5484 "moveTaskToBack()");
5485
5486 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005487 if (mMainStack.mResumedActivity != null
5488 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005489 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5490 Binder.getCallingUid(), "Task to back")) {
5491 return;
5492 }
5493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005494 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005495 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496 Binder.restoreCallingIdentity(origId);
5497 }
5498 }
5499
5500 /**
5501 * Moves an activity, and all of the other activities within the same task, to the bottom
5502 * of the history stack. The activity's order within the task is unchanged.
5503 *
5504 * @param token A reference to the activity we wish to move
5505 * @param nonRoot If false then this only works if the activity is the root
5506 * of a task; if true it will work for any activity in a task.
5507 * @return Returns true if the move completed, false if not.
5508 */
5509 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5510 synchronized(this) {
5511 final long origId = Binder.clearCallingIdentity();
5512 int taskId = getTaskForActivityLocked(token, !nonRoot);
5513 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005514 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005515 }
5516 Binder.restoreCallingIdentity(origId);
5517 }
5518 return false;
5519 }
5520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005521 public void moveTaskBackwards(int task) {
5522 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5523 "moveTaskBackwards()");
5524
5525 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005526 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5527 Binder.getCallingUid(), "Task backwards")) {
5528 return;
5529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005530 final long origId = Binder.clearCallingIdentity();
5531 moveTaskBackwardsLocked(task);
5532 Binder.restoreCallingIdentity(origId);
5533 }
5534 }
5535
5536 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005537 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
5539
5540 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5541 synchronized(this) {
5542 return getTaskForActivityLocked(token, onlyRoot);
5543 }
5544 }
5545
5546 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005547 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005548 TaskRecord lastTask = null;
5549 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005550 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005551 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 if (!onlyRoot || lastTask != r.task) {
5553 return r.task.taskId;
5554 }
5555 return -1;
5556 }
5557 lastTask = r.task;
5558 }
5559
5560 return -1;
5561 }
5562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 public void finishOtherInstances(IBinder token, ComponentName className) {
5564 synchronized(this) {
5565 final long origId = Binder.clearCallingIdentity();
5566
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005567 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 TaskRecord lastTask = null;
5569 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005570 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005572 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005573 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 null, "others")) {
5575 i--;
5576 N--;
5577 }
5578 }
5579 lastTask = r.task;
5580 }
5581
5582 Binder.restoreCallingIdentity(origId);
5583 }
5584 }
5585
5586 // =========================================================
5587 // THUMBNAILS
5588 // =========================================================
5589
5590 public void reportThumbnail(IBinder token,
5591 Bitmap thumbnail, CharSequence description) {
5592 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5593 final long origId = Binder.clearCallingIdentity();
5594 sendPendingThumbnail(null, token, thumbnail, description, true);
5595 Binder.restoreCallingIdentity(origId);
5596 }
5597
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005598 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005599 Bitmap thumbnail, CharSequence description, boolean always) {
5600 TaskRecord task = null;
5601 ArrayList receivers = null;
5602
5603 //System.out.println("Send pending thumbnail: " + r);
5604
5605 synchronized(this) {
5606 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005607 r = mMainStack.isInStackLocked(token);
5608 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005609 return;
5610 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005611 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005612 if (thumbnail == null && r.thumbHolder != null) {
5613 thumbnail = r.thumbHolder.lastThumbnail;
5614 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005615 }
5616 if (thumbnail == null && !always) {
5617 // If there is no thumbnail, and this entry is not actually
5618 // going away, then abort for now and pick up the next
5619 // thumbnail we get.
5620 return;
5621 }
5622 task = r.task;
5623
5624 int N = mPendingThumbnails.size();
5625 int i=0;
5626 while (i<N) {
5627 PendingThumbnailsRecord pr =
5628 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5629 //System.out.println("Looking in " + pr.pendingRecords);
5630 if (pr.pendingRecords.remove(r)) {
5631 if (receivers == null) {
5632 receivers = new ArrayList();
5633 }
5634 receivers.add(pr);
5635 if (pr.pendingRecords.size() == 0) {
5636 pr.finished = true;
5637 mPendingThumbnails.remove(i);
5638 N--;
5639 continue;
5640 }
5641 }
5642 i++;
5643 }
5644 }
5645
5646 if (receivers != null) {
5647 final int N = receivers.size();
5648 for (int i=0; i<N; i++) {
5649 try {
5650 PendingThumbnailsRecord pr =
5651 (PendingThumbnailsRecord)receivers.get(i);
5652 pr.receiver.newThumbnail(
5653 task != null ? task.taskId : -1, thumbnail, description);
5654 if (pr.finished) {
5655 pr.receiver.finished();
5656 }
5657 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005658 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005659 }
5660 }
5661 }
5662 }
5663
5664 // =========================================================
5665 // CONTENT PROVIDERS
5666 // =========================================================
5667
Jeff Brown10e89712011-07-08 18:52:57 -07005668 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5669 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005671 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005673 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 } catch (RemoteException ex) {
5675 }
5676 if (providers != null) {
5677 final int N = providers.size();
5678 for (int i=0; i<N; i++) {
5679 ProviderInfo cpi =
5680 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005681 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5682 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005683 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005684 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005685 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005686 }
5687 app.pubProviders.put(cpi.name, cpr);
5688 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005689 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005690 }
5691 }
5692 return providers;
5693 }
5694
5695 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005696 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5698 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5699 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005700 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005701 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 return null;
5703 }
5704 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005705 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 == PackageManager.PERMISSION_GRANTED) {
5707 return null;
5708 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005709
5710 PathPermission[] pps = cpi.pathPermissions;
5711 if (pps != null) {
5712 int i = pps.length;
5713 while (i > 0) {
5714 i--;
5715 PathPermission pp = pps[i];
5716 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005717 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005718 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005719 return null;
5720 }
5721 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005722 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005723 == PackageManager.PERMISSION_GRANTED) {
5724 return null;
5725 }
5726 }
5727 }
5728
Dianne Hackbornb424b632010-08-18 15:59:05 -07005729 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5730 if (perms != null) {
5731 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5732 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5733 return null;
5734 }
5735 }
5736 }
5737
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005738 String msg;
5739 if (!cpi.exported) {
5740 msg = "Permission Denial: opening provider " + cpi.name
5741 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5742 + ", uid=" + callingUid + ") that is not exported from uid "
5743 + cpi.applicationInfo.uid;
5744 } else {
5745 msg = "Permission Denial: opening provider " + cpi.name
5746 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5747 + ", uid=" + callingUid + ") requires "
5748 + cpi.readPermission + " or " + cpi.writePermission;
5749 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005750 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 return msg;
5752 }
5753
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005754 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5755 if (r != null) {
5756 Integer cnt = r.conProviders.get(cpr);
5757 if (DEBUG_PROVIDER) Slog.v(TAG,
5758 "Adding provider requested by "
5759 + r.processName + " from process "
5760 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5761 + " cnt=" + (cnt == null ? 1 : cnt));
5762 if (cnt == null) {
5763 cpr.clients.add(r);
5764 r.conProviders.put(cpr, new Integer(1));
5765 return true;
5766 } else {
5767 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5768 }
5769 } else {
5770 cpr.externals++;
5771 }
5772 return false;
5773 }
5774
5775 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5776 if (r != null) {
5777 Integer cnt = r.conProviders.get(cpr);
5778 if (DEBUG_PROVIDER) Slog.v(TAG,
5779 "Removing provider requested by "
5780 + r.processName + " from process "
5781 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5782 + " cnt=" + cnt);
5783 if (cnt == null || cnt.intValue() <= 1) {
5784 cpr.clients.remove(r);
5785 r.conProviders.remove(cpr);
5786 return true;
5787 } else {
5788 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5789 }
5790 } else {
5791 cpr.externals++;
5792 }
5793 return false;
5794 }
5795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005796 private final ContentProviderHolder getContentProviderImpl(
5797 IApplicationThread caller, String name) {
5798 ContentProviderRecord cpr;
5799 ProviderInfo cpi = null;
5800
5801 synchronized(this) {
5802 ProcessRecord r = null;
5803 if (caller != null) {
5804 r = getRecordForAppLocked(caller);
5805 if (r == null) {
5806 throw new SecurityException(
5807 "Unable to find app for caller " + caller
5808 + " (pid=" + Binder.getCallingPid()
5809 + ") when getting content provider " + name);
5810 }
5811 }
5812
5813 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005814 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005815 boolean providerRunning = cpr != null;
5816 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005817 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005818 String msg;
5819 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5820 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 }
5822
5823 if (r != null && cpr.canRunHere(r)) {
5824 // This provider has been published or is in the process
5825 // of being published... but it is also allowed to run
5826 // in the caller's process, so don't make a connection
5827 // and just let the caller instantiate its own instance.
5828 if (cpr.provider != null) {
5829 // don't give caller the provider object, it needs
5830 // to make its own.
5831 cpr = new ContentProviderRecord(cpr);
5832 }
5833 return cpr;
5834 }
5835
5836 final long origId = Binder.clearCallingIdentity();
5837
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005838 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005840 final boolean countChanged = incProviderCount(r, cpr);
5841 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005842 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005843 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005844 // make sure to count it as being accessed and thus
5845 // back up on the LRU list. This is good because
5846 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005847 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005848 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005849 }
5850
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005851 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005852 if (false) {
5853 if (cpr.name.flattenToShortString().equals(
5854 "com.android.providers.calendar/.CalendarProvider2")) {
5855 Slog.v(TAG, "****************** KILLING "
5856 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005857 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005858 }
5859 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005860 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005861 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5862 // NOTE: there is still a race here where a signal could be
5863 // pending on the process even though we managed to update its
5864 // adj level. Not sure what to do about this, but at least
5865 // the race is now smaller.
5866 if (!success) {
5867 // Uh oh... it looks like the provider's process
5868 // has been killed on us. We need to wait for a new
5869 // process to be started, and make sure its death
5870 // doesn't kill our process.
5871 Slog.i(TAG,
5872 "Existing provider " + cpr.name.flattenToShortString()
5873 + " is crashing; detaching " + r);
5874 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005875 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005876 if (!lastRef) {
5877 // This wasn't the last ref our process had on
5878 // the provider... we have now been killed, bail.
5879 return null;
5880 }
5881 providerRunning = false;
5882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005883 }
5884
5885 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005887
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005888 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005889 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005890 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005891 resolveContentProvider(name,
5892 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005893 } catch (RemoteException ex) {
5894 }
5895 if (cpi == null) {
5896 return null;
5897 }
5898
Dianne Hackbornb424b632010-08-18 15:59:05 -07005899 String msg;
5900 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5901 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 }
5903
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005904 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005905 && !cpi.processName.equals("system")) {
5906 // If this content provider does not run in the system
5907 // process, and the system is not yet ready to run other
5908 // processes, then fail fast instead of hanging.
5909 throw new IllegalArgumentException(
5910 "Attempt to launch content provider before system ready");
5911 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005912
5913 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5914 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 final boolean firstClass = cpr == null;
5916 if (firstClass) {
5917 try {
5918 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005919 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 getApplicationInfo(
5921 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005922 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005923 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005924 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005925 + cpi.name);
5926 return null;
5927 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005928 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 } catch (RemoteException ex) {
5930 // pm is in same process, this will never happen.
5931 }
5932 }
5933
5934 if (r != null && cpr.canRunHere(r)) {
5935 // If this is a multiprocess provider, then just return its
5936 // info and allow the caller to instantiate it. Only do
5937 // this if the provider is the same user as the caller's
5938 // process, or can run as root (so can be in any process).
5939 return cpr;
5940 }
5941
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005942 if (DEBUG_PROVIDER) {
5943 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005944 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005945 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 }
5947
5948 // This is single process, and our app is now connecting to it.
5949 // See if we are already in the process of launching this
5950 // provider.
5951 final int N = mLaunchingProviders.size();
5952 int i;
5953 for (i=0; i<N; i++) {
5954 if (mLaunchingProviders.get(i) == cpr) {
5955 break;
5956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005957 }
5958
5959 // If the provider is not already being launched, then get it
5960 // started.
5961 if (i >= N) {
5962 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005963
5964 try {
5965 // Content provider is now in use, its package can't be stopped.
5966 try {
5967 AppGlobals.getPackageManager().setPackageStoppedState(
5968 cpr.appInfo.packageName, false);
5969 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005970 } catch (IllegalArgumentException e) {
5971 Slog.w(TAG, "Failed trying to unstop package "
5972 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005973 }
5974
5975 ProcessRecord proc = startProcessLocked(cpi.processName,
5976 cpr.appInfo, false, 0, "content provider",
5977 new ComponentName(cpi.applicationInfo.packageName,
5978 cpi.name), false);
5979 if (proc == null) {
5980 Slog.w(TAG, "Unable to launch app "
5981 + cpi.applicationInfo.packageName + "/"
5982 + cpi.applicationInfo.uid + " for provider "
5983 + name + ": process is bad");
5984 return null;
5985 }
5986 cpr.launchingApp = proc;
5987 mLaunchingProviders.add(cpr);
5988 } finally {
5989 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005991 }
5992
5993 // Make sure the provider is published (the same provider class
5994 // may be published under multiple names).
5995 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005996 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005997 }
5998 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005999 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 }
6001 }
6002
6003 // Wait for the provider to be published...
6004 synchronized (cpr) {
6005 while (cpr.provider == null) {
6006 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006007 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006008 + cpi.applicationInfo.packageName + "/"
6009 + cpi.applicationInfo.uid + " for provider "
6010 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006011 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 cpi.applicationInfo.packageName,
6013 cpi.applicationInfo.uid, name);
6014 return null;
6015 }
6016 try {
6017 cpr.wait();
6018 } catch (InterruptedException ex) {
6019 }
6020 }
6021 }
6022 return cpr;
6023 }
6024
6025 public final ContentProviderHolder getContentProvider(
6026 IApplicationThread caller, String name) {
6027 if (caller == null) {
6028 String msg = "null IApplicationThread when getting content provider "
6029 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006030 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006031 throw new SecurityException(msg);
6032 }
6033
6034 return getContentProviderImpl(caller, name);
6035 }
6036
6037 private ContentProviderHolder getContentProviderExternal(String name) {
6038 return getContentProviderImpl(null, name);
6039 }
6040
6041 /**
6042 * Drop a content provider from a ProcessRecord's bookkeeping
6043 * @param cpr
6044 */
6045 public void removeContentProvider(IApplicationThread caller, String name) {
6046 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006047 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006049 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006050 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006051 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 return;
6053 }
6054 final ProcessRecord r = getRecordForAppLocked(caller);
6055 if (r == null) {
6056 throw new SecurityException(
6057 "Unable to find app for caller " + caller +
6058 " when removing content provider " + name);
6059 }
6060 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006061 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6062 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006063 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006065 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006066 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006067 return;
6068 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006069 if (decProviderCount(r, localCpr)) {
6070 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006072 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006073 }
6074 }
6075
6076 private void removeContentProviderExternal(String name) {
6077 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006078 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006079 if(cpr == null) {
6080 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006081 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 return;
6083 }
6084
6085 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006086 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6087 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 localCpr.externals--;
6089 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006090 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 }
6092 updateOomAdjLocked();
6093 }
6094 }
6095
6096 public final void publishContentProviders(IApplicationThread caller,
6097 List<ContentProviderHolder> providers) {
6098 if (providers == null) {
6099 return;
6100 }
6101
6102 synchronized(this) {
6103 final ProcessRecord r = getRecordForAppLocked(caller);
6104 if (r == null) {
6105 throw new SecurityException(
6106 "Unable to find app for caller " + caller
6107 + " (pid=" + Binder.getCallingPid()
6108 + ") when publishing content providers");
6109 }
6110
6111 final long origId = Binder.clearCallingIdentity();
6112
6113 final int N = providers.size();
6114 for (int i=0; i<N; i++) {
6115 ContentProviderHolder src = providers.get(i);
6116 if (src == null || src.info == null || src.provider == null) {
6117 continue;
6118 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006119 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006121 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6122 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006123 String names[] = dst.info.authority.split(";");
6124 for (int j = 0; j < names.length; j++) {
6125 mProvidersByName.put(names[j], dst);
6126 }
6127
6128 int NL = mLaunchingProviders.size();
6129 int j;
6130 for (j=0; j<NL; j++) {
6131 if (mLaunchingProviders.get(j) == dst) {
6132 mLaunchingProviders.remove(j);
6133 j--;
6134 NL--;
6135 }
6136 }
6137 synchronized (dst) {
6138 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006139 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 dst.notifyAll();
6141 }
6142 updateOomAdjLocked(r);
6143 }
6144 }
6145
6146 Binder.restoreCallingIdentity(origId);
6147 }
6148 }
6149
6150 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006151 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006152 synchronized (mSelf) {
6153 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6154 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006155 if (providers != null) {
6156 for (int i=providers.size()-1; i>=0; i--) {
6157 ProviderInfo pi = (ProviderInfo)providers.get(i);
6158 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6159 Slog.w(TAG, "Not installing system proc provider " + pi.name
6160 + ": not system .apk");
6161 providers.remove(i);
6162 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006163 }
6164 }
6165 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006166 if (providers != null) {
6167 mSystemThread.installSystemProviders(providers);
6168 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006169
6170 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006171
6172 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 }
6174
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006175 /**
6176 * Allows app to retrieve the MIME type of a URI without having permission
6177 * to access its content provider.
6178 *
6179 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6180 *
6181 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6182 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6183 */
6184 public String getProviderMimeType(Uri uri) {
6185 final String name = uri.getAuthority();
6186 final long ident = Binder.clearCallingIdentity();
6187 ContentProviderHolder holder = null;
6188
6189 try {
6190 holder = getContentProviderExternal(name);
6191 if (holder != null) {
6192 return holder.provider.getType(uri);
6193 }
6194 } catch (RemoteException e) {
6195 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6196 return null;
6197 } finally {
6198 if (holder != null) {
6199 removeContentProviderExternal(name);
6200 }
6201 Binder.restoreCallingIdentity(ident);
6202 }
6203
6204 return null;
6205 }
6206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006207 // =========================================================
6208 // GLOBAL MANAGEMENT
6209 // =========================================================
6210
6211 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6212 ApplicationInfo info, String customProcess) {
6213 String proc = customProcess != null ? customProcess : info.processName;
6214 BatteryStatsImpl.Uid.Proc ps = null;
6215 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6216 synchronized (stats) {
6217 ps = stats.getProcessStatsLocked(info.uid, proc);
6218 }
6219 return new ProcessRecord(ps, thread, info, proc);
6220 }
6221
6222 final ProcessRecord addAppLocked(ApplicationInfo info) {
6223 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6224
6225 if (app == null) {
6226 app = newProcessRecordLocked(null, info, null);
6227 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006228 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006229 }
6230
Dianne Hackborne7f97212011-02-24 14:40:20 -08006231 // This package really, really can not be stopped.
6232 try {
6233 AppGlobals.getPackageManager().setPackageStoppedState(
6234 info.packageName, false);
6235 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006236 } catch (IllegalArgumentException e) {
6237 Slog.w(TAG, "Failed trying to unstop package "
6238 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006239 }
6240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6242 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6243 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006244 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006245 }
6246 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6247 mPersistentStartingProcesses.add(app);
6248 startProcessLocked(app, "added application", app.processName);
6249 }
6250
6251 return app;
6252 }
6253
6254 public void unhandledBack() {
6255 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6256 "unhandledBack()");
6257
6258 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006259 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006260 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006261 TAG, "Performing unhandledBack(): stack size = " + count);
6262 if (count > 1) {
6263 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006264 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006265 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6266 Binder.restoreCallingIdentity(origId);
6267 }
6268 }
6269 }
6270
6271 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6272 String name = uri.getAuthority();
6273 ContentProviderHolder cph = getContentProviderExternal(name);
6274 ParcelFileDescriptor pfd = null;
6275 if (cph != null) {
6276 // We record the binder invoker's uid in thread-local storage before
6277 // going to the content provider to open the file. Later, in the code
6278 // that handles all permissions checks, we look for this uid and use
6279 // that rather than the Activity Manager's own uid. The effect is that
6280 // we do the check against the caller's permissions even though it looks
6281 // to the content provider like the Activity Manager itself is making
6282 // the request.
6283 sCallerIdentity.set(new Identity(
6284 Binder.getCallingPid(), Binder.getCallingUid()));
6285 try {
6286 pfd = cph.provider.openFile(uri, "r");
6287 } catch (FileNotFoundException e) {
6288 // do nothing; pfd will be returned null
6289 } finally {
6290 // Ensure that whatever happens, we clean up the identity state
6291 sCallerIdentity.remove();
6292 }
6293
6294 // We've got the fd now, so we're done with the provider.
6295 removeContentProviderExternal(name);
6296 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006297 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298 }
6299 return pfd;
6300 }
6301
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006302 // Actually is sleeping or shutting down or whatever else in the future
6303 // is an inactive state.
6304 public boolean isSleeping() {
6305 return mSleeping || mShuttingDown;
6306 }
6307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 public void goingToSleep() {
6309 synchronized(this) {
6310 mSleeping = true;
6311 mWindowManager.setEventDispatching(false);
6312
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006313 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006314
6315 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006316 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006317 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6318 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006319 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320 }
6321 }
6322
Dianne Hackborn55280a92009-05-07 15:53:46 -07006323 public boolean shutdown(int timeout) {
6324 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6325 != PackageManager.PERMISSION_GRANTED) {
6326 throw new SecurityException("Requires permission "
6327 + android.Manifest.permission.SHUTDOWN);
6328 }
6329
6330 boolean timedout = false;
6331
6332 synchronized(this) {
6333 mShuttingDown = true;
6334 mWindowManager.setEventDispatching(false);
6335
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006336 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006337 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006338 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006339 while (mMainStack.mResumedActivity != null
6340 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006341 long delay = endTime - System.currentTimeMillis();
6342 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006343 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006344 timedout = true;
6345 break;
6346 }
6347 try {
6348 this.wait();
6349 } catch (InterruptedException e) {
6350 }
6351 }
6352 }
6353 }
6354
6355 mUsageStatsService.shutdown();
6356 mBatteryStatsService.shutdown();
6357
6358 return timedout;
6359 }
6360
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006361 public final void activitySlept(IBinder token) {
6362 if (localLOGV) Slog.v(
6363 TAG, "Activity slept: token=" + token);
6364
6365 ActivityRecord r = null;
6366
6367 final long origId = Binder.clearCallingIdentity();
6368
6369 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006370 r = mMainStack.isInStackLocked(token);
6371 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006372 mMainStack.activitySleptLocked(r);
6373 }
6374 }
6375
6376 Binder.restoreCallingIdentity(origId);
6377 }
6378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006379 public void wakingUp() {
6380 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 mWindowManager.setEventDispatching(true);
6382 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006383 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006384 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006385 }
6386 }
6387
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006388 public void stopAppSwitches() {
6389 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6390 != PackageManager.PERMISSION_GRANTED) {
6391 throw new SecurityException("Requires permission "
6392 + android.Manifest.permission.STOP_APP_SWITCHES);
6393 }
6394
6395 synchronized(this) {
6396 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6397 + APP_SWITCH_DELAY_TIME;
6398 mDidAppSwitch = false;
6399 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6400 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6401 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6402 }
6403 }
6404
6405 public void resumeAppSwitches() {
6406 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6407 != PackageManager.PERMISSION_GRANTED) {
6408 throw new SecurityException("Requires permission "
6409 + android.Manifest.permission.STOP_APP_SWITCHES);
6410 }
6411
6412 synchronized(this) {
6413 // Note that we don't execute any pending app switches... we will
6414 // let those wait until either the timeout, or the next start
6415 // activity request.
6416 mAppSwitchesAllowedTime = 0;
6417 }
6418 }
6419
6420 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6421 String name) {
6422 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6423 return true;
6424 }
6425
6426 final int perm = checkComponentPermission(
6427 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006428 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006429 if (perm == PackageManager.PERMISSION_GRANTED) {
6430 return true;
6431 }
6432
Joe Onorato8a9b2202010-02-26 18:56:32 -08006433 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006434 return false;
6435 }
6436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 public void setDebugApp(String packageName, boolean waitForDebugger,
6438 boolean persistent) {
6439 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6440 "setDebugApp()");
6441
6442 // Note that this is not really thread safe if there are multiple
6443 // callers into it at the same time, but that's not a situation we
6444 // care about.
6445 if (persistent) {
6446 final ContentResolver resolver = mContext.getContentResolver();
6447 Settings.System.putString(
6448 resolver, Settings.System.DEBUG_APP,
6449 packageName);
6450 Settings.System.putInt(
6451 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6452 waitForDebugger ? 1 : 0);
6453 }
6454
6455 synchronized (this) {
6456 if (!persistent) {
6457 mOrigDebugApp = mDebugApp;
6458 mOrigWaitForDebugger = mWaitForDebugger;
6459 }
6460 mDebugApp = packageName;
6461 mWaitForDebugger = waitForDebugger;
6462 mDebugTransient = !persistent;
6463 if (packageName != null) {
6464 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006465 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006466 Binder.restoreCallingIdentity(origId);
6467 }
6468 }
6469 }
6470
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006471 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6472 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6473 synchronized (this) {
6474 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6475 if (!isDebuggable) {
6476 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6477 throw new SecurityException("Process not debuggable: " + app.packageName);
6478 }
6479 }
6480 mProfileApp = processName;
6481 mProfileFile = profileFile;
6482 if (mProfileFd != null) {
6483 try {
6484 mProfileFd.close();
6485 } catch (IOException e) {
6486 }
6487 mProfileFd = null;
6488 }
6489 mProfileFd = profileFd;
6490 mProfileType = 0;
6491 mAutoStopProfiler = autoStopProfiler;
6492 }
6493 }
6494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006495 public void setAlwaysFinish(boolean enabled) {
6496 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6497 "setAlwaysFinish()");
6498
6499 Settings.System.putInt(
6500 mContext.getContentResolver(),
6501 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6502
6503 synchronized (this) {
6504 mAlwaysFinishActivities = enabled;
6505 }
6506 }
6507
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006508 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006510 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006511 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006512 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 }
6514 }
6515
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006516 public boolean isUserAMonkey() {
6517 // For now the fact that there is a controller implies
6518 // we have a monkey.
6519 synchronized (this) {
6520 return mController != null;
6521 }
6522 }
6523
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006524 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006525 synchronized (this) {
6526 mWatchers.register(watcher);
6527 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006528 }
6529
6530 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006531 synchronized (this) {
6532 mWatchers.unregister(watcher);
6533 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006534 }
6535
Jeff Sharkeya4620792011-05-20 15:29:23 -07006536 public void registerProcessObserver(IProcessObserver observer) {
6537 mProcessObservers.register(observer);
6538 }
6539
6540 public void unregisterProcessObserver(IProcessObserver observer) {
6541 mProcessObservers.unregister(observer);
6542 }
6543
Daniel Sandler69a48172010-06-23 16:29:36 -04006544 public void setImmersive(IBinder token, boolean immersive) {
6545 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006546 ActivityRecord r = mMainStack.isInStackLocked(token);
6547 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006548 throw new IllegalArgumentException();
6549 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006550 r.immersive = immersive;
6551 }
6552 }
6553
6554 public boolean isImmersive(IBinder token) {
6555 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006556 ActivityRecord r = mMainStack.isInStackLocked(token);
6557 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006558 throw new IllegalArgumentException();
6559 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006560 return r.immersive;
6561 }
6562 }
6563
6564 public boolean isTopActivityImmersive() {
6565 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006566 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006567 return (r != null) ? r.immersive : false;
6568 }
6569 }
6570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006571 public final void enterSafeMode() {
6572 synchronized(this) {
6573 // It only makes sense to do this before the system is ready
6574 // and started launching other packages.
6575 if (!mSystemReady) {
6576 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006577 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006578 } catch (RemoteException e) {
6579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 }
6581 }
6582 }
6583
Jeff Brownb09abc12011-01-13 21:08:27 -08006584 public final void showSafeModeOverlay() {
6585 View v = LayoutInflater.from(mContext).inflate(
6586 com.android.internal.R.layout.safe_mode, null);
6587 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6588 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6589 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6590 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6591 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6592 lp.format = v.getBackground().getOpacity();
6593 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6594 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6595 ((WindowManager)mContext.getSystemService(
6596 Context.WINDOW_SERVICE)).addView(v, lp);
6597 }
6598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006599 public void noteWakeupAlarm(IIntentSender sender) {
6600 if (!(sender instanceof PendingIntentRecord)) {
6601 return;
6602 }
6603 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6604 synchronized (stats) {
6605 if (mBatteryStatsService.isOnBattery()) {
6606 mBatteryStatsService.enforceCallingPermission();
6607 PendingIntentRecord rec = (PendingIntentRecord)sender;
6608 int MY_UID = Binder.getCallingUid();
6609 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6610 BatteryStatsImpl.Uid.Pkg pkg =
6611 stats.getPackageStatsLocked(uid, rec.key.packageName);
6612 pkg.incWakeupsLocked();
6613 }
6614 }
6615 }
6616
Dianne Hackborn64825172011-03-02 21:32:58 -08006617 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006618 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006619 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006621 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006622 // XXX Note: don't acquire main activity lock here, because the window
6623 // manager calls in with its locks held.
6624
6625 boolean killed = false;
6626 synchronized (mPidsSelfLocked) {
6627 int[] types = new int[pids.length];
6628 int worstType = 0;
6629 for (int i=0; i<pids.length; i++) {
6630 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6631 if (proc != null) {
6632 int type = proc.setAdj;
6633 types[i] = type;
6634 if (type > worstType) {
6635 worstType = type;
6636 }
6637 }
6638 }
6639
Dianne Hackborn64825172011-03-02 21:32:58 -08006640 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006642 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6643 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006644 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006646
6647 // If this is not a secure call, don't let it kill processes that
6648 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006649 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6650 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006651 }
6652
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006653 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 for (int i=0; i<pids.length; i++) {
6655 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6656 if (proc == null) {
6657 continue;
6658 }
6659 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006660 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006661 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006662 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6663 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006665 proc.killedBackground = true;
6666 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 }
6668 }
6669 }
6670 return killed;
6671 }
6672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 public final void startRunning(String pkg, String cls, String action,
6674 String data) {
6675 synchronized(this) {
6676 if (mStartRunning) {
6677 return;
6678 }
6679 mStartRunning = true;
6680 mTopComponent = pkg != null && cls != null
6681 ? new ComponentName(pkg, cls) : null;
6682 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6683 mTopData = data;
6684 if (!mSystemReady) {
6685 return;
6686 }
6687 }
6688
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006689 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 }
6691
6692 private void retrieveSettings() {
6693 final ContentResolver resolver = mContext.getContentResolver();
6694 String debugApp = Settings.System.getString(
6695 resolver, Settings.System.DEBUG_APP);
6696 boolean waitForDebugger = Settings.System.getInt(
6697 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6698 boolean alwaysFinishActivities = Settings.System.getInt(
6699 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6700
6701 Configuration configuration = new Configuration();
6702 Settings.System.getConfiguration(resolver, configuration);
6703
6704 synchronized (this) {
6705 mDebugApp = mOrigDebugApp = debugApp;
6706 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6707 mAlwaysFinishActivities = alwaysFinishActivities;
6708 // This happens before any activities are started, so we can
6709 // change mConfiguration in-place.
6710 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006711 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006712 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 }
6714 }
6715
6716 public boolean testIsSystemReady() {
6717 // no need to synchronize(this) just to read & return the value
6718 return mSystemReady;
6719 }
6720
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006721 private static File getCalledPreBootReceiversFile() {
6722 File dataDir = Environment.getDataDirectory();
6723 File systemDir = new File(dataDir, "system");
6724 File fname = new File(systemDir, "called_pre_boots.dat");
6725 return fname;
6726 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006727
6728 static final int LAST_DONE_VERSION = 10000;
6729
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006730 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6731 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6732 File file = getCalledPreBootReceiversFile();
6733 FileInputStream fis = null;
6734 try {
6735 fis = new FileInputStream(file);
6736 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006737 int fvers = dis.readInt();
6738 if (fvers == LAST_DONE_VERSION) {
6739 String vers = dis.readUTF();
6740 String codename = dis.readUTF();
6741 String build = dis.readUTF();
6742 if (android.os.Build.VERSION.RELEASE.equals(vers)
6743 && android.os.Build.VERSION.CODENAME.equals(codename)
6744 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6745 int num = dis.readInt();
6746 while (num > 0) {
6747 num--;
6748 String pkg = dis.readUTF();
6749 String cls = dis.readUTF();
6750 lastDoneReceivers.add(new ComponentName(pkg, cls));
6751 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006752 }
6753 }
6754 } catch (FileNotFoundException e) {
6755 } catch (IOException e) {
6756 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6757 } finally {
6758 if (fis != null) {
6759 try {
6760 fis.close();
6761 } catch (IOException e) {
6762 }
6763 }
6764 }
6765 return lastDoneReceivers;
6766 }
6767
6768 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6769 File file = getCalledPreBootReceiversFile();
6770 FileOutputStream fos = null;
6771 DataOutputStream dos = null;
6772 try {
6773 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6774 fos = new FileOutputStream(file);
6775 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006776 dos.writeInt(LAST_DONE_VERSION);
6777 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006778 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006779 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006780 dos.writeInt(list.size());
6781 for (int i=0; i<list.size(); i++) {
6782 dos.writeUTF(list.get(i).getPackageName());
6783 dos.writeUTF(list.get(i).getClassName());
6784 }
6785 } catch (IOException e) {
6786 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6787 file.delete();
6788 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006789 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006790 if (dos != null) {
6791 try {
6792 dos.close();
6793 } catch (IOException e) {
6794 // TODO Auto-generated catch block
6795 e.printStackTrace();
6796 }
6797 }
6798 }
6799 }
6800
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006801 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 synchronized(this) {
6803 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006804 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 return;
6806 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006807
6808 // Check to see if there are any update receivers to run.
6809 if (!mDidUpdate) {
6810 if (mWaitingUpdate) {
6811 return;
6812 }
6813 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6814 List<ResolveInfo> ris = null;
6815 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006816 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006817 intent, null, 0);
6818 } catch (RemoteException e) {
6819 }
6820 if (ris != null) {
6821 for (int i=ris.size()-1; i>=0; i--) {
6822 if ((ris.get(i).activityInfo.applicationInfo.flags
6823 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6824 ris.remove(i);
6825 }
6826 }
6827 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006828
6829 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6830
6831 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006832 for (int i=0; i<ris.size(); i++) {
6833 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006834 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6835 if (lastDoneReceivers.contains(comp)) {
6836 ris.remove(i);
6837 i--;
6838 }
6839 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006840
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006841 for (int i=0; i<ris.size(); i++) {
6842 ActivityInfo ai = ris.get(i).activityInfo;
6843 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6844 doneReceivers.add(comp);
6845 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006846 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006847 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006848 finisher = new IIntentReceiver.Stub() {
6849 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006850 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006851 boolean sticky) {
6852 // The raw IIntentReceiver interface is called
6853 // with the AM lock held, so redispatch to
6854 // execute our code without the lock.
6855 mHandler.post(new Runnable() {
6856 public void run() {
6857 synchronized (ActivityManagerService.this) {
6858 mDidUpdate = true;
6859 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006860 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006861 showBootMessage(mContext.getText(
6862 R.string.android_upgrading_complete),
6863 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006864 systemReady(goingCallback);
6865 }
6866 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006867 }
6868 };
6869 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006870 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006871 broadcastIntentLocked(null, null, intent, null, finisher,
6872 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006873 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006874 mWaitingUpdate = true;
6875 }
6876 }
6877 }
6878 if (mWaitingUpdate) {
6879 return;
6880 }
6881 mDidUpdate = true;
6882 }
6883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006884 mSystemReady = true;
6885 if (!mStartRunning) {
6886 return;
6887 }
6888 }
6889
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006890 ArrayList<ProcessRecord> procsToKill = null;
6891 synchronized(mPidsSelfLocked) {
6892 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6893 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6894 if (!isAllowedWhileBooting(proc.info)){
6895 if (procsToKill == null) {
6896 procsToKill = new ArrayList<ProcessRecord>();
6897 }
6898 procsToKill.add(proc);
6899 }
6900 }
6901 }
6902
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006903 synchronized(this) {
6904 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006905 for (int i=procsToKill.size()-1; i>=0; i--) {
6906 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006907 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006908 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006909 }
6910 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006911
6912 // Now that we have cleaned up any update processes, we
6913 // are ready to start launching real processes and know that
6914 // we won't trample on them any more.
6915 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006916 }
6917
Joe Onorato8a9b2202010-02-26 18:56:32 -08006918 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006919 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006920 SystemClock.uptimeMillis());
6921
6922 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006923 // Make sure we have no pre-ready processes sitting around.
6924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006925 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6926 ResolveInfo ri = mContext.getPackageManager()
6927 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006928 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 CharSequence errorMsg = null;
6930 if (ri != null) {
6931 ActivityInfo ai = ri.activityInfo;
6932 ApplicationInfo app = ai.applicationInfo;
6933 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6934 mTopAction = Intent.ACTION_FACTORY_TEST;
6935 mTopData = null;
6936 mTopComponent = new ComponentName(app.packageName,
6937 ai.name);
6938 } else {
6939 errorMsg = mContext.getResources().getText(
6940 com.android.internal.R.string.factorytest_not_system);
6941 }
6942 } else {
6943 errorMsg = mContext.getResources().getText(
6944 com.android.internal.R.string.factorytest_no_action);
6945 }
6946 if (errorMsg != null) {
6947 mTopAction = null;
6948 mTopData = null;
6949 mTopComponent = null;
6950 Message msg = Message.obtain();
6951 msg.what = SHOW_FACTORY_ERROR_MSG;
6952 msg.getData().putCharSequence("msg", errorMsg);
6953 mHandler.sendMessage(msg);
6954 }
6955 }
6956 }
6957
6958 retrieveSettings();
6959
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006960 if (goingCallback != null) goingCallback.run();
6961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 synchronized (this) {
6963 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6964 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006965 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006966 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006967 if (apps != null) {
6968 int N = apps.size();
6969 int i;
6970 for (i=0; i<N; i++) {
6971 ApplicationInfo info
6972 = (ApplicationInfo)apps.get(i);
6973 if (info != null &&
6974 !info.packageName.equals("android")) {
6975 addAppLocked(info);
6976 }
6977 }
6978 }
6979 } catch (RemoteException ex) {
6980 // pm is in same process, this will never happen.
6981 }
6982 }
6983
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006984 // Start up initial activity.
6985 mBooting = true;
6986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006987 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006988 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006989 Message msg = Message.obtain();
6990 msg.what = SHOW_UID_ERROR_MSG;
6991 mHandler.sendMessage(msg);
6992 }
6993 } catch (RemoteException e) {
6994 }
6995
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006996 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006997 }
6998 }
6999
Dan Egnorb7f03672009-12-09 16:22:32 -08007000 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007001 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007003 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007004 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005 startAppProblemLocked(app);
7006 app.stopFreezingAllLocked();
7007 return handleAppCrashLocked(app);
7008 }
7009
Dan Egnorb7f03672009-12-09 16:22:32 -08007010 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007011 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007012 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007013 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007014 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7015 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007016 startAppProblemLocked(app);
7017 app.stopFreezingAllLocked();
7018 }
7019
7020 /**
7021 * Generate a process error record, suitable for attachment to a ProcessRecord.
7022 *
7023 * @param app The ProcessRecord in which the error occurred.
7024 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7025 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007026 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 * @param shortMsg Short message describing the crash.
7028 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007029 * @param stackTrace Full crash stack trace, may be null.
7030 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 * @return Returns a fully-formed AppErrorStateInfo record.
7032 */
7033 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007034 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007035 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 report.condition = condition;
7038 report.processName = app.processName;
7039 report.pid = app.pid;
7040 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007041 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007042 report.shortMsg = shortMsg;
7043 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007044 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045
7046 return report;
7047 }
7048
Dan Egnor42471dd2010-01-07 17:25:22 -08007049 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 synchronized (this) {
7051 app.crashing = false;
7052 app.crashingReport = null;
7053 app.notResponding = false;
7054 app.notRespondingReport = null;
7055 if (app.anrDialog == fromDialog) {
7056 app.anrDialog = null;
7057 }
7058 if (app.waitDialog == fromDialog) {
7059 app.waitDialog = null;
7060 }
7061 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007062 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007063 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007064 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7065 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007066 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007068 }
7069 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007070
Dan Egnorb7f03672009-12-09 16:22:32 -08007071 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007072 long now = SystemClock.uptimeMillis();
7073
7074 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7075 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007076 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007077 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007078 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007080 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007082 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7083 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007084 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007085 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007086 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007087 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 }
7089 }
7090 if (!app.persistent) {
7091 // We don't want to start this process again until the user
7092 // explicitly does so... but for persistent process, we really
7093 // need to keep it running. If a persistent process is actually
7094 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007095 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007096 app.info.processName);
7097 mBadProcesses.put(app.info.processName, app.info.uid, now);
7098 app.bad = true;
7099 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7100 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007101 // Don't let services in this process be restarted and potentially
7102 // annoy the user repeatedly. Unless it is persistent, since those
7103 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007104 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007105 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007106 return false;
7107 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007108 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007109 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007110 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007111 if (r.app == app) {
7112 // If the top running activity is from this crashing
7113 // process, then terminate it to avoid getting in a loop.
7114 Slog.w(TAG, " Force finishing activity "
7115 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007116 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007117 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007118 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007119 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007120 // stopped, to avoid a situation where one will get
7121 // re-start our crashing activity once it gets resumed again.
7122 index--;
7123 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007124 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007125 if (r.state == ActivityState.RESUMED
7126 || r.state == ActivityState.PAUSING
7127 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007128 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007129 Slog.w(TAG, " Force finishing activity "
7130 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007131 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007132 Activity.RESULT_CANCELED, null, "crashed");
7133 }
7134 }
7135 }
7136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007137 }
7138
7139 // Bump up the crash count of any services currently running in the proc.
7140 if (app.services.size() != 0) {
7141 // Any services running in the application need to be placed
7142 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007143 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007144 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007145 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007146 sr.crashCount++;
7147 }
7148 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007149
7150 // If the crashing process is what we consider to be the "home process" and it has been
7151 // replaced by a third-party app, clear the package preferred activities from packages
7152 // with a home activity running in the process to prevent a repeatedly crashing app
7153 // from blocking the user to manually clear the list.
7154 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7155 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7156 Iterator it = mHomeProcess.activities.iterator();
7157 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007158 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007159 if (r.isHomeActivity) {
7160 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7161 try {
7162 ActivityThread.getPackageManager()
7163 .clearPackagePreferredActivities(r.packageName);
7164 } catch (RemoteException c) {
7165 // pm is in same process, this will never happen.
7166 }
7167 }
7168 }
7169 }
7170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7172 return true;
7173 }
7174
7175 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007176 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7177 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007178 skipCurrentReceiverLocked(app);
7179 }
7180
7181 void skipCurrentReceiverLocked(ProcessRecord app) {
7182 boolean reschedule = false;
7183 BroadcastRecord r = app.curReceiver;
7184 if (r != null) {
7185 // The current broadcast is waiting for this app's receiver
7186 // to be finished. Looks like that's not going to happen, so
7187 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007188 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7190 r.resultExtras, r.resultAbort, true);
7191 reschedule = true;
7192 }
7193 r = mPendingBroadcast;
7194 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007195 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007196 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007197 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7199 r.resultExtras, r.resultAbort, true);
7200 reschedule = true;
7201 }
7202 if (reschedule) {
7203 scheduleBroadcastsLocked();
7204 }
7205 }
7206
Dan Egnor60d87622009-12-16 16:32:58 -08007207 /**
7208 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7209 * The application process will exit immediately after this call returns.
7210 * @param app object of the crashing app, null for the system server
7211 * @param crashInfo describing the exception
7212 */
7213 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007214 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007215 final String processName = app == null ? "system_server"
7216 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007217
7218 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007219 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007220 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007221 crashInfo.exceptionClassName,
7222 crashInfo.exceptionMessage,
7223 crashInfo.throwFileName,
7224 crashInfo.throwLineNumber);
7225
Jeff Sharkeya353d262011-10-28 11:12:06 -07007226 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007227
7228 crashApplication(r, crashInfo);
7229 }
7230
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007231 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007232 IBinder app,
7233 int violationMask,
7234 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007235 ProcessRecord r = findAppProcess(app, "StrictMode");
7236 if (r == null) {
7237 return;
7238 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007239
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007240 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007241 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007242 boolean logIt = true;
7243 synchronized (mAlreadyLoggedViolatedStacks) {
7244 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7245 logIt = false;
7246 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007247 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007248 // the relative pain numbers, without logging all
7249 // the stack traces repeatedly. We'd want to do
7250 // likewise in the client code, which also does
7251 // dup suppression, before the Binder call.
7252 } else {
7253 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7254 mAlreadyLoggedViolatedStacks.clear();
7255 }
7256 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7257 }
7258 }
7259 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007260 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007261 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007262 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007263
7264 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7265 AppErrorResult result = new AppErrorResult();
7266 synchronized (this) {
7267 final long origId = Binder.clearCallingIdentity();
7268
7269 Message msg = Message.obtain();
7270 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7271 HashMap<String, Object> data = new HashMap<String, Object>();
7272 data.put("result", result);
7273 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007274 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007275 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007276 msg.obj = data;
7277 mHandler.sendMessage(msg);
7278
7279 Binder.restoreCallingIdentity(origId);
7280 }
7281 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007282 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007283 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007284 }
7285
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007286 // Depending on the policy in effect, there could be a bunch of
7287 // these in quick succession so we try to batch these together to
7288 // minimize disk writes, number of dropbox entries, and maximize
7289 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007290 private void logStrictModeViolationToDropBox(
7291 ProcessRecord process,
7292 StrictMode.ViolationInfo info) {
7293 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007294 return;
7295 }
7296 final boolean isSystemApp = process == null ||
7297 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7298 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007299 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007300 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7301 final DropBoxManager dbox = (DropBoxManager)
7302 mContext.getSystemService(Context.DROPBOX_SERVICE);
7303
7304 // Exit early if the dropbox isn't configured to accept this report type.
7305 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7306
7307 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007308 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007309 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7310 synchronized (sb) {
7311 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007312 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007313 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7314 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007315 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7316 if (info.violationNumThisLoop != 0) {
7317 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7318 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007319 if (info.numAnimationsRunning != 0) {
7320 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7321 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007322 if (info.broadcastIntentAction != null) {
7323 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7324 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007325 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007326 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007327 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007328 if (info.numInstances != -1) {
7329 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7330 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007331 if (info.tags != null) {
7332 for (String tag : info.tags) {
7333 sb.append("Span-Tag: ").append(tag).append("\n");
7334 }
7335 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007336 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007337 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7338 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007339 }
7340 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007341
7342 // Only buffer up to ~64k. Various logging bits truncate
7343 // things at 128k.
7344 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007345 }
7346
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007347 // Flush immediately if the buffer's grown too large, or this
7348 // is a non-system app. Non-system apps are isolated with a
7349 // different tag & policy and not batched.
7350 //
7351 // Batching is useful during internal testing with
7352 // StrictMode settings turned up high. Without batching,
7353 // thousands of separate files could be created on boot.
7354 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007355 new Thread("Error dump: " + dropboxTag) {
7356 @Override
7357 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007358 String report;
7359 synchronized (sb) {
7360 report = sb.toString();
7361 sb.delete(0, sb.length());
7362 sb.trimToSize();
7363 }
7364 if (report.length() != 0) {
7365 dbox.addText(dropboxTag, report);
7366 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007367 }
7368 }.start();
7369 return;
7370 }
7371
7372 // System app batching:
7373 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007374 // An existing dropbox-writing thread is outstanding, so
7375 // we don't need to start it up. The existing thread will
7376 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007377 return;
7378 }
7379
7380 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7381 // (After this point, we shouldn't access AMS internal data structures.)
7382 new Thread("Error dump: " + dropboxTag) {
7383 @Override
7384 public void run() {
7385 // 5 second sleep to let stacks arrive and be batched together
7386 try {
7387 Thread.sleep(5000); // 5 seconds
7388 } catch (InterruptedException e) {}
7389
7390 String errorReport;
7391 synchronized (mStrictModeBuffer) {
7392 errorReport = mStrictModeBuffer.toString();
7393 if (errorReport.length() == 0) {
7394 return;
7395 }
7396 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7397 mStrictModeBuffer.trimToSize();
7398 }
7399 dbox.addText(dropboxTag, errorReport);
7400 }
7401 }.start();
7402 }
7403
Dan Egnor60d87622009-12-16 16:32:58 -08007404 /**
7405 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7406 * @param app object of the crashing app, null for the system server
7407 * @param tag reported by the caller
7408 * @param crashInfo describing the context of the error
7409 * @return true if the process should exit immediately (WTF is fatal)
7410 */
7411 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007412 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007413 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007414 final String processName = app == null ? "system_server"
7415 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007416
7417 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007418 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007419 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007420 tag, crashInfo.exceptionMessage);
7421
Jeff Sharkeya353d262011-10-28 11:12:06 -07007422 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007423
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007424 if (r != null && r.pid != Process.myPid() &&
7425 Settings.Secure.getInt(mContext.getContentResolver(),
7426 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007427 crashApplication(r, crashInfo);
7428 return true;
7429 } else {
7430 return false;
7431 }
7432 }
7433
7434 /**
7435 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7436 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7437 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007438 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007439 if (app == null) {
7440 return null;
7441 }
7442
7443 synchronized (this) {
7444 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7445 final int NA = apps.size();
7446 for (int ia=0; ia<NA; ia++) {
7447 ProcessRecord p = apps.valueAt(ia);
7448 if (p.thread != null && p.thread.asBinder() == app) {
7449 return p;
7450 }
7451 }
7452 }
7453
Dianne Hackborncb44d962011-03-10 17:02:27 -08007454 Slog.w(TAG, "Can't find mystery application for " + reason
7455 + " from pid=" + Binder.getCallingPid()
7456 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007457 return null;
7458 }
7459 }
7460
7461 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007462 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7463 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007464 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007465 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7466 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007467 // Watchdog thread ends up invoking this function (with
7468 // a null ProcessRecord) to add the stack file to dropbox.
7469 // Do not acquire a lock on this (am) in such cases, as it
7470 // could cause a potential deadlock, if and when watchdog
7471 // is invoked due to unavailability of lock on am and it
7472 // would prevent watchdog from killing system_server.
7473 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007474 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007475 return;
7476 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007477 // Note: ProcessRecord 'process' is guarded by the service
7478 // instance. (notably process.pkgList, which could otherwise change
7479 // concurrently during execution of this method)
7480 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007481 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007482 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007483 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007484 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7485 for (String pkg : process.pkgList) {
7486 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007487 try {
Dan Egnora455d192010-03-12 08:52:28 -08007488 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7489 if (pi != null) {
7490 sb.append(" v").append(pi.versionCode);
7491 if (pi.versionName != null) {
7492 sb.append(" (").append(pi.versionName).append(")");
7493 }
7494 }
7495 } catch (RemoteException e) {
7496 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007497 }
Dan Egnora455d192010-03-12 08:52:28 -08007498 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007499 }
Dan Egnora455d192010-03-12 08:52:28 -08007500 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007501 }
7502
7503 private static String processClass(ProcessRecord process) {
7504 if (process == null || process.pid == MY_PID) {
7505 return "system_server";
7506 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7507 return "system_app";
7508 } else {
7509 return "data_app";
7510 }
7511 }
7512
7513 /**
7514 * Write a description of an error (crash, WTF, ANR) to the drop box.
7515 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7516 * @param process which caused the error, null means the system server
7517 * @param activity which triggered the error, null if unknown
7518 * @param parent activity related to the error, null if unknown
7519 * @param subject line related to the error, null if absent
7520 * @param report in long form describing the error, null if absent
7521 * @param logFile to include in the report, null if none
7522 * @param crashInfo giving an application stack trace, null if absent
7523 */
7524 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007525 ProcessRecord process, String processName, ActivityRecord activity,
7526 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007527 final String report, final File logFile,
7528 final ApplicationErrorReport.CrashInfo crashInfo) {
7529 // NOTE -- this must never acquire the ActivityManagerService lock,
7530 // otherwise the watchdog may be prevented from resetting the system.
7531
7532 final String dropboxTag = processClass(process) + "_" + eventType;
7533 final DropBoxManager dbox = (DropBoxManager)
7534 mContext.getSystemService(Context.DROPBOX_SERVICE);
7535
7536 // Exit early if the dropbox isn't configured to accept this report type.
7537 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7538
7539 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007540 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007541 if (activity != null) {
7542 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7543 }
7544 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7545 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7546 }
7547 if (parent != null && parent != activity) {
7548 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7549 }
7550 if (subject != null) {
7551 sb.append("Subject: ").append(subject).append("\n");
7552 }
7553 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007554 if (Debug.isDebuggerConnected()) {
7555 sb.append("Debugger: Connected\n");
7556 }
Dan Egnora455d192010-03-12 08:52:28 -08007557 sb.append("\n");
7558
7559 // Do the rest in a worker thread to avoid blocking the caller on I/O
7560 // (After this point, we shouldn't access AMS internal data structures.)
7561 Thread worker = new Thread("Error dump: " + dropboxTag) {
7562 @Override
7563 public void run() {
7564 if (report != null) {
7565 sb.append(report);
7566 }
7567 if (logFile != null) {
7568 try {
7569 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7570 } catch (IOException e) {
7571 Slog.e(TAG, "Error reading " + logFile, e);
7572 }
7573 }
7574 if (crashInfo != null && crashInfo.stackTrace != null) {
7575 sb.append(crashInfo.stackTrace);
7576 }
7577
7578 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7579 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7580 if (lines > 0) {
7581 sb.append("\n");
7582
7583 // Merge several logcat streams, and take the last N lines
7584 InputStreamReader input = null;
7585 try {
7586 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7587 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7588 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7589
7590 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7591 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7592 input = new InputStreamReader(logcat.getInputStream());
7593
7594 int num;
7595 char[] buf = new char[8192];
7596 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7597 } catch (IOException e) {
7598 Slog.e(TAG, "Error running logcat", e);
7599 } finally {
7600 if (input != null) try { input.close(); } catch (IOException e) {}
7601 }
7602 }
7603
7604 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007605 }
Dan Egnora455d192010-03-12 08:52:28 -08007606 };
7607
7608 if (process == null || process.pid == MY_PID) {
7609 worker.run(); // We may be about to die -- need to run this synchronously
7610 } else {
7611 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007612 }
7613 }
7614
7615 /**
7616 * Bring up the "unexpected error" dialog box for a crashing app.
7617 * Deal with edge cases (intercepts from instrumented applications,
7618 * ActivityController, error intent receivers, that sort of thing).
7619 * @param r the application crashing
7620 * @param crashInfo describing the failure
7621 */
7622 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007623 long timeMillis = System.currentTimeMillis();
7624 String shortMsg = crashInfo.exceptionClassName;
7625 String longMsg = crashInfo.exceptionMessage;
7626 String stackTrace = crashInfo.stackTrace;
7627 if (shortMsg != null && longMsg != null) {
7628 longMsg = shortMsg + ": " + longMsg;
7629 } else if (shortMsg != null) {
7630 longMsg = shortMsg;
7631 }
7632
Dan Egnor60d87622009-12-16 16:32:58 -08007633 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007634 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007635 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007636 try {
7637 String name = r != null ? r.processName : null;
7638 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007639 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007640 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007641 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007642 + " at watcher's request");
7643 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007644 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007645 }
7646 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007647 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007648 }
7649 }
7650
7651 final long origId = Binder.clearCallingIdentity();
7652
7653 // If this process is running instrumentation, finish it.
7654 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007655 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007656 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007657 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7658 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007659 Bundle info = new Bundle();
7660 info.putString("shortMsg", shortMsg);
7661 info.putString("longMsg", longMsg);
7662 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7663 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007664 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 }
7666
Dan Egnor60d87622009-12-16 16:32:58 -08007667 // If we can't identify the process or it's already exceeded its crash quota,
7668 // quit right away without showing a crash dialog.
7669 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007670 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007671 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 }
7673
7674 Message msg = Message.obtain();
7675 msg.what = SHOW_ERROR_MSG;
7676 HashMap data = new HashMap();
7677 data.put("result", result);
7678 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007679 msg.obj = data;
7680 mHandler.sendMessage(msg);
7681
7682 Binder.restoreCallingIdentity(origId);
7683 }
7684
7685 int res = result.get();
7686
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007687 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007688 synchronized (this) {
7689 if (r != null) {
7690 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7691 SystemClock.uptimeMillis());
7692 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007693 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007694 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007695 }
7696 }
7697
7698 if (appErrorIntent != null) {
7699 try {
7700 mContext.startActivity(appErrorIntent);
7701 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007702 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007704 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007706
7707 Intent createAppErrorIntentLocked(ProcessRecord r,
7708 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7709 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007710 if (report == null) {
7711 return null;
7712 }
7713 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7714 result.setComponent(r.errorReportReceiver);
7715 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7716 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7717 return result;
7718 }
7719
Dan Egnorb7f03672009-12-09 16:22:32 -08007720 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7721 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007722 if (r.errorReportReceiver == null) {
7723 return null;
7724 }
7725
7726 if (!r.crashing && !r.notResponding) {
7727 return null;
7728 }
7729
Dan Egnorb7f03672009-12-09 16:22:32 -08007730 ApplicationErrorReport report = new ApplicationErrorReport();
7731 report.packageName = r.info.packageName;
7732 report.installerPackageName = r.errorReportReceiver.getPackageName();
7733 report.processName = r.processName;
7734 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007735 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007736
Dan Egnorb7f03672009-12-09 16:22:32 -08007737 if (r.crashing) {
7738 report.type = ApplicationErrorReport.TYPE_CRASH;
7739 report.crashInfo = crashInfo;
7740 } else if (r.notResponding) {
7741 report.type = ApplicationErrorReport.TYPE_ANR;
7742 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007743
Dan Egnorb7f03672009-12-09 16:22:32 -08007744 report.anrInfo.activity = r.notRespondingReport.tag;
7745 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7746 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007747 }
7748
Dan Egnorb7f03672009-12-09 16:22:32 -08007749 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007750 }
7751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7753 // assume our apps are happy - lazy create the list
7754 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7755
7756 synchronized (this) {
7757
7758 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007759 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7760 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007761 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7762 // This one's in trouble, so we'll generate a report for it
7763 // crashes are higher priority (in case there's a crash *and* an anr)
7764 ActivityManager.ProcessErrorStateInfo report = null;
7765 if (app.crashing) {
7766 report = app.crashingReport;
7767 } else if (app.notResponding) {
7768 report = app.notRespondingReport;
7769 }
7770
7771 if (report != null) {
7772 if (errList == null) {
7773 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7774 }
7775 errList.add(report);
7776 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007777 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007778 " crashing = " + app.crashing +
7779 " notResponding = " + app.notResponding);
7780 }
7781 }
7782 }
7783 }
7784
7785 return errList;
7786 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007787
7788 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007789 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007790 if (currApp != null) {
7791 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7792 }
7793 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007794 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7795 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007796 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7797 if (currApp != null) {
7798 currApp.lru = 0;
7799 }
7800 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007801 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007802 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7803 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7804 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7805 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7806 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7807 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7808 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7809 } else {
7810 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7811 }
7812 }
7813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7815 // Lazy instantiation of list
7816 List<ActivityManager.RunningAppProcessInfo> runList = null;
7817 synchronized (this) {
7818 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007819 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7820 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007821 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7822 // Generate process state info for running application
7823 ActivityManager.RunningAppProcessInfo currApp =
7824 new ActivityManager.RunningAppProcessInfo(app.processName,
7825 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007826 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007827 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007828 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007829 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007830 if (app.persistent) {
7831 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007833 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007834 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007835 currApp.importanceReasonCode = app.adjTypeCode;
7836 if (app.adjSource instanceof ProcessRecord) {
7837 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007838 currApp.importanceReasonImportance = oomAdjToImportance(
7839 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007840 } else if (app.adjSource instanceof ActivityRecord) {
7841 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007842 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7843 }
7844 if (app.adjTarget instanceof ComponentName) {
7845 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7846 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007847 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007848 // + " lru=" + currApp.lru);
7849 if (runList == null) {
7850 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7851 }
7852 runList.add(currApp);
7853 }
7854 }
7855 }
7856 return runList;
7857 }
7858
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007859 public List<ApplicationInfo> getRunningExternalApplications() {
7860 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7861 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7862 if (runningApps != null && runningApps.size() > 0) {
7863 Set<String> extList = new HashSet<String>();
7864 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7865 if (app.pkgList != null) {
7866 for (String pkg : app.pkgList) {
7867 extList.add(pkg);
7868 }
7869 }
7870 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007871 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007872 for (String pkg : extList) {
7873 try {
7874 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7875 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7876 retList.add(info);
7877 }
7878 } catch (RemoteException e) {
7879 }
7880 }
7881 }
7882 return retList;
7883 }
7884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 @Override
7886 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007887 if (checkCallingPermission(android.Manifest.permission.DUMP)
7888 != PackageManager.PERMISSION_GRANTED) {
7889 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7890 + Binder.getCallingPid()
7891 + ", uid=" + Binder.getCallingUid()
7892 + " without permission "
7893 + android.Manifest.permission.DUMP);
7894 return;
7895 }
7896
7897 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007898 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007899
7900 int opti = 0;
7901 while (opti < args.length) {
7902 String opt = args[opti];
7903 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7904 break;
7905 }
7906 opti++;
7907 if ("-a".equals(opt)) {
7908 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007909 } else if ("-c".equals(opt)) {
7910 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911 } else if ("-h".equals(opt)) {
7912 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007913 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007914 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007915 pw.println(" a[ctivities]: activity stack state");
7916 pw.println(" b[roadcasts]: broadcast state");
7917 pw.println(" i[ntents]: pending intent state");
7918 pw.println(" p[rocesses]: process state");
7919 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007920 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7921 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007922 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007923 pw.println(" all: dump all activities");
7924 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007925 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007926 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7927 pw.println(" a partial substring in a component name, a");
7928 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007929 pw.println(" -a: include all available server state.");
7930 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007931 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007932 } else {
7933 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007934 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007935 }
7936
7937 // Is the caller requesting to dump a particular piece of data?
7938 if (opti < args.length) {
7939 String cmd = args[opti];
7940 opti++;
7941 if ("activities".equals(cmd) || "a".equals(cmd)) {
7942 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007943 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007944 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007945 return;
7946 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7947 synchronized (this) {
7948 dumpBroadcastsLocked(fd, pw, args, opti, true);
7949 }
7950 return;
7951 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7952 synchronized (this) {
7953 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7954 }
7955 return;
7956 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7957 synchronized (this) {
7958 dumpProcessesLocked(fd, pw, args, opti, true);
7959 }
7960 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007961 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7962 synchronized (this) {
7963 dumpOomLocked(fd, pw, args, opti, true);
7964 }
7965 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007966 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7967 synchronized (this) {
7968 dumpProvidersLocked(fd, pw, args, opti, true);
7969 }
7970 return;
7971 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007972 String[] newArgs;
7973 String name;
7974 if (opti >= args.length) {
7975 name = null;
7976 newArgs = EMPTY_STRING_ARRAY;
7977 } else {
7978 name = args[opti];
7979 opti++;
7980 newArgs = new String[args.length - opti];
7981 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7982 }
7983 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7984 pw.println("No services match: " + name);
7985 pw.println("Use -h for help.");
7986 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007987 return;
7988 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7989 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007990 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007991 }
7992 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007993 } else {
7994 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007995 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7996 pw.println("Bad activity command, or no activities match: " + cmd);
7997 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007998 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007999 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008001 }
8002
8003 // No piece of data specified, dump everything.
8004 synchronized (this) {
8005 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008006 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008007 if (needSep) {
8008 pw.println(" ");
8009 }
8010 if (dumpAll) {
8011 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008012 }
8013 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
8014 if (needSep) {
8015 pw.println(" ");
8016 }
8017 if (dumpAll) {
8018 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008019 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008020 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008021 if (needSep) {
8022 pw.println(" ");
8023 }
8024 if (dumpAll) {
8025 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008026 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008027 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008028 if (needSep) {
8029 pw.println(" ");
8030 }
8031 if (dumpAll) {
8032 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008033 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008034 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008035 if (needSep) {
8036 pw.println(" ");
8037 }
8038 if (dumpAll) {
8039 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008040 }
8041 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
8042 }
8043 }
8044
8045 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008046 int opti, boolean dumpAll, boolean dumpClient) {
8047 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8048 pw.println(" Main stack:");
8049 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008050 pw.println(" ");
8051 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008052 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008053 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008054 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008055 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008056 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
8057 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008058 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008059 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008060 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008061 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008062 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
8063 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008064 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008065 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8066 pw.println(" ");
8067 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008068 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
8069 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008070 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008071 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008072 pw.println(" ");
8073 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008074 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
8075 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008076 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008077
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008078 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008079 if (mMainStack.mPausingActivity != null) {
8080 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8081 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008082 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008083 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008084 if (dumpAll) {
8085 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8086 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008087 pw.println(" mDismissKeyguardOnNextActivity: "
8088 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008090
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008091 if (mRecentTasks.size() > 0) {
8092 pw.println();
8093 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008094
8095 final int N = mRecentTasks.size();
8096 for (int i=0; i<N; i++) {
8097 TaskRecord tr = mRecentTasks.get(i);
8098 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8099 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008100 if (dumpAll) {
8101 mRecentTasks.get(i).dump(pw, " ");
8102 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008103 }
8104 }
8105
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008106 if (dumpAll) {
8107 pw.println(" ");
8108 pw.println(" mCurTask: " + mCurTask);
8109 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008110
8111 return true;
8112 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008113
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008114 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8115 int opti, boolean dumpAll) {
8116 boolean needSep = false;
8117 int numPers = 0;
8118
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008119 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8120
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008121 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008122 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8123 final int NA = procs.size();
8124 for (int ia=0; ia<NA; ia++) {
8125 if (!needSep) {
8126 pw.println(" All known processes:");
8127 needSep = true;
8128 }
8129 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008130 pw.print(r.persistent ? " *PERS*" : " *APP*");
8131 pw.print(" UID "); pw.print(procs.keyAt(ia));
8132 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008133 r.dump(pw, " ");
8134 if (r.persistent) {
8135 numPers++;
8136 }
8137 }
8138 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008139 }
8140
8141 if (mLruProcesses.size() > 0) {
8142 if (needSep) pw.println(" ");
8143 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008144 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008145 dumpProcessOomList(pw, this, mLruProcesses, " ",
8146 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008147 needSep = true;
8148 }
8149
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008150 if (dumpAll) {
8151 synchronized (mPidsSelfLocked) {
8152 if (mPidsSelfLocked.size() > 0) {
8153 if (needSep) pw.println(" ");
8154 needSep = true;
8155 pw.println(" PID mappings:");
8156 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8157 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8158 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 }
8161 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008162 }
8163
8164 if (mForegroundProcesses.size() > 0) {
8165 if (needSep) pw.println(" ");
8166 needSep = true;
8167 pw.println(" Foreground Processes:");
8168 for (int i=0; i<mForegroundProcesses.size(); i++) {
8169 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8170 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008171 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008172 }
8173
8174 if (mPersistentStartingProcesses.size() > 0) {
8175 if (needSep) pw.println(" ");
8176 needSep = true;
8177 pw.println(" Persisent processes that are starting:");
8178 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008179 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008181
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008182 if (mRemovedProcesses.size() > 0) {
8183 if (needSep) pw.println(" ");
8184 needSep = true;
8185 pw.println(" Processes that are being removed:");
8186 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008187 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008188 }
8189
8190 if (mProcessesOnHold.size() > 0) {
8191 if (needSep) pw.println(" ");
8192 needSep = true;
8193 pw.println(" Processes that are on old until the system is ready:");
8194 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008195 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008197
Dianne Hackborn287952c2010-09-22 22:34:31 -07008198 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008199
8200 if (mProcessCrashTimes.getMap().size() > 0) {
8201 if (needSep) pw.println(" ");
8202 needSep = true;
8203 pw.println(" Time since processes crashed:");
8204 long now = SystemClock.uptimeMillis();
8205 for (Map.Entry<String, SparseArray<Long>> procs
8206 : mProcessCrashTimes.getMap().entrySet()) {
8207 SparseArray<Long> uids = procs.getValue();
8208 final int N = uids.size();
8209 for (int i=0; i<N; i++) {
8210 pw.print(" Process "); pw.print(procs.getKey());
8211 pw.print(" uid "); pw.print(uids.keyAt(i));
8212 pw.print(": last crashed ");
8213 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008214 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008215 }
8216 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008218
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008219 if (mBadProcesses.getMap().size() > 0) {
8220 if (needSep) pw.println(" ");
8221 needSep = true;
8222 pw.println(" Bad processes:");
8223 for (Map.Entry<String, SparseArray<Long>> procs
8224 : mBadProcesses.getMap().entrySet()) {
8225 SparseArray<Long> uids = procs.getValue();
8226 final int N = uids.size();
8227 for (int i=0; i<N; i++) {
8228 pw.print(" Bad process "); pw.print(procs.getKey());
8229 pw.print(" uid "); pw.print(uids.keyAt(i));
8230 pw.print(": crashed at time ");
8231 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008232 }
8233 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008235
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008236 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008237 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008238 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008239 if (mHeavyWeightProcess != null) {
8240 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8241 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008242 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008243 if (dumpAll) {
8244 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008245 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008246 pw.println(" mScreenCompatPackages:");
8247 for (Map.Entry<String, Integer> entry
8248 : mCompatModePackages.getPackages().entrySet()) {
8249 String pkg = entry.getKey();
8250 int mode = entry.getValue();
8251 pw.print(" "); pw.print(pkg); pw.print(": ");
8252 pw.print(mode); pw.println();
8253 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008254 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008255 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008256 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8257 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8258 || mOrigWaitForDebugger) {
8259 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8260 + " mDebugTransient=" + mDebugTransient
8261 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8262 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008263 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8264 || mProfileFd != null) {
8265 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8266 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8267 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8268 + mAutoStopProfiler);
8269 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008270 if (mAlwaysFinishActivities || mController != null) {
8271 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8272 + " mController=" + mController);
8273 }
8274 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008275 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008276 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008277 + " mProcessesReady=" + mProcessesReady
8278 + " mSystemReady=" + mSystemReady);
8279 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008280 + " mBooted=" + mBooted
8281 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008282 pw.print(" mLastPowerCheckRealtime=");
8283 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8284 pw.println("");
8285 pw.print(" mLastPowerCheckUptime=");
8286 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8287 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008288 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8289 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008290 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008291 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8292 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008293 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008294
8295 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 }
8297
Dianne Hackborn287952c2010-09-22 22:34:31 -07008298 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8299 int opti, boolean needSep, boolean dumpAll) {
8300 if (mProcessesToGc.size() > 0) {
8301 if (needSep) pw.println(" ");
8302 needSep = true;
8303 pw.println(" Processes that are waiting to GC:");
8304 long now = SystemClock.uptimeMillis();
8305 for (int i=0; i<mProcessesToGc.size(); i++) {
8306 ProcessRecord proc = mProcessesToGc.get(i);
8307 pw.print(" Process "); pw.println(proc);
8308 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8309 pw.print(", last gced=");
8310 pw.print(now-proc.lastRequestedGc);
8311 pw.print(" ms ago, last lowMem=");
8312 pw.print(now-proc.lastLowMemory);
8313 pw.println(" ms ago");
8314
8315 }
8316 }
8317 return needSep;
8318 }
8319
8320 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8321 int opti, boolean dumpAll) {
8322 boolean needSep = false;
8323
8324 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008325 if (needSep) pw.println(" ");
8326 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008327 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008328 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008329 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008330 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8331 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8332 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8333 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8334 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008335 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008336 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008337 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008338 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008339 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008340 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008341
8342 if (needSep) pw.println(" ");
8343 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008344 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008345 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008346 "Proc", "PERS", true);
8347 needSep = true;
8348 }
8349
8350 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8351
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008352 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008353 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008354 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008355 if (mHeavyWeightProcess != null) {
8356 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8357 }
8358
8359 return true;
8360 }
8361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 /**
8363 * There are three ways to call this:
8364 * - no service specified: dump all the services
8365 * - a flattened component name that matched an existing service was specified as the
8366 * first arg: dump that one service
8367 * - the first arg isn't the flattened component name of an existing service:
8368 * dump all services whose component contains the first arg as a substring
8369 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008370 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8371 int opti, boolean dumpAll) {
8372 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008373
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008374 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008375 synchronized (this) {
8376 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008377 services.add(r1);
8378 }
8379 }
8380 } else {
8381 ComponentName componentName = name != null
8382 ? ComponentName.unflattenFromString(name) : null;
8383 int objectId = 0;
8384 if (componentName == null) {
8385 // Not a '/' separated full component name; maybe an object ID?
8386 try {
8387 objectId = Integer.parseInt(name, 16);
8388 name = null;
8389 componentName = null;
8390 } catch (RuntimeException e) {
8391 }
8392 }
8393
8394 synchronized (this) {
8395 for (ServiceRecord r1 : mServices.values()) {
8396 if (componentName != null) {
8397 if (r1.name.equals(componentName)) {
8398 services.add(r1);
8399 }
8400 } else if (name != null) {
8401 if (r1.name.flattenToString().contains(name)) {
8402 services.add(r1);
8403 }
8404 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008405 services.add(r1);
8406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 }
8408 }
8409 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008410
8411 if (services.size() <= 0) {
8412 return false;
8413 }
8414
8415 boolean needSep = false;
8416 for (int i=0; i<services.size(); i++) {
8417 if (needSep) {
8418 pw.println();
8419 }
8420 needSep = true;
8421 dumpService("", fd, pw, services.get(i), args, dumpAll);
8422 }
8423 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008424 }
8425
8426 /**
8427 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8428 * there is a thread associated with the service.
8429 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008430 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8431 final ServiceRecord r, String[] args, boolean dumpAll) {
8432 String innerPrefix = prefix + " ";
8433 synchronized (this) {
8434 pw.print(prefix); pw.print("SERVICE ");
8435 pw.print(r.shortName); pw.print(" ");
8436 pw.print(Integer.toHexString(System.identityHashCode(r)));
8437 pw.print(" pid=");
8438 if (r.app != null) pw.println(r.app.pid);
8439 else pw.println("(not running)");
8440 if (dumpAll) {
8441 r.dump(pw, innerPrefix);
8442 }
8443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008444 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008445 pw.print(prefix); pw.println(" Client:");
8446 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008447 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008448 TransferPipe tp = new TransferPipe();
8449 try {
8450 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8451 tp.setBufferPrefix(prefix + " ");
8452 tp.go(fd);
8453 } finally {
8454 tp.kill();
8455 }
8456 } catch (IOException e) {
8457 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008458 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008459 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008460 }
8461 }
8462 }
8463
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008464 static class ItemMatcher {
8465 ArrayList<ComponentName> components;
8466 ArrayList<String> strings;
8467 ArrayList<Integer> objects;
8468 boolean all;
8469
8470 ItemMatcher() {
8471 all = true;
8472 }
8473
8474 void build(String name) {
8475 ComponentName componentName = ComponentName.unflattenFromString(name);
8476 if (componentName != null) {
8477 if (components == null) {
8478 components = new ArrayList<ComponentName>();
8479 }
8480 components.add(componentName);
8481 all = false;
8482 } else {
8483 int objectId = 0;
8484 // Not a '/' separated full component name; maybe an object ID?
8485 try {
8486 objectId = Integer.parseInt(name, 16);
8487 if (objects == null) {
8488 objects = new ArrayList<Integer>();
8489 }
8490 objects.add(objectId);
8491 all = false;
8492 } catch (RuntimeException e) {
8493 // Not an integer; just do string match.
8494 if (strings == null) {
8495 strings = new ArrayList<String>();
8496 }
8497 strings.add(name);
8498 all = false;
8499 }
8500 }
8501 }
8502
8503 int build(String[] args, int opti) {
8504 for (; opti<args.length; opti++) {
8505 String name = args[opti];
8506 if ("--".equals(name)) {
8507 return opti+1;
8508 }
8509 build(name);
8510 }
8511 return opti;
8512 }
8513
8514 boolean match(Object object, ComponentName comp) {
8515 if (all) {
8516 return true;
8517 }
8518 if (components != null) {
8519 for (int i=0; i<components.size(); i++) {
8520 if (components.get(i).equals(comp)) {
8521 return true;
8522 }
8523 }
8524 }
8525 if (objects != null) {
8526 for (int i=0; i<objects.size(); i++) {
8527 if (System.identityHashCode(object) == objects.get(i)) {
8528 return true;
8529 }
8530 }
8531 }
8532 if (strings != null) {
8533 String flat = comp.flattenToString();
8534 for (int i=0; i<strings.size(); i++) {
8535 if (flat.contains(strings.get(i))) {
8536 return true;
8537 }
8538 }
8539 }
8540 return false;
8541 }
8542 }
8543
Dianne Hackborn625ac272010-09-17 18:29:22 -07008544 /**
8545 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008546 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008547 * - the cmd arg isn't the flattened component name of an existing activity:
8548 * dump all activity whose component contains the cmd as a substring
8549 * - A hex number of the ActivityRecord object instance.
8550 */
8551 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8552 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008553 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008554
8555 if ("all".equals(name)) {
8556 synchronized (this) {
8557 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008558 activities.add(r1);
8559 }
8560 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008561 } else if ("top".equals(name)) {
8562 synchronized (this) {
8563 final int N = mMainStack.mHistory.size();
8564 if (N > 0) {
8565 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8566 }
8567 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008568 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008569 ItemMatcher matcher = new ItemMatcher();
8570 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008571
8572 synchronized (this) {
8573 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008574 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008575 activities.add(r1);
8576 }
8577 }
8578 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008579 }
8580
8581 if (activities.size() <= 0) {
8582 return false;
8583 }
8584
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008585 String[] newArgs = new String[args.length - opti];
8586 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8587
Dianne Hackborn30d71892010-12-11 10:37:55 -08008588 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008589 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008590 for (int i=activities.size()-1; i>=0; i--) {
8591 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008592 if (needSep) {
8593 pw.println();
8594 }
8595 needSep = true;
8596 synchronized (this) {
8597 if (lastTask != r.task) {
8598 lastTask = r.task;
8599 pw.print("TASK "); pw.print(lastTask.affinity);
8600 pw.print(" id="); pw.println(lastTask.taskId);
8601 if (dumpAll) {
8602 lastTask.dump(pw, " ");
8603 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008604 }
8605 }
8606 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008607 }
8608 return true;
8609 }
8610
8611 /**
8612 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8613 * there is a thread associated with the activity.
8614 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008615 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008616 final ActivityRecord r, String[] args, boolean dumpAll) {
8617 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008618 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008619 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8620 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8621 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008622 if (r.app != null) pw.println(r.app.pid);
8623 else pw.println("(not running)");
8624 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008625 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008626 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008627 }
8628 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008629 // flush anything that is already in the PrintWriter since the thread is going
8630 // to write to the file descriptor directly
8631 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008632 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008633 TransferPipe tp = new TransferPipe();
8634 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008635 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8636 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008637 tp.go(fd);
8638 } finally {
8639 tp.kill();
8640 }
8641 } catch (IOException e) {
8642 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008643 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008644 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008645 }
8646 }
8647 }
8648
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008649 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8650 int opti, boolean dumpAll) {
8651 boolean needSep = false;
8652
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008653 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008654 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008656 pw.println(" Registered Receivers:");
8657 Iterator it = mRegisteredReceivers.values().iterator();
8658 while (it.hasNext()) {
8659 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008660 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008661 r.dump(pw, " ");
8662 }
8663 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008664
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008665 pw.println();
8666 pw.println(" Receiver Resolver Table:");
8667 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008668 needSep = true;
8669 }
8670
8671 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8672 || mPendingBroadcast != null) {
8673 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008674 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008675 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008676 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008677 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8678 pw.println(" Broadcast #" + i + ":");
8679 mParallelBroadcasts.get(i).dump(pw, " ");
8680 }
8681 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008682 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008683 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008684 }
8685 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8686 pw.println(" Serialized Broadcast #" + i + ":");
8687 mOrderedBroadcasts.get(i).dump(pw, " ");
8688 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008689 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008690 pw.println(" Pending broadcast:");
8691 if (mPendingBroadcast != null) {
8692 mPendingBroadcast.dump(pw, " ");
8693 } else {
8694 pw.println(" (null)");
8695 }
8696 needSep = true;
8697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008698
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008699 if (needSep) {
8700 pw.println();
8701 }
8702 pw.println(" Historical broadcasts:");
8703 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8704 BroadcastRecord r = mBroadcastHistory[i];
8705 if (r == null) {
8706 break;
8707 }
8708 if (dumpAll) {
8709 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8710 r.dump(pw, " ");
8711 } else {
8712 if (i >= 50) {
8713 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008714 break;
8715 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008716 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008717 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008718 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008719 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008720
8721 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008722 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008723 pw.println(" Sticky broadcasts:");
8724 StringBuilder sb = new StringBuilder(128);
8725 for (Map.Entry<String, ArrayList<Intent>> ent
8726 : mStickyBroadcasts.entrySet()) {
8727 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008728 if (dumpAll) {
8729 pw.println(":");
8730 ArrayList<Intent> intents = ent.getValue();
8731 final int N = intents.size();
8732 for (int i=0; i<N; i++) {
8733 sb.setLength(0);
8734 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008735 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008736 pw.println(sb.toString());
8737 Bundle bundle = intents.get(i).getExtras();
8738 if (bundle != null) {
8739 pw.print(" ");
8740 pw.println(bundle.toString());
8741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008743 } else {
8744 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008745 }
8746 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008747 needSep = true;
8748 }
8749
8750 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008751 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008752 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008753 pw.println(" mHandler:");
8754 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008755 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008756 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008757
8758 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 }
8760
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008761 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008762 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008763 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008764
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008765 ItemMatcher matcher = new ItemMatcher();
8766 matcher.build(args, opti);
8767
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8769 if (mServices.size() > 0) {
8770 pw.println(" Active services:");
8771 long nowReal = SystemClock.elapsedRealtime();
8772 Iterator<ServiceRecord> it = mServices.values().iterator();
8773 needSep = false;
8774 while (it.hasNext()) {
8775 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008776 if (!matcher.match(r, r.name)) {
8777 continue;
8778 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008779 if (needSep) {
8780 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008781 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008782 pw.print(" * "); pw.println(r);
8783 if (dumpAll) {
8784 r.dump(pw, " ");
8785 needSep = true;
8786 } else {
8787 pw.print(" app="); pw.println(r.app);
8788 pw.print(" created=");
8789 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8790 pw.print(" started="); pw.print(r.startRequested);
8791 pw.print(" connections="); pw.println(r.connections.size());
8792 }
8793 if (dumpClient && r.app != null && r.app.thread != null) {
8794 pw.println(" Client:");
8795 pw.flush();
8796 try {
8797 TransferPipe tp = new TransferPipe();
8798 try {
8799 r.app.thread.dumpService(
8800 tp.getWriteFd().getFileDescriptor(), r, args);
8801 tp.setBufferPrefix(" ");
8802 // Short timeout, since blocking here can
8803 // deadlock with the application.
8804 tp.go(fd, 2000);
8805 } finally {
8806 tp.kill();
8807 }
8808 } catch (IOException e) {
8809 pw.println(" Failure while dumping the service: " + e);
8810 } catch (RemoteException e) {
8811 pw.println(" Got a RemoteException while dumping the service");
8812 }
8813 needSep = true;
8814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008816 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008817 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008818
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008819 if (mPendingServices.size() > 0) {
8820 if (needSep) pw.println(" ");
8821 pw.println(" Pending services:");
8822 for (int i=0; i<mPendingServices.size(); i++) {
8823 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008824 if (!matcher.match(r, r.name)) {
8825 continue;
8826 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008827 pw.print(" * Pending "); pw.println(r);
8828 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008829 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008830 needSep = true;
8831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008832
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008833 if (mRestartingServices.size() > 0) {
8834 if (needSep) pw.println(" ");
8835 pw.println(" Restarting services:");
8836 for (int i=0; i<mRestartingServices.size(); i++) {
8837 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008838 if (!matcher.match(r, r.name)) {
8839 continue;
8840 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008841 pw.print(" * Restarting "); pw.println(r);
8842 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008843 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008844 needSep = true;
8845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008846
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008847 if (mStoppingServices.size() > 0) {
8848 if (needSep) pw.println(" ");
8849 pw.println(" Stopping services:");
8850 for (int i=0; i<mStoppingServices.size(); i++) {
8851 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008852 if (!matcher.match(r, r.name)) {
8853 continue;
8854 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008855 pw.print(" * Stopping "); pw.println(r);
8856 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008857 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008858 needSep = true;
8859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008860
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008861 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008862 if (mServiceConnections.size() > 0) {
8863 if (needSep) pw.println(" ");
8864 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008865 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 = mServiceConnections.values().iterator();
8867 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008868 ArrayList<ConnectionRecord> r = it.next();
8869 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008870 ConnectionRecord cr = r.get(i);
8871 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8872 continue;
8873 }
8874 pw.print(" * "); pw.println(cr);
8875 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008878 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 }
8880 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008881
8882 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 }
8884
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008885 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8886 int opti, boolean dumpAll) {
8887 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008889 ItemMatcher matcher = new ItemMatcher();
8890 matcher.build(args, opti);
8891
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008892 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8893 if (mProvidersByClass.size() > 0) {
8894 if (needSep) pw.println(" ");
8895 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008896 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008897 = mProvidersByClass.entrySet().iterator();
8898 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008899 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008900 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008901 ComponentName comp = e.getKey();
8902 String cls = comp.getClassName();
8903 int end = cls.lastIndexOf('.');
8904 if (end > 0 && end < (cls.length()-2)) {
8905 cls = cls.substring(end+1);
8906 }
8907 if (!matcher.match(r, comp)) {
8908 continue;
8909 }
8910 pw.print(" * "); pw.print(cls); pw.print(" (");
8911 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008912 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008913 pw.println();
8914 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008915 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008916 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008917 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008918 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008919 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008920 } else {
8921 pw.println();
8922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008924 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008925 needSep = true;
8926 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008927
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008928 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008929 if (mProvidersByName.size() > 0) {
8930 pw.println(" ");
8931 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008932 Iterator<Map.Entry<String, ContentProviderRecord>> it
8933 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008934 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008935 Map.Entry<String, ContentProviderRecord> e = it.next();
8936 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008937 if (!matcher.match(r, r.name)) {
8938 continue;
8939 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008940 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8941 pw.println(r);
8942 }
8943 needSep = true;
8944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008945 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008946
8947 if (mLaunchingProviders.size() > 0) {
8948 if (needSep) pw.println(" ");
8949 pw.println(" Launching content providers:");
8950 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8951 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8952 pw.println(mLaunchingProviders.get(i));
8953 }
8954 needSep = true;
8955 }
8956
8957 if (mGrantedUriPermissions.size() > 0) {
8958 pw.println();
8959 pw.println("Granted Uri Permissions:");
8960 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8961 int uid = mGrantedUriPermissions.keyAt(i);
8962 HashMap<Uri, UriPermission> perms
8963 = mGrantedUriPermissions.valueAt(i);
8964 pw.print(" * UID "); pw.print(uid);
8965 pw.println(" holds:");
8966 for (UriPermission perm : perms.values()) {
8967 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008968 if (dumpAll) {
8969 perm.dump(pw, " ");
8970 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008971 }
8972 }
8973 needSep = true;
8974 }
8975
8976 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 }
8978
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008979 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8980 int opti, boolean dumpAll) {
8981 boolean needSep = false;
8982
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008983 if (this.mIntentSenderRecords.size() > 0) {
8984 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8985 Iterator<WeakReference<PendingIntentRecord>> it
8986 = mIntentSenderRecords.values().iterator();
8987 while (it.hasNext()) {
8988 WeakReference<PendingIntentRecord> ref = it.next();
8989 PendingIntentRecord rec = ref != null ? ref.get(): null;
8990 needSep = true;
8991 if (rec != null) {
8992 pw.print(" * "); pw.println(rec);
8993 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008994 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008995 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008996 } else {
8997 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 }
8999 }
9000 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009001
9002 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009003 }
9004
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009005 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9006 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009007 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009008 boolean needNL = false;
9009 final String innerPrefix = prefix + " ";
9010 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009012 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009013 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009014 if (needNL) {
9015 pw.println(" ");
9016 needNL = false;
9017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009018 if (lastTask != r.task) {
9019 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009020 pw.print(prefix);
9021 pw.print(full ? "* " : " ");
9022 pw.println(lastTask);
9023 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009024 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009025 } else if (complete) {
9026 // Complete + brief == give a summary. Isn't that obvious?!?
9027 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009028 pw.print(prefix); pw.print(" ");
9029 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009030 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009032 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009033 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9034 pw.print(" #"); pw.print(i); pw.print(": ");
9035 pw.println(r);
9036 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009037 r.dump(pw, innerPrefix);
9038 } else if (complete) {
9039 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009040 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009041 if (r.app != null) {
9042 pw.print(innerPrefix); pw.println(r.app);
9043 }
9044 }
9045 if (client && r.app != null && r.app.thread != null) {
9046 // flush anything that is already in the PrintWriter since the thread is going
9047 // to write to the file descriptor directly
9048 pw.flush();
9049 try {
9050 TransferPipe tp = new TransferPipe();
9051 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009052 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9053 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009054 // Short timeout, since blocking here can
9055 // deadlock with the application.
9056 tp.go(fd, 2000);
9057 } finally {
9058 tp.kill();
9059 }
9060 } catch (IOException e) {
9061 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9062 } catch (RemoteException e) {
9063 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9064 }
9065 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009066 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009067 }
9068 }
9069
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009070 private static String buildOomTag(String prefix, String space, int val, int base) {
9071 if (val == base) {
9072 if (space == null) return prefix;
9073 return prefix + " ";
9074 }
9075 return prefix + "+" + Integer.toString(val-base);
9076 }
9077
9078 private static final int dumpProcessList(PrintWriter pw,
9079 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009080 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009081 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009082 final int N = list.size()-1;
9083 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009084 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009085 pw.println(String.format("%s%s #%2d: %s",
9086 prefix, (r.persistent ? persistentLabel : normalLabel),
9087 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009088 if (r.persistent) {
9089 numPers++;
9090 }
9091 }
9092 return numPers;
9093 }
9094
Dianne Hackborn287952c2010-09-22 22:34:31 -07009095 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009096 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009097 String prefix, String normalLabel, String persistentLabel,
9098 boolean inclDetails) {
9099
Dianne Hackborn905577f2011-09-07 18:31:28 -07009100 ArrayList<Pair<ProcessRecord, Integer>> list
9101 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9102 for (int i=0; i<origList.size(); i++) {
9103 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9104 }
9105
9106 Comparator<Pair<ProcessRecord, Integer>> comparator
9107 = new Comparator<Pair<ProcessRecord, Integer>>() {
9108 @Override
9109 public int compare(Pair<ProcessRecord, Integer> object1,
9110 Pair<ProcessRecord, Integer> object2) {
9111 if (object1.first.setAdj != object2.first.setAdj) {
9112 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9113 }
9114 if (object1.second.intValue() != object2.second.intValue()) {
9115 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9116 }
9117 return 0;
9118 }
9119 };
9120
9121 Collections.sort(list, comparator);
9122
Dianne Hackborn287952c2010-09-22 22:34:31 -07009123 final long curRealtime = SystemClock.elapsedRealtime();
9124 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9125 final long curUptime = SystemClock.uptimeMillis();
9126 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9127
9128 final int N = list.size()-1;
9129 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009130 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009131 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009132 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009133 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009134 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9135 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009136 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9137 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009138 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9139 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009140 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9141 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009142 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9143 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9144 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9145 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9146 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9147 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9148 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9149 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9150 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9151 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009152 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9153 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009154 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9155 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009156 } else {
9157 oomAdj = Integer.toString(r.setAdj);
9158 }
9159 String schedGroup;
9160 switch (r.setSchedGroup) {
9161 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9162 schedGroup = "B";
9163 break;
9164 case Process.THREAD_GROUP_DEFAULT:
9165 schedGroup = "F";
9166 break;
9167 default:
9168 schedGroup = Integer.toString(r.setSchedGroup);
9169 break;
9170 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009171 String foreground;
9172 if (r.foregroundActivities) {
9173 foreground = "A";
9174 } else if (r.foregroundServices) {
9175 foreground = "S";
9176 } else {
9177 foreground = " ";
9178 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009179 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009180 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009181 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009182 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009183 if (r.adjSource != null || r.adjTarget != null) {
9184 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009185 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009186 if (r.adjTarget instanceof ComponentName) {
9187 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9188 } else if (r.adjTarget != null) {
9189 pw.print(r.adjTarget.toString());
9190 } else {
9191 pw.print("{null}");
9192 }
9193 pw.print("<=");
9194 if (r.adjSource instanceof ProcessRecord) {
9195 pw.print("Proc{");
9196 pw.print(((ProcessRecord)r.adjSource).toShortString());
9197 pw.println("}");
9198 } else if (r.adjSource != null) {
9199 pw.println(r.adjSource.toString());
9200 } else {
9201 pw.println("{null}");
9202 }
9203 }
9204 if (inclDetails) {
9205 pw.print(prefix);
9206 pw.print(" ");
9207 pw.print("oom: max="); pw.print(r.maxAdj);
9208 pw.print(" hidden="); pw.print(r.hiddenAdj);
9209 pw.print(" curRaw="); pw.print(r.curRawAdj);
9210 pw.print(" setRaw="); pw.print(r.setRawAdj);
9211 pw.print(" cur="); pw.print(r.curAdj);
9212 pw.print(" set="); pw.println(r.setAdj);
9213 pw.print(prefix);
9214 pw.print(" ");
9215 pw.print("keeping="); pw.print(r.keeping);
9216 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009217 pw.print(" empty="); pw.print(r.empty);
9218 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009219
9220 if (!r.keeping) {
9221 if (r.lastWakeTime != 0) {
9222 long wtime;
9223 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9224 synchronized (stats) {
9225 wtime = stats.getProcessWakeTime(r.info.uid,
9226 r.pid, curRealtime);
9227 }
9228 long timeUsed = wtime - r.lastWakeTime;
9229 pw.print(prefix);
9230 pw.print(" ");
9231 pw.print("keep awake over ");
9232 TimeUtils.formatDuration(realtimeSince, pw);
9233 pw.print(" used ");
9234 TimeUtils.formatDuration(timeUsed, pw);
9235 pw.print(" (");
9236 pw.print((timeUsed*100)/realtimeSince);
9237 pw.println("%)");
9238 }
9239 if (r.lastCpuTime != 0) {
9240 long timeUsed = r.curCpuTime - r.lastCpuTime;
9241 pw.print(prefix);
9242 pw.print(" ");
9243 pw.print("run cpu over ");
9244 TimeUtils.formatDuration(uptimeSince, pw);
9245 pw.print(" used ");
9246 TimeUtils.formatDuration(timeUsed, pw);
9247 pw.print(" (");
9248 pw.print((timeUsed*100)/uptimeSince);
9249 pw.println("%)");
9250 }
9251 }
9252 }
9253 }
9254 }
9255
Dianne Hackbornb437e092011-08-05 17:50:29 -07009256 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009257 ArrayList<ProcessRecord> procs;
9258 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009259 if (args != null && args.length > start
9260 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009261 procs = new ArrayList<ProcessRecord>();
9262 int pid = -1;
9263 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009264 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009265 } catch (NumberFormatException e) {
9266
9267 }
9268 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9269 ProcessRecord proc = mLruProcesses.get(i);
9270 if (proc.pid == pid) {
9271 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009272 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009273 procs.add(proc);
9274 }
9275 }
9276 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009277 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009278 return null;
9279 }
9280 } else {
9281 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9282 }
9283 }
9284 return procs;
9285 }
9286
9287 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9288 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009289 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009290 if (procs == null) {
9291 return;
9292 }
9293
9294 long uptime = SystemClock.uptimeMillis();
9295 long realtime = SystemClock.elapsedRealtime();
9296 pw.println("Applications Graphics Acceleration Info:");
9297 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9298
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009299 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9300 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009301 if (r.thread != null) {
9302 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9303 pw.flush();
9304 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009305 TransferPipe tp = new TransferPipe();
9306 try {
9307 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9308 tp.go(fd);
9309 } finally {
9310 tp.kill();
9311 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009312 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009313 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009314 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009315 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009316 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009317 pw.flush();
9318 }
9319 }
9320 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009321 }
9322
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009323 final static class MemItem {
9324 final String label;
9325 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009326 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009327
9328 public MemItem(String _label, long _pss) {
9329 label = _label;
9330 pss = _pss;
9331 }
9332 }
9333
Dianne Hackbornb437e092011-08-05 17:50:29 -07009334 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9335 boolean sort) {
9336 if (sort) {
9337 Collections.sort(items, new Comparator<MemItem>() {
9338 @Override
9339 public int compare(MemItem lhs, MemItem rhs) {
9340 if (lhs.pss < rhs.pss) {
9341 return 1;
9342 } else if (lhs.pss > rhs.pss) {
9343 return -1;
9344 }
9345 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009346 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009347 });
9348 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009349
9350 for (int i=0; i<items.size(); i++) {
9351 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009352 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9353 if (mi.subitems != null) {
9354 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9355 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009356 }
9357 }
9358
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009359 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009360 PrintWriter pw, String prefix, String[] args, boolean brief,
9361 PrintWriter categoryPw) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009362 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009363 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009364
9365 int opti = 0;
9366 while (opti < args.length) {
9367 String opt = args[opti];
9368 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9369 break;
9370 }
9371 opti++;
9372 if ("-a".equals(opt)) {
9373 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009374 } else if ("--oom".equals(opt)) {
9375 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009376 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009377 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009378 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009379 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009380 pw.println("If [process] is specified it can be the name or ");
9381 pw.println("pid of a specific process to dump.");
9382 return;
9383 } else {
9384 pw.println("Unknown argument: " + opt + "; use -h for help");
9385 }
9386 }
9387
9388 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009389 if (procs == null) {
9390 return;
9391 }
9392
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009393 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 long uptime = SystemClock.uptimeMillis();
9395 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009396
9397 if (procs.size() == 1 || isCheckinRequest) {
9398 dumpAll = true;
9399 }
9400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 if (isCheckinRequest) {
9402 // short checkin version
9403 pw.println(uptime + "," + realtime);
9404 pw.flush();
9405 } else {
9406 pw.println("Applications Memory Usage (kB):");
9407 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9408 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009409
Dianne Hackbornb437e092011-08-05 17:50:29 -07009410 String[] innerArgs = new String[args.length-opti];
9411 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9412
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009413 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9414 long nativePss=0, dalvikPss=0, otherPss=0;
9415 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9416
Dianne Hackbornb437e092011-08-05 17:50:29 -07009417 final int[] oomAdj = new int[] {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009418 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
Dianne Hackborn7d608422011-08-07 16:24:18 -07009419 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009420 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009421 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009422 };
9423 final String[] oomLabel = new String[] {
9424 "System", "Persistent", "Foreground",
9425 "Visible", "Perceptible", "Heavy Weight",
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009426 "Backup", "A Services", "Home", "Previous",
9427 "B Services", "Background"
Dianne Hackbornb437e092011-08-05 17:50:29 -07009428 };
9429 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009430 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009431
9432 long totalPss = 0;
9433
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009434 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9435 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009436 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009437 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009438 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9439 pw.flush();
9440 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009441 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009442 if (dumpAll) {
9443 try {
9444 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9445 } catch (RemoteException e) {
9446 if (!isCheckinRequest) {
9447 pw.println("Got RemoteException!");
9448 pw.flush();
9449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009450 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009451 } else {
9452 mi = new Debug.MemoryInfo();
9453 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009455
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009456 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009457 long myTotalPss = mi.getTotalPss();
9458 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009459 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9460 myTotalPss);
9461 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009462
9463 nativePss += mi.nativePss;
9464 dalvikPss += mi.dalvikPss;
9465 otherPss += mi.otherPss;
9466 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9467 long mem = mi.getOtherPss(j);
9468 miscPss[j] += mem;
9469 otherPss -= mem;
9470 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009471
9472 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9473 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9474 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009475 if (oomProcs[oomIndex] == null) {
9476 oomProcs[oomIndex] = new ArrayList<MemItem>();
9477 }
9478 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009479 break;
9480 }
9481 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009483 }
9484 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009485
9486 if (!isCheckinRequest && procs.size() > 1) {
9487 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9488
9489 catMems.add(new MemItem("Native", nativePss));
9490 catMems.add(new MemItem("Dalvik", dalvikPss));
9491 catMems.add(new MemItem("Unknown", otherPss));
9492 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9493 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9494 }
9495
Dianne Hackbornb437e092011-08-05 17:50:29 -07009496 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9497 for (int j=0; j<oomPss.length; j++) {
9498 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009499 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9500 item.subitems = oomProcs[j];
9501 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009502 }
9503 }
9504
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009505 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009506 pw.println();
9507 pw.println("Total PSS by process:");
9508 dumpMemItems(pw, " ", procMems, true);
9509 pw.println();
9510 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009511 pw.println("Total PSS by OOM adjustment:");
9512 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009513 if (!oomOnly) {
9514 PrintWriter out = categoryPw != null ? categoryPw : pw;
9515 out.println();
9516 out.println("Total PSS by category:");
9517 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009518 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009519 pw.println();
9520 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522 }
9523
9524 /**
9525 * Searches array of arguments for the specified string
9526 * @param args array of argument strings
9527 * @param value value to search for
9528 * @return true if the value is contained in the array
9529 */
9530 private static boolean scanArgs(String[] args, String value) {
9531 if (args != null) {
9532 for (String arg : args) {
9533 if (value.equals(arg)) {
9534 return true;
9535 }
9536 }
9537 }
9538 return false;
9539 }
9540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 private final void killServicesLocked(ProcessRecord app,
9542 boolean allowRestart) {
9543 // Report disconnected services.
9544 if (false) {
9545 // XXX we are letting the client link to the service for
9546 // death notifications.
9547 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009548 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009550 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009551 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009552 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009553 = r.connections.values().iterator();
9554 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009555 ArrayList<ConnectionRecord> cl = jt.next();
9556 for (int i=0; i<cl.size(); i++) {
9557 ConnectionRecord c = cl.get(i);
9558 if (c.binding.client != app) {
9559 try {
9560 //c.conn.connected(r.className, null);
9561 } catch (Exception e) {
9562 // todo: this should be asynchronous!
9563 Slog.w(TAG, "Exception thrown disconnected servce "
9564 + r.shortName
9565 + " from app " + app.processName, e);
9566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 }
9568 }
9569 }
9570 }
9571 }
9572 }
9573 }
9574
9575 // Clean up any connections this application has to other services.
9576 if (app.connections.size() > 0) {
9577 Iterator<ConnectionRecord> it = app.connections.iterator();
9578 while (it.hasNext()) {
9579 ConnectionRecord r = it.next();
9580 removeConnectionLocked(r, app, null);
9581 }
9582 }
9583 app.connections.clear();
9584
9585 if (app.services.size() != 0) {
9586 // Any services running in the application need to be placed
9587 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009588 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009589 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009590 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009591 synchronized (sr.stats.getBatteryStats()) {
9592 sr.stats.stopLaunchedLocked();
9593 }
9594 sr.app = null;
9595 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009596 if (mStoppingServices.remove(sr)) {
9597 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9598 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009599
9600 boolean hasClients = sr.bindings.size() > 0;
9601 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009602 Iterator<IntentBindRecord> bindings
9603 = sr.bindings.values().iterator();
9604 while (bindings.hasNext()) {
9605 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009606 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009607 + ": shouldUnbind=" + b.hasBound);
9608 b.binder = null;
9609 b.requested = b.received = b.hasBound = false;
9610 }
9611 }
9612
Dianne Hackborn070783f2010-12-29 16:46:28 -08009613 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9614 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009615 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009617 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 sr.crashCount, sr.shortName, app.pid);
9619 bringDownServiceLocked(sr, true);
9620 } else if (!allowRestart) {
9621 bringDownServiceLocked(sr, true);
9622 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009623 boolean canceled = scheduleServiceRestartLocked(sr, true);
9624
9625 // Should the service remain running? Note that in the
9626 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009627 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009628 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9629 if (sr.pendingStarts.size() == 0) {
9630 sr.startRequested = false;
9631 if (!hasClients) {
9632 // Whoops, no reason to restart!
9633 bringDownServiceLocked(sr, true);
9634 }
9635 }
9636 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009637 }
9638 }
9639
9640 if (!allowRestart) {
9641 app.services.clear();
9642 }
9643 }
9644
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009645 // Make sure we have no more records on the stopping list.
9646 int i = mStoppingServices.size();
9647 while (i > 0) {
9648 i--;
9649 ServiceRecord sr = mStoppingServices.get(i);
9650 if (sr.app == app) {
9651 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009652 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009653 }
9654 }
9655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009656 app.executingServices.clear();
9657 }
9658
9659 private final void removeDyingProviderLocked(ProcessRecord proc,
9660 ContentProviderRecord cpr) {
9661 synchronized (cpr) {
9662 cpr.launchingApp = null;
9663 cpr.notifyAll();
9664 }
9665
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009666 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 String names[] = cpr.info.authority.split(";");
9668 for (int j = 0; j < names.length; j++) {
9669 mProvidersByName.remove(names[j]);
9670 }
9671
9672 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9673 while (cit.hasNext()) {
9674 ProcessRecord capp = cit.next();
9675 if (!capp.persistent && capp.thread != null
9676 && capp.pid != 0
9677 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009678 Slog.i(TAG, "Kill " + capp.processName
9679 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009680 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009681 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009682 capp.processName, capp.setAdj, "dying provider "
9683 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009684 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 }
9686 }
9687
9688 mLaunchingProviders.remove(cpr);
9689 }
9690
9691 /**
9692 * Main code for cleaning up a process when it has gone away. This is
9693 * called both as a result of the process dying, or directly when stopping
9694 * a process when running in single process mode.
9695 */
9696 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009697 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009699 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 }
9701
Dianne Hackborn36124872009-10-08 16:22:03 -07009702 mProcessesToGc.remove(app);
9703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009704 // Dismiss any open dialogs.
9705 if (app.crashDialog != null) {
9706 app.crashDialog.dismiss();
9707 app.crashDialog = null;
9708 }
9709 if (app.anrDialog != null) {
9710 app.anrDialog.dismiss();
9711 app.anrDialog = null;
9712 }
9713 if (app.waitDialog != null) {
9714 app.waitDialog.dismiss();
9715 app.waitDialog = null;
9716 }
9717
9718 app.crashing = false;
9719 app.notResponding = false;
9720
9721 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009722 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009723 app.thread = null;
9724 app.forcingToForeground = null;
9725 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009726 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009727 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009728 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009729
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009730 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009731
9732 boolean restart = false;
9733
9734 int NL = mLaunchingProviders.size();
9735
9736 // Remove published content providers.
9737 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009738 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009739 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009740 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009742 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009743
9744 // See if someone is waiting for this provider... in which
9745 // case we don't remove it, but just let it restart.
9746 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009747 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 for (; i<NL; i++) {
9749 if (mLaunchingProviders.get(i) == cpr) {
9750 restart = true;
9751 break;
9752 }
9753 }
9754 } else {
9755 i = NL;
9756 }
9757
9758 if (i >= NL) {
9759 removeDyingProviderLocked(app, cpr);
9760 NL = mLaunchingProviders.size();
9761 }
9762 }
9763 app.pubProviders.clear();
9764 }
9765
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009766 // Take care of any launching providers waiting for this process.
9767 if (checkAppInLaunchingProvidersLocked(app, false)) {
9768 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771 // Unregister from connected content providers.
9772 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009773 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009774 while (it.hasNext()) {
9775 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9776 cpr.clients.remove(app);
9777 }
9778 app.conProviders.clear();
9779 }
9780
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009781 // At this point there may be remaining entries in mLaunchingProviders
9782 // where we were the only one waiting, so they are no longer of use.
9783 // Look for these and clean up if found.
9784 // XXX Commented out for now. Trying to figure out a way to reproduce
9785 // the actual situation to identify what is actually going on.
9786 if (false) {
9787 for (int i=0; i<NL; i++) {
9788 ContentProviderRecord cpr = (ContentProviderRecord)
9789 mLaunchingProviders.get(i);
9790 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9791 synchronized (cpr) {
9792 cpr.launchingApp = null;
9793 cpr.notifyAll();
9794 }
9795 }
9796 }
9797 }
9798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009799 skipCurrentReceiverLocked(app);
9800
9801 // Unregister any receivers.
9802 if (app.receivers.size() > 0) {
9803 Iterator<ReceiverList> it = app.receivers.iterator();
9804 while (it.hasNext()) {
9805 removeReceiverLocked(it.next());
9806 }
9807 app.receivers.clear();
9808 }
9809
Christopher Tate181fafa2009-05-14 11:12:14 -07009810 // If the app is undergoing backup, tell the backup manager about it
9811 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009812 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009813 try {
9814 IBackupManager bm = IBackupManager.Stub.asInterface(
9815 ServiceManager.getService(Context.BACKUP_SERVICE));
9816 bm.agentDisconnected(app.info.packageName);
9817 } catch (RemoteException e) {
9818 // can't happen; backup manager is local
9819 }
9820 }
9821
Jeff Sharkey287bd832011-05-28 19:36:26 -07009822 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009824 // If the caller is restarting this app, then leave it in its
9825 // current lists and let the caller take care of it.
9826 if (restarting) {
9827 return;
9828 }
9829
9830 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009831 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009832 "Removing non-persistent process during cleanup: " + app);
9833 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009834 if (mHeavyWeightProcess == app) {
9835 mHeavyWeightProcess = null;
9836 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009838 } else if (!app.removed) {
9839 // This app is persistent, so we need to keep its record around.
9840 // If it is not already on the pending app list, add it there
9841 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009842 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9843 mPersistentStartingProcesses.add(app);
9844 restart = true;
9845 }
9846 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009847 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9848 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009849 mProcessesOnHold.remove(app);
9850
The Android Open Source Project4df24232009-03-05 14:34:35 -08009851 if (app == mHomeProcess) {
9852 mHomeProcess = null;
9853 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009854 if (app == mPreviousProcess) {
9855 mPreviousProcess = null;
9856 }
9857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 if (restart) {
9859 // We have components that still need to be running in the
9860 // process, so re-launch it.
9861 mProcessNames.put(app.processName, app.info.uid, app);
9862 startProcessLocked(app, "restart", app.processName);
9863 } else if (app.pid > 0 && app.pid != MY_PID) {
9864 // Goodbye!
9865 synchronized (mPidsSelfLocked) {
9866 mPidsSelfLocked.remove(app.pid);
9867 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9868 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009869 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009870 }
9871 }
9872
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009873 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9874 // Look through the content providers we are waiting to have launched,
9875 // and if any run in this process then either schedule a restart of
9876 // the process or kill the client waiting for it if this process has
9877 // gone bad.
9878 int NL = mLaunchingProviders.size();
9879 boolean restart = false;
9880 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009881 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009882 if (cpr.launchingApp == app) {
9883 if (!alwaysBad && !app.bad) {
9884 restart = true;
9885 } else {
9886 removeDyingProviderLocked(app, cpr);
9887 NL = mLaunchingProviders.size();
9888 }
9889 }
9890 }
9891 return restart;
9892 }
9893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009894 // =========================================================
9895 // SERVICES
9896 // =========================================================
9897
9898 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9899 ActivityManager.RunningServiceInfo info =
9900 new ActivityManager.RunningServiceInfo();
9901 info.service = r.name;
9902 if (r.app != null) {
9903 info.pid = r.app.pid;
9904 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009905 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 info.process = r.processName;
9907 info.foreground = r.isForeground;
9908 info.activeSince = r.createTime;
9909 info.started = r.startRequested;
9910 info.clientCount = r.connections.size();
9911 info.crashCount = r.crashCount;
9912 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009913 if (r.isForeground) {
9914 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9915 }
9916 if (r.startRequested) {
9917 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9918 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009919 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009920 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9921 }
9922 if (r.app != null && r.app.persistent) {
9923 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9924 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009925
9926 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9927 for (int i=0; i<connl.size(); i++) {
9928 ConnectionRecord conn = connl.get(i);
9929 if (conn.clientLabel != 0) {
9930 info.clientPackage = conn.binding.client.info.packageName;
9931 info.clientLabel = conn.clientLabel;
9932 return info;
9933 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009934 }
9935 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 return info;
9937 }
9938
9939 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9940 int flags) {
9941 synchronized (this) {
9942 ArrayList<ActivityManager.RunningServiceInfo> res
9943 = new ArrayList<ActivityManager.RunningServiceInfo>();
9944
9945 if (mServices.size() > 0) {
9946 Iterator<ServiceRecord> it = mServices.values().iterator();
9947 while (it.hasNext() && res.size() < maxNum) {
9948 res.add(makeRunningServiceInfoLocked(it.next()));
9949 }
9950 }
9951
9952 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9953 ServiceRecord r = mRestartingServices.get(i);
9954 ActivityManager.RunningServiceInfo info =
9955 makeRunningServiceInfoLocked(r);
9956 info.restarting = r.nextRestartTime;
9957 res.add(info);
9958 }
9959
9960 return res;
9961 }
9962 }
9963
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009964 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9965 synchronized (this) {
9966 ServiceRecord r = mServices.get(name);
9967 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009968 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9969 for (int i=0; i<conn.size(); i++) {
9970 if (conn.get(i).clientIntent != null) {
9971 return conn.get(i).clientIntent;
9972 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009973 }
9974 }
9975 }
9976 }
9977 return null;
9978 }
9979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009980 private final ServiceRecord findServiceLocked(ComponentName name,
9981 IBinder token) {
9982 ServiceRecord r = mServices.get(name);
9983 return r == token ? r : null;
9984 }
9985
9986 private final class ServiceLookupResult {
9987 final ServiceRecord record;
9988 final String permission;
9989
9990 ServiceLookupResult(ServiceRecord _record, String _permission) {
9991 record = _record;
9992 permission = _permission;
9993 }
9994 };
9995
9996 private ServiceLookupResult findServiceLocked(Intent service,
9997 String resolvedType) {
9998 ServiceRecord r = null;
9999 if (service.getComponent() != null) {
10000 r = mServices.get(service.getComponent());
10001 }
10002 if (r == null) {
10003 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10004 r = mServicesByIntent.get(filter);
10005 }
10006
10007 if (r == null) {
10008 try {
10009 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010010 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010011 service, resolvedType, 0);
10012 ServiceInfo sInfo =
10013 rInfo != null ? rInfo.serviceInfo : null;
10014 if (sInfo == null) {
10015 return null;
10016 }
10017
10018 ComponentName name = new ComponentName(
10019 sInfo.applicationInfo.packageName, sInfo.name);
10020 r = mServices.get(name);
10021 } catch (RemoteException ex) {
10022 // pm is in same process, this will never happen.
10023 }
10024 }
10025 if (r != null) {
10026 int callingPid = Binder.getCallingPid();
10027 int callingUid = Binder.getCallingUid();
10028 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010029 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010030 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010031 if (!r.exported) {
10032 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10033 + " from pid=" + callingPid
10034 + ", uid=" + callingUid
10035 + " that is not exported from uid " + r.appInfo.uid);
10036 return new ServiceLookupResult(null, "not exported from uid "
10037 + r.appInfo.uid);
10038 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010039 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010040 + " from pid=" + callingPid
10041 + ", uid=" + callingUid
10042 + " requires " + r.permission);
10043 return new ServiceLookupResult(null, r.permission);
10044 }
10045 return new ServiceLookupResult(r, null);
10046 }
10047 return null;
10048 }
10049
10050 private class ServiceRestarter implements Runnable {
10051 private ServiceRecord mService;
10052
10053 void setService(ServiceRecord service) {
10054 mService = service;
10055 }
10056
10057 public void run() {
10058 synchronized(ActivityManagerService.this) {
10059 performServiceRestartLocked(mService);
10060 }
10061 }
10062 }
10063
10064 private ServiceLookupResult retrieveServiceLocked(Intent service,
10065 String resolvedType, int callingPid, int callingUid) {
10066 ServiceRecord r = null;
10067 if (service.getComponent() != null) {
10068 r = mServices.get(service.getComponent());
10069 }
10070 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10071 r = mServicesByIntent.get(filter);
10072 if (r == null) {
10073 try {
10074 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010075 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010076 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 ServiceInfo sInfo =
10078 rInfo != null ? rInfo.serviceInfo : null;
10079 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010080 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081 ": not found");
10082 return null;
10083 }
10084
10085 ComponentName name = new ComponentName(
10086 sInfo.applicationInfo.packageName, sInfo.name);
10087 r = mServices.get(name);
10088 if (r == null) {
10089 filter = new Intent.FilterComparison(service.cloneFilter());
10090 ServiceRestarter res = new ServiceRestarter();
10091 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10092 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10093 synchronized (stats) {
10094 ss = stats.getServiceStatsLocked(
10095 sInfo.applicationInfo.uid, sInfo.packageName,
10096 sInfo.name);
10097 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010098 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010099 res.setService(r);
10100 mServices.put(name, r);
10101 mServicesByIntent.put(filter, r);
10102
10103 // Make sure this component isn't in the pending list.
10104 int N = mPendingServices.size();
10105 for (int i=0; i<N; i++) {
10106 ServiceRecord pr = mPendingServices.get(i);
10107 if (pr.name.equals(name)) {
10108 mPendingServices.remove(i);
10109 i--;
10110 N--;
10111 }
10112 }
10113 }
10114 } catch (RemoteException ex) {
10115 // pm is in same process, this will never happen.
10116 }
10117 }
10118 if (r != null) {
10119 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010120 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010122 if (!r.exported) {
10123 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10124 + " from pid=" + callingPid
10125 + ", uid=" + callingUid
10126 + " that is not exported from uid " + r.appInfo.uid);
10127 return new ServiceLookupResult(null, "not exported from uid "
10128 + r.appInfo.uid);
10129 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010130 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010131 + " from pid=" + callingPid
10132 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010133 + " requires " + r.permission);
10134 return new ServiceLookupResult(null, r.permission);
10135 }
10136 return new ServiceLookupResult(r, null);
10137 }
10138 return null;
10139 }
10140
Dianne Hackborn287952c2010-09-22 22:34:31 -070010141 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10142 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10143 + why + " of " + r + " in app " + r.app);
10144 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10145 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010146 long now = SystemClock.uptimeMillis();
10147 if (r.executeNesting == 0 && r.app != null) {
10148 if (r.app.executingServices.size() == 0) {
10149 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10150 msg.obj = r.app;
10151 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10152 }
10153 r.app.executingServices.add(r);
10154 }
10155 r.executeNesting++;
10156 r.executingStart = now;
10157 }
10158
10159 private final void sendServiceArgsLocked(ServiceRecord r,
10160 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010161 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010162 if (N == 0) {
10163 return;
10164 }
10165
Dianne Hackborn39792d22010-08-19 18:01:52 -070010166 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010168 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010169 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10170 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010171 if (si.intent == null && N > 1) {
10172 // If somehow we got a dummy null intent in the middle,
10173 // then skip it. DO NOT skip a null intent when it is
10174 // the only one in the list -- this is to support the
10175 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010176 continue;
10177 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010178 si.deliveredTime = SystemClock.uptimeMillis();
10179 r.deliveredStarts.add(si);
10180 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010181 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010182 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010183 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010184 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010185 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010186 if (!oomAdjusted) {
10187 oomAdjusted = true;
10188 updateOomAdjLocked(r.app);
10189 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010190 int flags = 0;
10191 if (si.deliveryCount > 0) {
10192 flags |= Service.START_FLAG_RETRY;
10193 }
10194 if (si.doneExecutingCount > 0) {
10195 flags |= Service.START_FLAG_REDELIVERY;
10196 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010197 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010198 } catch (RemoteException e) {
10199 // Remote process gone... we'll let the normal cleanup take
10200 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010201 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010202 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010203 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010204 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010205 break;
10206 }
10207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 }
10209
10210 private final boolean requestServiceBindingLocked(ServiceRecord r,
10211 IntentBindRecord i, boolean rebind) {
10212 if (r.app == null || r.app.thread == null) {
10213 // If service is not currently running, can't yet bind.
10214 return false;
10215 }
10216 if ((!i.requested || rebind) && i.apps.size() > 0) {
10217 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010218 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10220 if (!rebind) {
10221 i.requested = true;
10222 }
10223 i.hasBound = true;
10224 i.doRebind = false;
10225 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010226 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010227 return false;
10228 }
10229 }
10230 return true;
10231 }
10232
10233 private final void requestServiceBindingsLocked(ServiceRecord r) {
10234 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10235 while (bindings.hasNext()) {
10236 IntentBindRecord i = bindings.next();
10237 if (!requestServiceBindingLocked(r, i, false)) {
10238 break;
10239 }
10240 }
10241 }
10242
10243 private final void realStartServiceLocked(ServiceRecord r,
10244 ProcessRecord app) throws RemoteException {
10245 if (app.thread == null) {
10246 throw new RemoteException();
10247 }
10248
10249 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010250 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010251
10252 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010253 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010254 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010255
10256 boolean created = false;
10257 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010258 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010259 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010260 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010262 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010263 synchronized (r.stats.getBatteryStats()) {
10264 r.stats.startLaunchedLocked();
10265 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010266 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010267 app.thread.scheduleCreateService(r, r.serviceInfo,
10268 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010269 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010270 created = true;
10271 } finally {
10272 if (!created) {
10273 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010274 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 }
10276 }
10277
10278 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010279
10280 // If the service is in the started state, and there are no
10281 // pending arguments, then fake up one so its onStartCommand() will
10282 // be called.
10283 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010284 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10285 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010286 }
10287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 sendServiceArgsLocked(r, true);
10289 }
10290
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010291 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10292 boolean allowCancel) {
10293 boolean canceled = false;
10294
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010295 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010296 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010297 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010298
Dianne Hackborn070783f2010-12-29 16:46:28 -080010299 if ((r.serviceInfo.applicationInfo.flags
10300 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10301 minDuration /= 4;
10302 }
10303
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010304 // Any delivered but not yet finished starts should be put back
10305 // on the pending list.
10306 final int N = r.deliveredStarts.size();
10307 if (N > 0) {
10308 for (int i=N-1; i>=0; i--) {
10309 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010310 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010311 if (si.intent == null) {
10312 // We'll generate this again if needed.
10313 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10314 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10315 r.pendingStarts.add(0, si);
10316 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10317 dur *= 2;
10318 if (minDuration < dur) minDuration = dur;
10319 if (resetTime < dur) resetTime = dur;
10320 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010321 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010322 + r.name);
10323 canceled = true;
10324 }
10325 }
10326 r.deliveredStarts.clear();
10327 }
10328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010329 r.totalRestartCount++;
10330 if (r.restartDelay == 0) {
10331 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010332 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010333 } else {
10334 // If it has been a "reasonably long time" since the service
10335 // was started, then reset our restart duration back to
10336 // the beginning, so we don't infinitely increase the duration
10337 // on a service that just occasionally gets killed (which is
10338 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010339 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010340 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010341 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010342 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010343 if ((r.serviceInfo.applicationInfo.flags
10344 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10345 // Services in peristent processes will restart much more
10346 // quickly, since they are pretty important. (Think SystemUI).
10347 r.restartDelay += minDuration/2;
10348 } else {
10349 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10350 if (r.restartDelay < minDuration) {
10351 r.restartDelay = minDuration;
10352 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010354 }
10355 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010356
10357 r.nextRestartTime = now + r.restartDelay;
10358
10359 // Make sure that we don't end up restarting a bunch of services
10360 // all at the same time.
10361 boolean repeat;
10362 do {
10363 repeat = false;
10364 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10365 ServiceRecord r2 = mRestartingServices.get(i);
10366 if (r2 != r && r.nextRestartTime
10367 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10368 && r.nextRestartTime
10369 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10370 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10371 r.restartDelay = r.nextRestartTime - now;
10372 repeat = true;
10373 break;
10374 }
10375 }
10376 } while (repeat);
10377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378 if (!mRestartingServices.contains(r)) {
10379 mRestartingServices.add(r);
10380 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010381
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010382 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010384 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010385 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010386 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010387 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010388 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010389 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010390 r.shortName, r.restartDelay);
10391
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010392 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010393 }
10394
10395 final void performServiceRestartLocked(ServiceRecord r) {
10396 if (!mRestartingServices.contains(r)) {
10397 return;
10398 }
10399 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10400 }
10401
10402 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10403 if (r.restartDelay == 0) {
10404 return false;
10405 }
10406 r.resetRestartCounter();
10407 mRestartingServices.remove(r);
10408 mHandler.removeCallbacks(r.restarter);
10409 return true;
10410 }
10411
10412 private final boolean bringUpServiceLocked(ServiceRecord r,
10413 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010414 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010415 //r.dump(" ");
10416
Dianne Hackborn36124872009-10-08 16:22:03 -070010417 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010418 sendServiceArgsLocked(r, false);
10419 return true;
10420 }
10421
10422 if (!whileRestarting && r.restartDelay > 0) {
10423 // If waiting for a restart, then do nothing.
10424 return true;
10425 }
10426
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010427 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010428
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010429 // We are now bringing the service up, so no longer in the
10430 // restarting state.
10431 mRestartingServices.remove(r);
10432
Dianne Hackborne7f97212011-02-24 14:40:20 -080010433 // Service is now being launched, its package can't be stopped.
10434 try {
10435 AppGlobals.getPackageManager().setPackageStoppedState(
10436 r.packageName, false);
10437 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010438 } catch (IllegalArgumentException e) {
10439 Slog.w(TAG, "Failed trying to unstop package "
10440 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010441 }
10442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443 final String appName = r.processName;
10444 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10445 if (app != null && app.thread != null) {
10446 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010447 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010448 realStartServiceLocked(r, app);
10449 return true;
10450 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 }
10453
10454 // If a dead object exception was thrown -- fall through to
10455 // restart the application.
10456 }
10457
Dianne Hackborn36124872009-10-08 16:22:03 -070010458 // Not running -- get it started, and enqueue this service record
10459 // to be executed when the app comes up.
10460 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10461 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010462 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010463 + r.appInfo.packageName + "/"
10464 + r.appInfo.uid + " for service "
10465 + r.intent.getIntent() + ": process is bad");
10466 bringDownServiceLocked(r, true);
10467 return false;
10468 }
10469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010470 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 mPendingServices.add(r);
10472 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010474 return true;
10475 }
10476
10477 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010478 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010479 //r.dump(" ");
10480
10481 // Does it still need to run?
10482 if (!force && r.startRequested) {
10483 return;
10484 }
10485 if (r.connections.size() > 0) {
10486 if (!force) {
10487 // XXX should probably keep a count of the number of auto-create
10488 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010489 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010491 ArrayList<ConnectionRecord> cr = it.next();
10492 for (int i=0; i<cr.size(); i++) {
10493 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10494 return;
10495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010496 }
10497 }
10498 }
10499
10500 // Report to all of the connections that the service is no longer
10501 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010502 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010503 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010504 ArrayList<ConnectionRecord> c = it.next();
10505 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010506 ConnectionRecord cr = c.get(i);
10507 // There is still a connection to the service that is
10508 // being brought down. Mark it as dead.
10509 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010510 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010511 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010512 } catch (Exception e) {
10513 Slog.w(TAG, "Failure disconnecting service " + r.name +
10514 " to connection " + c.get(i).conn.asBinder() +
10515 " (in " + c.get(i).binding.client.processName + ")", e);
10516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010517 }
10518 }
10519 }
10520
10521 // Tell the service that it has been unbound.
10522 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10523 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10524 while (it.hasNext()) {
10525 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010526 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 + ": hasBound=" + ibr.hasBound);
10528 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10529 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010530 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010531 updateOomAdjLocked(r.app);
10532 ibr.hasBound = false;
10533 r.app.thread.scheduleUnbindService(r,
10534 ibr.intent.getIntent());
10535 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010536 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010537 + r.shortName, e);
10538 serviceDoneExecutingLocked(r, true);
10539 }
10540 }
10541 }
10542 }
10543
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010544 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010545 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546 System.identityHashCode(r), r.shortName,
10547 (r.app != null) ? r.app.pid : -1);
10548
10549 mServices.remove(r.name);
10550 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010551 r.totalRestartCount = 0;
10552 unscheduleServiceRestartLocked(r);
10553
10554 // Also make sure it is not on the pending list.
10555 int N = mPendingServices.size();
10556 for (int i=0; i<N; i++) {
10557 if (mPendingServices.get(i) == r) {
10558 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010559 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010560 i--;
10561 N--;
10562 }
10563 }
10564
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010565 r.cancelNotification();
10566 r.isForeground = false;
10567 r.foregroundId = 0;
10568 r.foregroundNoti = null;
10569
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010570 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010571 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010572 r.pendingStarts.clear();
10573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010574 if (r.app != null) {
10575 synchronized (r.stats.getBatteryStats()) {
10576 r.stats.stopLaunchedLocked();
10577 }
10578 r.app.services.remove(r);
10579 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010580 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010581 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010582 mStoppingServices.add(r);
10583 updateOomAdjLocked(r.app);
10584 r.app.thread.scheduleStopService(r);
10585 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010586 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010587 + r.shortName, e);
10588 serviceDoneExecutingLocked(r, true);
10589 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010590 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010591 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010592 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010593 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010594 }
10595 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010596 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010597 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010598 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010599
10600 if (r.bindings.size() > 0) {
10601 r.bindings.clear();
10602 }
10603
10604 if (r.restarter instanceof ServiceRestarter) {
10605 ((ServiceRestarter)r.restarter).setService(null);
10606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010607 }
10608
10609 ComponentName startServiceLocked(IApplicationThread caller,
10610 Intent service, String resolvedType,
10611 int callingPid, int callingUid) {
10612 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010613 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010614 + " type=" + resolvedType + " args=" + service.getExtras());
10615
10616 if (caller != null) {
10617 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10618 if (callerApp == null) {
10619 throw new SecurityException(
10620 "Unable to find app for caller " + caller
10621 + " (pid=" + Binder.getCallingPid()
10622 + ") when starting service " + service);
10623 }
10624 }
10625
10626 ServiceLookupResult res =
10627 retrieveServiceLocked(service, resolvedType,
10628 callingPid, callingUid);
10629 if (res == null) {
10630 return null;
10631 }
10632 if (res.record == null) {
10633 return new ComponentName("!", res.permission != null
10634 ? res.permission : "private to package");
10635 }
10636 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010637 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10638 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010639 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010640 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010641 }
10642 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010643 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010644 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010645 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 r.lastActivity = SystemClock.uptimeMillis();
10647 synchronized (r.stats.getBatteryStats()) {
10648 r.stats.startRunningLocked();
10649 }
10650 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10651 return new ComponentName("!", "Service process is bad");
10652 }
10653 return r.name;
10654 }
10655 }
10656
10657 public ComponentName startService(IApplicationThread caller, Intent service,
10658 String resolvedType) {
10659 // Refuse possible leaked file descriptors
10660 if (service != null && service.hasFileDescriptors() == true) {
10661 throw new IllegalArgumentException("File descriptors passed in Intent");
10662 }
10663
10664 synchronized(this) {
10665 final int callingPid = Binder.getCallingPid();
10666 final int callingUid = Binder.getCallingUid();
10667 final long origId = Binder.clearCallingIdentity();
10668 ComponentName res = startServiceLocked(caller, service,
10669 resolvedType, callingPid, callingUid);
10670 Binder.restoreCallingIdentity(origId);
10671 return res;
10672 }
10673 }
10674
10675 ComponentName startServiceInPackage(int uid,
10676 Intent service, String resolvedType) {
10677 synchronized(this) {
10678 final long origId = Binder.clearCallingIdentity();
10679 ComponentName res = startServiceLocked(null, service,
10680 resolvedType, -1, uid);
10681 Binder.restoreCallingIdentity(origId);
10682 return res;
10683 }
10684 }
10685
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010686 private void stopServiceLocked(ServiceRecord service) {
10687 synchronized (service.stats.getBatteryStats()) {
10688 service.stats.stopRunningLocked();
10689 }
10690 service.startRequested = false;
10691 service.callStart = false;
10692 bringDownServiceLocked(service, false);
10693 }
10694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010695 public int stopService(IApplicationThread caller, Intent service,
10696 String resolvedType) {
10697 // Refuse possible leaked file descriptors
10698 if (service != null && service.hasFileDescriptors() == true) {
10699 throw new IllegalArgumentException("File descriptors passed in Intent");
10700 }
10701
10702 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010703 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010704 + " type=" + resolvedType);
10705
10706 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10707 if (caller != null && callerApp == null) {
10708 throw new SecurityException(
10709 "Unable to find app for caller " + caller
10710 + " (pid=" + Binder.getCallingPid()
10711 + ") when stopping service " + service);
10712 }
10713
10714 // If this service is active, make sure it is stopped.
10715 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10716 if (r != null) {
10717 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010718 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010719 try {
10720 stopServiceLocked(r.record);
10721 } finally {
10722 Binder.restoreCallingIdentity(origId);
10723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 return 1;
10725 }
10726 return -1;
10727 }
10728 }
10729
10730 return 0;
10731 }
10732
10733 public IBinder peekService(Intent service, String resolvedType) {
10734 // Refuse possible leaked file descriptors
10735 if (service != null && service.hasFileDescriptors() == true) {
10736 throw new IllegalArgumentException("File descriptors passed in Intent");
10737 }
10738
10739 IBinder ret = null;
10740
10741 synchronized(this) {
10742 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10743
10744 if (r != null) {
10745 // r.record is null if findServiceLocked() failed the caller permission check
10746 if (r.record == null) {
10747 throw new SecurityException(
10748 "Permission Denial: Accessing service " + r.record.name
10749 + " from pid=" + Binder.getCallingPid()
10750 + ", uid=" + Binder.getCallingUid()
10751 + " requires " + r.permission);
10752 }
10753 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10754 if (ib != null) {
10755 ret = ib.binder;
10756 }
10757 }
10758 }
10759
10760 return ret;
10761 }
10762
10763 public boolean stopServiceToken(ComponentName className, IBinder token,
10764 int startId) {
10765 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010766 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 + " " + token + " startId=" + startId);
10768 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010769 if (r != null) {
10770 if (startId >= 0) {
10771 // Asked to only stop if done with all work. Note that
10772 // to avoid leaks, we will take this as dropping all
10773 // start items up to and including this one.
10774 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10775 if (si != null) {
10776 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010777 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10778 cur.removeUriPermissionsLocked();
10779 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010780 break;
10781 }
10782 }
10783 }
10784
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010785 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010786 return false;
10787 }
10788
10789 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010790 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010791 + " is last, but have " + r.deliveredStarts.size()
10792 + " remaining args");
10793 }
10794 }
10795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 synchronized (r.stats.getBatteryStats()) {
10797 r.stats.stopRunningLocked();
10798 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010799 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 }
10801 final long origId = Binder.clearCallingIdentity();
10802 bringDownServiceLocked(r, false);
10803 Binder.restoreCallingIdentity(origId);
10804 return true;
10805 }
10806 }
10807 return false;
10808 }
10809
10810 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010811 int id, Notification notification, boolean removeNotification) {
10812 final long origId = Binder.clearCallingIdentity();
10813 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010814 synchronized(this) {
10815 ServiceRecord r = findServiceLocked(className, token);
10816 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010817 if (id != 0) {
10818 if (notification == null) {
10819 throw new IllegalArgumentException("null notification");
10820 }
10821 if (r.foregroundId != id) {
10822 r.cancelNotification();
10823 r.foregroundId = id;
10824 }
10825 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10826 r.foregroundNoti = notification;
10827 r.isForeground = true;
10828 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 if (r.app != null) {
10830 updateServiceForegroundLocked(r.app, true);
10831 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010832 } else {
10833 if (r.isForeground) {
10834 r.isForeground = false;
10835 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010836 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010837 updateServiceForegroundLocked(r.app, true);
10838 }
10839 }
10840 if (removeNotification) {
10841 r.cancelNotification();
10842 r.foregroundId = 0;
10843 r.foregroundNoti = null;
10844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845 }
10846 }
10847 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010848 } finally {
10849 Binder.restoreCallingIdentity(origId);
10850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 }
10852
10853 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10854 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010855 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010856 if (sr.isForeground) {
10857 anyForeground = true;
10858 break;
10859 }
10860 }
10861 if (anyForeground != proc.foregroundServices) {
10862 proc.foregroundServices = anyForeground;
10863 if (oomAdj) {
10864 updateOomAdjLocked();
10865 }
10866 }
10867 }
10868
10869 public int bindService(IApplicationThread caller, IBinder token,
10870 Intent service, String resolvedType,
10871 IServiceConnection connection, int flags) {
10872 // Refuse possible leaked file descriptors
10873 if (service != null && service.hasFileDescriptors() == true) {
10874 throw new IllegalArgumentException("File descriptors passed in Intent");
10875 }
10876
10877 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010878 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010879 + " type=" + resolvedType + " conn=" + connection.asBinder()
10880 + " flags=0x" + Integer.toHexString(flags));
10881 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10882 if (callerApp == null) {
10883 throw new SecurityException(
10884 "Unable to find app for caller " + caller
10885 + " (pid=" + Binder.getCallingPid()
10886 + ") when binding service " + service);
10887 }
10888
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010889 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010890 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010891 activity = mMainStack.isInStackLocked(token);
10892 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010893 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010894 return 0;
10895 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896 }
10897
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010898 int clientLabel = 0;
10899 PendingIntent clientIntent = null;
10900
10901 if (callerApp.info.uid == Process.SYSTEM_UID) {
10902 // Hacky kind of thing -- allow system stuff to tell us
10903 // what they are, so we can report this elsewhere for
10904 // others to know why certain services are running.
10905 try {
10906 clientIntent = (PendingIntent)service.getParcelableExtra(
10907 Intent.EXTRA_CLIENT_INTENT);
10908 } catch (RuntimeException e) {
10909 }
10910 if (clientIntent != null) {
10911 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10912 if (clientLabel != 0) {
10913 // There are no useful extras in the intent, trash them.
10914 // System code calling with this stuff just needs to know
10915 // this will happen.
10916 service = service.cloneFilter();
10917 }
10918 }
10919 }
10920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010921 ServiceLookupResult res =
10922 retrieveServiceLocked(service, resolvedType,
10923 Binder.getCallingPid(), Binder.getCallingUid());
10924 if (res == null) {
10925 return 0;
10926 }
10927 if (res.record == null) {
10928 return -1;
10929 }
10930 ServiceRecord s = res.record;
10931
10932 final long origId = Binder.clearCallingIdentity();
10933
10934 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010935 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010936 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010937 }
10938
10939 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10940 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010941 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010942
10943 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010944 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10945 if (clist == null) {
10946 clist = new ArrayList<ConnectionRecord>();
10947 s.connections.put(binder, clist);
10948 }
10949 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010950 b.connections.add(c);
10951 if (activity != null) {
10952 if (activity.connections == null) {
10953 activity.connections = new HashSet<ConnectionRecord>();
10954 }
10955 activity.connections.add(c);
10956 }
10957 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010958 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10959 b.client.hasAboveClient = true;
10960 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010961 clist = mServiceConnections.get(binder);
10962 if (clist == null) {
10963 clist = new ArrayList<ConnectionRecord>();
10964 mServiceConnections.put(binder, clist);
10965 }
10966 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967
10968 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10969 s.lastActivity = SystemClock.uptimeMillis();
10970 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10971 return 0;
10972 }
10973 }
10974
10975 if (s.app != null) {
10976 // This could have made the service more important.
10977 updateOomAdjLocked(s.app);
10978 }
10979
Joe Onorato8a9b2202010-02-26 18:56:32 -080010980 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010981 + ": received=" + b.intent.received
10982 + " apps=" + b.intent.apps.size()
10983 + " doRebind=" + b.intent.doRebind);
10984
10985 if (s.app != null && b.intent.received) {
10986 // Service is already running, so we can immediately
10987 // publish the connection.
10988 try {
10989 c.conn.connected(s.name, b.intent.binder);
10990 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010991 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 + " to connection " + c.conn.asBinder()
10993 + " (in " + c.binding.client.processName + ")", e);
10994 }
10995
10996 // If this is the first app connected back to this binding,
10997 // and the service had previously asked to be told when
10998 // rebound, then do so.
10999 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11000 requestServiceBindingLocked(s, b.intent, true);
11001 }
11002 } else if (!b.intent.requested) {
11003 requestServiceBindingLocked(s, b.intent, false);
11004 }
11005
11006 Binder.restoreCallingIdentity(origId);
11007 }
11008
11009 return 1;
11010 }
11011
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011012 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011013 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011014 IBinder binder = c.conn.asBinder();
11015 AppBindRecord b = c.binding;
11016 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011017 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11018 if (clist != null) {
11019 clist.remove(c);
11020 if (clist.size() == 0) {
11021 s.connections.remove(binder);
11022 }
11023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 b.connections.remove(c);
11025 if (c.activity != null && c.activity != skipAct) {
11026 if (c.activity.connections != null) {
11027 c.activity.connections.remove(c);
11028 }
11029 }
11030 if (b.client != skipApp) {
11031 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011032 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11033 b.client.updateHasAboveClientLocked();
11034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011036 clist = mServiceConnections.get(binder);
11037 if (clist != null) {
11038 clist.remove(c);
11039 if (clist.size() == 0) {
11040 mServiceConnections.remove(binder);
11041 }
11042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011043
11044 if (b.connections.size() == 0) {
11045 b.intent.apps.remove(b.client);
11046 }
11047
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011048 if (!c.serviceDead) {
11049 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11050 + ": shouldUnbind=" + b.intent.hasBound);
11051 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11052 && b.intent.hasBound) {
11053 try {
11054 bumpServiceExecutingLocked(s, "unbind");
11055 updateOomAdjLocked(s.app);
11056 b.intent.hasBound = false;
11057 // Assume the client doesn't want to know about a rebind;
11058 // we will deal with that later if it asks for one.
11059 b.intent.doRebind = false;
11060 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11061 } catch (Exception e) {
11062 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11063 serviceDoneExecutingLocked(s, true);
11064 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011066
11067 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11068 bringDownServiceLocked(s, false);
11069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011070 }
11071 }
11072
11073 public boolean unbindService(IServiceConnection connection) {
11074 synchronized (this) {
11075 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011076 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011077 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11078 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011079 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 + connection.asBinder());
11081 return false;
11082 }
11083
11084 final long origId = Binder.clearCallingIdentity();
11085
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011086 while (clist.size() > 0) {
11087 ConnectionRecord r = clist.get(0);
11088 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011090 if (r.binding.service.app != null) {
11091 // This could have made the service less important.
11092 updateOomAdjLocked(r.binding.service.app);
11093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011094 }
11095
11096 Binder.restoreCallingIdentity(origId);
11097 }
11098
11099 return true;
11100 }
11101
11102 public void publishService(IBinder token, Intent intent, IBinder service) {
11103 // Refuse possible leaked file descriptors
11104 if (intent != null && intent.hasFileDescriptors() == true) {
11105 throw new IllegalArgumentException("File descriptors passed in Intent");
11106 }
11107
11108 synchronized(this) {
11109 if (!(token instanceof ServiceRecord)) {
11110 throw new IllegalArgumentException("Invalid service token");
11111 }
11112 ServiceRecord r = (ServiceRecord)token;
11113
11114 final long origId = Binder.clearCallingIdentity();
11115
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011116 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011117 + " " + intent + ": " + service);
11118 if (r != null) {
11119 Intent.FilterComparison filter
11120 = new Intent.FilterComparison(intent);
11121 IntentBindRecord b = r.bindings.get(filter);
11122 if (b != null && !b.received) {
11123 b.binder = service;
11124 b.requested = true;
11125 b.received = true;
11126 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011127 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128 = r.connections.values().iterator();
11129 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011130 ArrayList<ConnectionRecord> clist = it.next();
11131 for (int i=0; i<clist.size(); i++) {
11132 ConnectionRecord c = clist.get(i);
11133 if (!filter.equals(c.binding.intent.intent)) {
11134 if (DEBUG_SERVICE) Slog.v(
11135 TAG, "Not publishing to: " + c);
11136 if (DEBUG_SERVICE) Slog.v(
11137 TAG, "Bound intent: " + c.binding.intent.intent);
11138 if (DEBUG_SERVICE) Slog.v(
11139 TAG, "Published intent: " + intent);
11140 continue;
11141 }
11142 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11143 try {
11144 c.conn.connected(r.name, service);
11145 } catch (Exception e) {
11146 Slog.w(TAG, "Failure sending service " + r.name +
11147 " to connection " + c.conn.asBinder() +
11148 " (in " + c.binding.client.processName + ")", e);
11149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011150 }
11151 }
11152 }
11153 }
11154
11155 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11156
11157 Binder.restoreCallingIdentity(origId);
11158 }
11159 }
11160 }
11161
11162 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11163 // Refuse possible leaked file descriptors
11164 if (intent != null && intent.hasFileDescriptors() == true) {
11165 throw new IllegalArgumentException("File descriptors passed in Intent");
11166 }
11167
11168 synchronized(this) {
11169 if (!(token instanceof ServiceRecord)) {
11170 throw new IllegalArgumentException("Invalid service token");
11171 }
11172 ServiceRecord r = (ServiceRecord)token;
11173
11174 final long origId = Binder.clearCallingIdentity();
11175
11176 if (r != null) {
11177 Intent.FilterComparison filter
11178 = new Intent.FilterComparison(intent);
11179 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011180 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 + " at " + b + ": apps="
11182 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011183
11184 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011185 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011186 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011187 // Applications have already bound since the last
11188 // unbind, so just rebind right here.
11189 requestServiceBindingLocked(r, b, true);
11190 } else {
11191 // Note to tell the service the next time there is
11192 // a new client.
11193 b.doRebind = true;
11194 }
11195 }
11196
Per Edelberg78f9fff2010-08-30 20:01:35 +020011197 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011198
11199 Binder.restoreCallingIdentity(origId);
11200 }
11201 }
11202 }
11203
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011204 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011205 synchronized(this) {
11206 if (!(token instanceof ServiceRecord)) {
11207 throw new IllegalArgumentException("Invalid service token");
11208 }
11209 ServiceRecord r = (ServiceRecord)token;
11210 boolean inStopping = mStoppingServices.contains(token);
11211 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011212 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011213 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 + " with incorrect token: given " + token
11215 + ", expected " + r);
11216 return;
11217 }
11218
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011219 if (type == 1) {
11220 // This is a call from a service start... take care of
11221 // book-keeping.
11222 r.callStart = true;
11223 switch (res) {
11224 case Service.START_STICKY_COMPATIBILITY:
11225 case Service.START_STICKY: {
11226 // We are done with the associated start arguments.
11227 r.findDeliveredStart(startId, true);
11228 // Don't stop if killed.
11229 r.stopIfKilled = false;
11230 break;
11231 }
11232 case Service.START_NOT_STICKY: {
11233 // We are done with the associated start arguments.
11234 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011235 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011236 // There is no more work, and this service
11237 // doesn't want to hang around if killed.
11238 r.stopIfKilled = true;
11239 }
11240 break;
11241 }
11242 case Service.START_REDELIVER_INTENT: {
11243 // We'll keep this item until they explicitly
11244 // call stop for it, but keep track of the fact
11245 // that it was delivered.
11246 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11247 if (si != null) {
11248 si.deliveryCount = 0;
11249 si.doneExecutingCount++;
11250 // Don't stop if killed.
11251 r.stopIfKilled = true;
11252 }
11253 break;
11254 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011255 case Service.START_TASK_REMOVED_COMPLETE: {
11256 // Special processing for onTaskRemoved(). Don't
11257 // impact normal onStartCommand() processing.
11258 r.findDeliveredStart(startId, true);
11259 break;
11260 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011261 default:
11262 throw new IllegalArgumentException(
11263 "Unknown service start result: " + res);
11264 }
11265 if (res == Service.START_STICKY_COMPATIBILITY) {
11266 r.callStart = false;
11267 }
11268 }
11269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011270 final long origId = Binder.clearCallingIdentity();
11271 serviceDoneExecutingLocked(r, inStopping);
11272 Binder.restoreCallingIdentity(origId);
11273 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011274 Slog.w(TAG, "Done executing unknown service from pid "
11275 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011276 }
11277 }
11278 }
11279
11280 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011281 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11282 + ": nesting=" + r.executeNesting
11283 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011284 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 r.executeNesting--;
11286 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011287 if (DEBUG_SERVICE) Slog.v(TAG,
11288 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011289 r.app.executingServices.remove(r);
11290 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011291 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11292 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011293 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11294 }
11295 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011296 if (DEBUG_SERVICE) Slog.v(TAG,
11297 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011298 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011299 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011300 }
11301 updateOomAdjLocked(r.app);
11302 }
11303 }
11304
11305 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011306 String anrMessage = null;
11307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011308 synchronized(this) {
11309 if (proc.executingServices.size() == 0 || proc.thread == null) {
11310 return;
11311 }
11312 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11313 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11314 ServiceRecord timeout = null;
11315 long nextTime = 0;
11316 while (it.hasNext()) {
11317 ServiceRecord sr = it.next();
11318 if (sr.executingStart < maxTime) {
11319 timeout = sr;
11320 break;
11321 }
11322 if (sr.executingStart > nextTime) {
11323 nextTime = sr.executingStart;
11324 }
11325 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011326 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011327 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011328 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011329 } else {
11330 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11331 msg.obj = proc;
11332 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11333 }
11334 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011335
11336 if (anrMessage != null) {
11337 appNotResponding(proc, null, null, anrMessage);
11338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 }
11340
11341 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011342 // BACKUP AND RESTORE
11343 // =========================================================
11344
11345 // Cause the target app to be launched if necessary and its backup agent
11346 // instantiated. The backup agent will invoke backupAgentCreated() on the
11347 // activity manager to announce its creation.
11348 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011349 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011350 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11351
11352 synchronized(this) {
11353 // !!! TODO: currently no check here that we're already bound
11354 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11355 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11356 synchronized (stats) {
11357 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11358 }
11359
Dianne Hackborne7f97212011-02-24 14:40:20 -080011360 // Backup agent is now in use, its package can't be stopped.
11361 try {
11362 AppGlobals.getPackageManager().setPackageStoppedState(
11363 app.packageName, false);
11364 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011365 } catch (IllegalArgumentException e) {
11366 Slog.w(TAG, "Failed trying to unstop package "
11367 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011368 }
11369
Christopher Tate181fafa2009-05-14 11:12:14 -070011370 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011371 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11372 ? new ComponentName(app.packageName, app.backupAgentName)
11373 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011374 // startProcessLocked() returns existing proc's record if it's already running
11375 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011376 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011377 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011378 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011379 return false;
11380 }
11381
11382 r.app = proc;
11383 mBackupTarget = r;
11384 mBackupAppName = app.packageName;
11385
Christopher Tate6fa95972009-06-05 18:43:55 -070011386 // Try not to kill the process during backup
11387 updateOomAdjLocked(proc);
11388
Christopher Tate181fafa2009-05-14 11:12:14 -070011389 // If the process is already attached, schedule the creation of the backup agent now.
11390 // If it is not yet live, this will be done when it attaches to the framework.
11391 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011392 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011393 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011394 proc.thread.scheduleCreateBackupAgent(app,
11395 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011396 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011397 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011398 }
11399 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011400 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011401 }
11402 // Invariants: at this point, the target app process exists and the application
11403 // is either already running or in the process of coming up. mBackupTarget and
11404 // mBackupAppName describe the app, so that when it binds back to the AM we
11405 // know that it's scheduled for a backup-agent operation.
11406 }
11407
11408 return true;
11409 }
11410
11411 // A backup agent has just come up
11412 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011413 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011414 + " = " + agent);
11415
11416 synchronized(this) {
11417 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011418 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011419 return;
11420 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011421 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011422
Dianne Hackborn06740692010-09-22 22:46:21 -070011423 long oldIdent = Binder.clearCallingIdentity();
11424 try {
11425 IBackupManager bm = IBackupManager.Stub.asInterface(
11426 ServiceManager.getService(Context.BACKUP_SERVICE));
11427 bm.agentConnected(agentPackageName, agent);
11428 } catch (RemoteException e) {
11429 // can't happen; the backup manager service is local
11430 } catch (Exception e) {
11431 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11432 e.printStackTrace();
11433 } finally {
11434 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011435 }
11436 }
11437
11438 // done with this agent
11439 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011440 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011441 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011442 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011443 return;
11444 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011445
11446 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011447 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011448 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011449 return;
11450 }
11451
Christopher Tate181fafa2009-05-14 11:12:14 -070011452 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011453 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011454 return;
11455 }
11456
Christopher Tate6fa95972009-06-05 18:43:55 -070011457 ProcessRecord proc = mBackupTarget.app;
11458 mBackupTarget = null;
11459 mBackupAppName = null;
11460
11461 // Not backing this app up any more; reset its OOM adjustment
11462 updateOomAdjLocked(proc);
11463
Christopher Tatec7b31e32009-06-10 15:49:30 -070011464 // If the app crashed during backup, 'thread' will be null here
11465 if (proc.thread != null) {
11466 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011467 proc.thread.scheduleDestroyBackupAgent(appInfo,
11468 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011469 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011470 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011471 e.printStackTrace();
11472 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011473 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011474 }
11475 }
11476 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011477 // BROADCASTS
11478 // =========================================================
11479
Josh Bartel7f208742010-02-25 11:01:44 -060011480 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011481 List cur) {
11482 final ContentResolver resolver = mContext.getContentResolver();
11483 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11484 if (list == null) {
11485 return cur;
11486 }
11487 int N = list.size();
11488 for (int i=0; i<N; i++) {
11489 Intent intent = list.get(i);
11490 if (filter.match(resolver, intent, true, TAG) >= 0) {
11491 if (cur == null) {
11492 cur = new ArrayList<Intent>();
11493 }
11494 cur.add(intent);
11495 }
11496 }
11497 return cur;
11498 }
11499
11500 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011501 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011502 + mBroadcastsScheduled);
11503
11504 if (mBroadcastsScheduled) {
11505 return;
11506 }
11507 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11508 mBroadcastsScheduled = true;
11509 }
11510
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011511 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011512 IIntentReceiver receiver, IntentFilter filter, String permission) {
11513 synchronized(this) {
11514 ProcessRecord callerApp = null;
11515 if (caller != null) {
11516 callerApp = getRecordForAppLocked(caller);
11517 if (callerApp == null) {
11518 throw new SecurityException(
11519 "Unable to find app for caller " + caller
11520 + " (pid=" + Binder.getCallingPid()
11521 + ") when registering receiver " + receiver);
11522 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011523 if (callerApp.info.uid != Process.SYSTEM_UID &&
11524 !callerApp.pkgList.contains(callerPackage)) {
11525 throw new SecurityException("Given caller package " + callerPackage
11526 + " is not running in process " + callerApp);
11527 }
11528 } else {
11529 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011530 }
11531
11532 List allSticky = null;
11533
11534 // Look for any matching sticky broadcasts...
11535 Iterator actions = filter.actionsIterator();
11536 if (actions != null) {
11537 while (actions.hasNext()) {
11538 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011539 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011540 }
11541 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011542 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011543 }
11544
11545 // The first sticky in the list is returned directly back to
11546 // the client.
11547 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11548
Joe Onorato8a9b2202010-02-26 18:56:32 -080011549 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 + ": " + sticky);
11551
11552 if (receiver == null) {
11553 return sticky;
11554 }
11555
11556 ReceiverList rl
11557 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11558 if (rl == null) {
11559 rl = new ReceiverList(this, callerApp,
11560 Binder.getCallingPid(),
11561 Binder.getCallingUid(), receiver);
11562 if (rl.app != null) {
11563 rl.app.receivers.add(rl);
11564 } else {
11565 try {
11566 receiver.asBinder().linkToDeath(rl, 0);
11567 } catch (RemoteException e) {
11568 return sticky;
11569 }
11570 rl.linkedToDeath = true;
11571 }
11572 mRegisteredReceivers.put(receiver.asBinder(), rl);
11573 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011574 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011575 rl.add(bf);
11576 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011577 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011578 }
11579 mReceiverResolver.addFilter(bf);
11580
11581 // Enqueue broadcasts for all existing stickies that match
11582 // this filter.
11583 if (allSticky != null) {
11584 ArrayList receivers = new ArrayList();
11585 receivers.add(bf);
11586
11587 int N = allSticky.size();
11588 for (int i=0; i<N; i++) {
11589 Intent intent = (Intent)allSticky.get(i);
11590 BroadcastRecord r = new BroadcastRecord(intent, null,
11591 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011592 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011593 if (mParallelBroadcasts.size() == 0) {
11594 scheduleBroadcastsLocked();
11595 }
11596 mParallelBroadcasts.add(r);
11597 }
11598 }
11599
11600 return sticky;
11601 }
11602 }
11603
11604 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011605 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011606
11607 boolean doNext = false;
11608
11609 synchronized(this) {
11610 ReceiverList rl
11611 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11612 if (rl != null) {
11613 if (rl.curBroadcast != null) {
11614 BroadcastRecord r = rl.curBroadcast;
11615 doNext = finishReceiverLocked(
11616 receiver.asBinder(), r.resultCode, r.resultData,
11617 r.resultExtras, r.resultAbort, true);
11618 }
11619
11620 if (rl.app != null) {
11621 rl.app.receivers.remove(rl);
11622 }
11623 removeReceiverLocked(rl);
11624 if (rl.linkedToDeath) {
11625 rl.linkedToDeath = false;
11626 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11627 }
11628 }
11629 }
11630
11631 if (!doNext) {
11632 return;
11633 }
11634
11635 final long origId = Binder.clearCallingIdentity();
11636 processNextBroadcast(false);
11637 trimApplications();
11638 Binder.restoreCallingIdentity(origId);
11639 }
11640
11641 void removeReceiverLocked(ReceiverList rl) {
11642 mRegisteredReceivers.remove(rl.receiver.asBinder());
11643 int N = rl.size();
11644 for (int i=0; i<N; i++) {
11645 mReceiverResolver.removeFilter(rl.get(i));
11646 }
11647 }
11648
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011649 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11650 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11651 ProcessRecord r = mLruProcesses.get(i);
11652 if (r.thread != null) {
11653 try {
11654 r.thread.dispatchPackageBroadcast(cmd, packages);
11655 } catch (RemoteException ex) {
11656 }
11657 }
11658 }
11659 }
11660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 private final int broadcastIntentLocked(ProcessRecord callerApp,
11662 String callerPackage, Intent intent, String resolvedType,
11663 IIntentReceiver resultTo, int resultCode, String resultData,
11664 Bundle map, String requiredPermission,
11665 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11666 intent = new Intent(intent);
11667
Dianne Hackborne7f97212011-02-24 14:40:20 -080011668 // By default broadcasts do not go to stopped apps.
11669 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11670
Joe Onorato8a9b2202010-02-26 18:56:32 -080011671 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011672 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11673 + " ordered=" + ordered);
11674 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011675 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011676 }
11677
11678 // Handle special intents: if this broadcast is from the package
11679 // manager about a package being removed, we need to remove all of
11680 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011681 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011683 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11684 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011685 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011686 || uidRemoved) {
11687 if (checkComponentPermission(
11688 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011689 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 == PackageManager.PERMISSION_GRANTED) {
11691 if (uidRemoved) {
11692 final Bundle intentExtras = intent.getExtras();
11693 final int uid = intentExtras != null
11694 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11695 if (uid >= 0) {
11696 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11697 synchronized (bs) {
11698 bs.removeUidStatsLocked(uid);
11699 }
11700 }
11701 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011702 // If resources are unvailble just force stop all
11703 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011704 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011705 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11706 if (list != null && (list.length > 0)) {
11707 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011708 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011709 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011710 sendPackageBroadcastLocked(
11711 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011712 }
11713 } else {
11714 Uri data = intent.getData();
11715 String ssp;
11716 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11717 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11718 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011719 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011720 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011721 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011722 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11723 new String[] {ssp});
11724 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011725 }
11726 }
11727 }
11728 } else {
11729 String msg = "Permission Denial: " + intent.getAction()
11730 + " broadcast from " + callerPackage + " (pid=" + callingPid
11731 + ", uid=" + callingUid + ")"
11732 + " requires "
11733 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011734 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011735 throw new SecurityException(msg);
11736 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011737
11738 // Special case for adding a package: by default turn on compatibility
11739 // mode.
11740 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011741 Uri data = intent.getData();
11742 String ssp;
11743 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11744 mCompatModePackages.handlePackageAddedLocked(ssp,
11745 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011747 }
11748
11749 /*
11750 * If this is the time zone changed action, queue up a message that will reset the timezone
11751 * of all currently running processes. This message will get queued up before the broadcast
11752 * happens.
11753 */
11754 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11755 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11756 }
11757
Robert Greenwalt03595d02010-11-02 14:08:23 -070011758 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11759 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11760 }
11761
Robert Greenwalt434203a2010-10-11 16:00:27 -070011762 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11763 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11764 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11765 }
11766
Dianne Hackborn854060af2009-07-09 18:14:31 -070011767 /*
11768 * Prevent non-system code (defined here to be non-persistent
11769 * processes) from sending protected broadcasts.
11770 */
11771 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11772 || callingUid == Process.SHELL_UID || callingUid == 0) {
11773 // Always okay.
11774 } else if (callerApp == null || !callerApp.persistent) {
11775 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011776 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011777 intent.getAction())) {
11778 String msg = "Permission Denial: not allowed to send broadcast "
11779 + intent.getAction() + " from pid="
11780 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011781 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011782 throw new SecurityException(msg);
11783 }
11784 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011785 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011786 return BROADCAST_SUCCESS;
11787 }
11788 }
11789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011790 // Add to the sticky list if requested.
11791 if (sticky) {
11792 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11793 callingPid, callingUid)
11794 != PackageManager.PERMISSION_GRANTED) {
11795 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11796 + callingPid + ", uid=" + callingUid
11797 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011798 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 throw new SecurityException(msg);
11800 }
11801 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011802 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011803 + " and enforce permission " + requiredPermission);
11804 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11805 }
11806 if (intent.getComponent() != null) {
11807 throw new SecurityException(
11808 "Sticky broadcasts can't target a specific component");
11809 }
11810 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11811 if (list == null) {
11812 list = new ArrayList<Intent>();
11813 mStickyBroadcasts.put(intent.getAction(), list);
11814 }
11815 int N = list.size();
11816 int i;
11817 for (i=0; i<N; i++) {
11818 if (intent.filterEquals(list.get(i))) {
11819 // This sticky already exists, replace it.
11820 list.set(i, new Intent(intent));
11821 break;
11822 }
11823 }
11824 if (i >= N) {
11825 list.add(new Intent(intent));
11826 }
11827 }
11828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 // Figure out who all will receive this broadcast.
11830 List receivers = null;
11831 List<BroadcastFilter> registeredReceivers = null;
11832 try {
11833 if (intent.getComponent() != null) {
11834 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011835 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011836 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011837 if (ai != null) {
11838 receivers = new ArrayList();
11839 ResolveInfo ri = new ResolveInfo();
11840 ri.activityInfo = ai;
11841 receivers.add(ri);
11842 }
11843 } else {
11844 // Need to resolve the intent to interested receivers...
11845 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11846 == 0) {
11847 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011848 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011849 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 }
Mihai Preda074edef2009-05-18 17:13:31 +020011851 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011852 }
11853 } catch (RemoteException ex) {
11854 // pm is in same process, this will never happen.
11855 }
11856
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011857 final boolean replacePending =
11858 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11859
Joe Onorato8a9b2202010-02-26 18:56:32 -080011860 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011861 + " replacePending=" + replacePending);
11862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011863 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11864 if (!ordered && NR > 0) {
11865 // If we are not serializing this broadcast, then send the
11866 // registered receivers separately so they don't wait for the
11867 // components to be launched.
11868 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11869 callerPackage, callingPid, callingUid, requiredPermission,
11870 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011871 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011872 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011873 TAG, "Enqueueing parallel broadcast " + r
11874 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011875 boolean replaced = false;
11876 if (replacePending) {
11877 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11878 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011879 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011880 "***** DROPPING PARALLEL: " + intent);
11881 mParallelBroadcasts.set(i, r);
11882 replaced = true;
11883 break;
11884 }
11885 }
11886 }
11887 if (!replaced) {
11888 mParallelBroadcasts.add(r);
11889 scheduleBroadcastsLocked();
11890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011891 registeredReceivers = null;
11892 NR = 0;
11893 }
11894
11895 // Merge into one list.
11896 int ir = 0;
11897 if (receivers != null) {
11898 // A special case for PACKAGE_ADDED: do not allow the package
11899 // being added to see this broadcast. This prevents them from
11900 // using this as a back door to get run as soon as they are
11901 // installed. Maybe in the future we want to have a special install
11902 // broadcast or such for apps, but we'd like to deliberately make
11903 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011904 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011905 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11906 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11907 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011908 Uri data = intent.getData();
11909 if (data != null) {
11910 String pkgName = data.getSchemeSpecificPart();
11911 if (pkgName != null) {
11912 skipPackages = new String[] { pkgName };
11913 }
11914 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011915 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011916 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011917 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011918 if (skipPackages != null && (skipPackages.length > 0)) {
11919 for (String skipPackage : skipPackages) {
11920 if (skipPackage != null) {
11921 int NT = receivers.size();
11922 for (int it=0; it<NT; it++) {
11923 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11924 if (curt.activityInfo.packageName.equals(skipPackage)) {
11925 receivers.remove(it);
11926 it--;
11927 NT--;
11928 }
11929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011930 }
11931 }
11932 }
11933
11934 int NT = receivers != null ? receivers.size() : 0;
11935 int it = 0;
11936 ResolveInfo curt = null;
11937 BroadcastFilter curr = null;
11938 while (it < NT && ir < NR) {
11939 if (curt == null) {
11940 curt = (ResolveInfo)receivers.get(it);
11941 }
11942 if (curr == null) {
11943 curr = registeredReceivers.get(ir);
11944 }
11945 if (curr.getPriority() >= curt.priority) {
11946 // Insert this broadcast record into the final list.
11947 receivers.add(it, curr);
11948 ir++;
11949 curr = null;
11950 it++;
11951 NT++;
11952 } else {
11953 // Skip to the next ResolveInfo in the final list.
11954 it++;
11955 curt = null;
11956 }
11957 }
11958 }
11959 while (ir < NR) {
11960 if (receivers == null) {
11961 receivers = new ArrayList();
11962 }
11963 receivers.add(registeredReceivers.get(ir));
11964 ir++;
11965 }
11966
11967 if ((receivers != null && receivers.size() > 0)
11968 || resultTo != null) {
11969 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11970 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011971 receivers, resultTo, resultCode, resultData, map, ordered,
11972 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011973 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 TAG, "Enqueueing ordered broadcast " + r
11975 + ": prev had " + mOrderedBroadcasts.size());
11976 if (DEBUG_BROADCAST) {
11977 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011978 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011979 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011980 boolean replaced = false;
11981 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011982 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011983 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011984 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011985 "***** DROPPING ORDERED: " + intent);
11986 mOrderedBroadcasts.set(i, r);
11987 replaced = true;
11988 break;
11989 }
11990 }
11991 }
11992 if (!replaced) {
11993 mOrderedBroadcasts.add(r);
11994 scheduleBroadcastsLocked();
11995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011996 }
11997
11998 return BROADCAST_SUCCESS;
11999 }
12000
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012001 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 // Refuse possible leaked file descriptors
12003 if (intent != null && intent.hasFileDescriptors() == true) {
12004 throw new IllegalArgumentException("File descriptors passed in Intent");
12005 }
12006
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012007 int flags = intent.getFlags();
12008
12009 if (!mProcessesReady) {
12010 // if the caller really truly claims to know what they're doing, go
12011 // ahead and allow the broadcast without launching any receivers
12012 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12013 intent = new Intent(intent);
12014 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12015 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12016 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12017 + " before boot completion");
12018 throw new IllegalStateException("Cannot broadcast before boot completed");
12019 }
12020 }
12021
12022 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12023 throw new IllegalArgumentException(
12024 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12025 }
12026
12027 return intent;
12028 }
12029
12030 public final int broadcastIntent(IApplicationThread caller,
12031 Intent intent, String resolvedType, IIntentReceiver resultTo,
12032 int resultCode, String resultData, Bundle map,
12033 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012034 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012035 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012037 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12038 final int callingPid = Binder.getCallingPid();
12039 final int callingUid = Binder.getCallingUid();
12040 final long origId = Binder.clearCallingIdentity();
12041 int res = broadcastIntentLocked(callerApp,
12042 callerApp != null ? callerApp.info.packageName : null,
12043 intent, resolvedType, resultTo,
12044 resultCode, resultData, map, requiredPermission, serialized,
12045 sticky, callingPid, callingUid);
12046 Binder.restoreCallingIdentity(origId);
12047 return res;
12048 }
12049 }
12050
12051 int broadcastIntentInPackage(String packageName, int uid,
12052 Intent intent, String resolvedType, IIntentReceiver resultTo,
12053 int resultCode, String resultData, Bundle map,
12054 String requiredPermission, boolean serialized, boolean sticky) {
12055 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012056 intent = verifyBroadcastLocked(intent);
12057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 final long origId = Binder.clearCallingIdentity();
12059 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12060 resultTo, resultCode, resultData, map, requiredPermission,
12061 serialized, sticky, -1, uid);
12062 Binder.restoreCallingIdentity(origId);
12063 return res;
12064 }
12065 }
12066
12067 public final void unbroadcastIntent(IApplicationThread caller,
12068 Intent intent) {
12069 // Refuse possible leaked file descriptors
12070 if (intent != null && intent.hasFileDescriptors() == true) {
12071 throw new IllegalArgumentException("File descriptors passed in Intent");
12072 }
12073
12074 synchronized(this) {
12075 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12076 != PackageManager.PERMISSION_GRANTED) {
12077 String msg = "Permission Denial: unbroadcastIntent() from pid="
12078 + Binder.getCallingPid()
12079 + ", uid=" + Binder.getCallingUid()
12080 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012081 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012082 throw new SecurityException(msg);
12083 }
12084 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12085 if (list != null) {
12086 int N = list.size();
12087 int i;
12088 for (i=0; i<N; i++) {
12089 if (intent.filterEquals(list.get(i))) {
12090 list.remove(i);
12091 break;
12092 }
12093 }
12094 }
12095 }
12096 }
12097
12098 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12099 String resultData, Bundle resultExtras, boolean resultAbort,
12100 boolean explicit) {
12101 if (mOrderedBroadcasts.size() == 0) {
12102 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012103 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012104 }
12105 return false;
12106 }
12107 BroadcastRecord r = mOrderedBroadcasts.get(0);
12108 if (r.receiver == null) {
12109 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012110 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012111 }
12112 return false;
12113 }
12114 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012115 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 return false;
12117 }
12118 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012119 r.state = BroadcastRecord.IDLE;
12120 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012121 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012122 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012123 }
12124 }
12125 r.receiver = null;
12126 r.intent.setComponent(null);
12127 if (r.curApp != null) {
12128 r.curApp.curReceiver = null;
12129 }
12130 if (r.curFilter != null) {
12131 r.curFilter.receiverList.curBroadcast = null;
12132 }
12133 r.curFilter = null;
12134 r.curApp = null;
12135 r.curComponent = null;
12136 r.curReceiver = null;
12137 mPendingBroadcast = null;
12138
12139 r.resultCode = resultCode;
12140 r.resultData = resultData;
12141 r.resultExtras = resultExtras;
12142 r.resultAbort = resultAbort;
12143
12144 // We will process the next receiver right now if this is finishing
12145 // an app receiver (which is always asynchronous) or after we have
12146 // come back from calling a receiver.
12147 return state == BroadcastRecord.APP_RECEIVE
12148 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12149 }
12150
12151 public void finishReceiver(IBinder who, int resultCode, String resultData,
12152 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012153 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012154
12155 // Refuse possible leaked file descriptors
12156 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12157 throw new IllegalArgumentException("File descriptors passed in Bundle");
12158 }
12159
12160 boolean doNext;
12161
12162 final long origId = Binder.clearCallingIdentity();
12163
12164 synchronized(this) {
12165 doNext = finishReceiverLocked(
12166 who, resultCode, resultData, resultExtras, resultAbort, true);
12167 }
12168
12169 if (doNext) {
12170 processNextBroadcast(false);
12171 }
12172 trimApplications();
12173
12174 Binder.restoreCallingIdentity(origId);
12175 }
12176
Jeff Brown4d94a762010-09-23 11:33:28 -070012177 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012178 if (r.nextReceiver > 0) {
12179 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12180 if (curReceiver instanceof BroadcastFilter) {
12181 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012182 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012183 System.identityHashCode(r),
12184 r.intent.getAction(),
12185 r.nextReceiver - 1,
12186 System.identityHashCode(bf));
12187 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012188 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012189 System.identityHashCode(r),
12190 r.intent.getAction(),
12191 r.nextReceiver - 1,
12192 ((ResolveInfo)curReceiver).toString());
12193 }
12194 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012195 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012197 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 System.identityHashCode(r),
12199 r.intent.getAction(),
12200 r.nextReceiver,
12201 "NONE");
12202 }
12203 }
12204
Jeff Brown4d94a762010-09-23 11:33:28 -070012205 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12206 if (! mPendingBroadcastTimeoutMessage) {
12207 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12208 mHandler.sendMessageAtTime(msg, timeoutTime);
12209 mPendingBroadcastTimeoutMessage = true;
12210 }
12211 }
12212
12213 private final void cancelBroadcastTimeoutLocked() {
12214 if (mPendingBroadcastTimeoutMessage) {
12215 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12216 mPendingBroadcastTimeoutMessage = false;
12217 }
12218 }
12219
12220 private final void broadcastTimeoutLocked(boolean fromMsg) {
12221 if (fromMsg) {
12222 mPendingBroadcastTimeoutMessage = false;
12223 }
12224
12225 if (mOrderedBroadcasts.size() == 0) {
12226 return;
12227 }
12228
12229 long now = SystemClock.uptimeMillis();
12230 BroadcastRecord r = mOrderedBroadcasts.get(0);
12231 if (fromMsg) {
12232 if (mDidDexOpt) {
12233 // Delay timeouts until dexopt finishes.
12234 mDidDexOpt = false;
12235 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12236 setBroadcastTimeoutLocked(timeoutTime);
12237 return;
12238 }
12239 if (! mProcessesReady) {
12240 // Only process broadcast timeouts if the system is ready. That way
12241 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12242 // to do heavy lifting for system up.
12243 return;
12244 }
12245
12246 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12247 if (timeoutTime > now) {
12248 // We can observe premature timeouts because we do not cancel and reset the
12249 // broadcast timeout message after each receiver finishes. Instead, we set up
12250 // an initial timeout then kick it down the road a little further as needed
12251 // when it expires.
12252 if (DEBUG_BROADCAST) Slog.v(TAG,
12253 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12254 + timeoutTime);
12255 setBroadcastTimeoutLocked(timeoutTime);
12256 return;
12257 }
12258 }
12259
12260 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12261 + ", started " + (now - r.receiverTime) + "ms ago");
12262 r.receiverTime = now;
12263 r.anrCount++;
12264
12265 // Current receiver has passed its expiration date.
12266 if (r.nextReceiver <= 0) {
12267 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12268 return;
12269 }
12270
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012271 ProcessRecord app = null;
12272 String anrMessage = null;
12273
Jeff Brown4d94a762010-09-23 11:33:28 -070012274 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12275 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12276 logBroadcastReceiverDiscardLocked(r);
12277 if (curReceiver instanceof BroadcastFilter) {
12278 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12279 if (bf.receiverList.pid != 0
12280 && bf.receiverList.pid != MY_PID) {
12281 synchronized (this.mPidsSelfLocked) {
12282 app = this.mPidsSelfLocked.get(
12283 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012285 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012286 } else {
12287 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012288 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012289
Jeff Brown4d94a762010-09-23 11:33:28 -070012290 if (app != null) {
12291 anrMessage = "Broadcast of " + r.intent.toString();
12292 }
12293
12294 if (mPendingBroadcast == r) {
12295 mPendingBroadcast = null;
12296 }
12297
12298 // Move on to the next receiver.
12299 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12300 r.resultExtras, r.resultAbort, true);
12301 scheduleBroadcastsLocked();
12302
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012303 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012304 // Post the ANR to the handler since we do not want to process ANRs while
12305 // potentially holding our lock.
12306 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012308 }
12309
12310 private final void processCurBroadcastLocked(BroadcastRecord r,
12311 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012312 if (DEBUG_BROADCAST) Slog.v(TAG,
12313 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012314 if (app.thread == null) {
12315 throw new RemoteException();
12316 }
12317 r.receiver = app.thread.asBinder();
12318 r.curApp = app;
12319 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012320 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012321
12322 // Tell the application to launch this receiver.
12323 r.intent.setComponent(r.curComponent);
12324
12325 boolean started = false;
12326 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012327 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012328 "Delivering to component " + r.curComponent
12329 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012330 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012331 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012332 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012333 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012334 if (DEBUG_BROADCAST) Slog.v(TAG,
12335 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336 started = true;
12337 } finally {
12338 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012339 if (DEBUG_BROADCAST) Slog.v(TAG,
12340 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 r.receiver = null;
12342 r.curApp = null;
12343 app.curReceiver = null;
12344 }
12345 }
12346
12347 }
12348
Jeff Brown4d94a762010-09-23 11:33:28 -070012349 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012350 Intent intent, int resultCode, String data, Bundle extras,
12351 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012352 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012353 if (app != null && app.thread != null) {
12354 // If we have an app thread, do the call through that so it is
12355 // correctly ordered with other one-way calls.
12356 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012357 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012358 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012359 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012360 }
12361 }
12362
Jeff Brown4d94a762010-09-23 11:33:28 -070012363 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 BroadcastFilter filter, boolean ordered) {
12365 boolean skip = false;
12366 if (filter.requiredPermission != null) {
12367 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012368 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012369 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012370 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371 + r.intent.toString()
12372 + " from " + r.callerPackage + " (pid="
12373 + r.callingPid + ", uid=" + r.callingUid + ")"
12374 + " requires " + filter.requiredPermission
12375 + " due to registered receiver " + filter);
12376 skip = true;
12377 }
12378 }
12379 if (r.requiredPermission != null) {
12380 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012381 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012382 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012383 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012384 + r.intent.toString()
12385 + " to " + filter.receiverList.app
12386 + " (pid=" + filter.receiverList.pid
12387 + ", uid=" + filter.receiverList.uid + ")"
12388 + " requires " + r.requiredPermission
12389 + " due to sender " + r.callerPackage
12390 + " (uid " + r.callingUid + ")");
12391 skip = true;
12392 }
12393 }
12394
12395 if (!skip) {
12396 // If this is not being sent as an ordered broadcast, then we
12397 // don't want to touch the fields that keep track of the current
12398 // state of ordered broadcasts.
12399 if (ordered) {
12400 r.receiver = filter.receiverList.receiver.asBinder();
12401 r.curFilter = filter;
12402 filter.receiverList.curBroadcast = r;
12403 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012404 if (filter.receiverList.app != null) {
12405 // Bump hosting application to no longer be in background
12406 // scheduling class. Note that we can't do that if there
12407 // isn't an app... but we can only be in that case for
12408 // things that directly call the IActivityManager API, which
12409 // are already core system stuff so don't matter for this.
12410 r.curApp = filter.receiverList.app;
12411 filter.receiverList.app.curReceiver = r;
12412 updateOomAdjLocked();
12413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012414 }
12415 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012416 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012417 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012418 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012419 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012420 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012421 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012422 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012423 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012424 if (ordered) {
12425 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12426 }
12427 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012428 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012429 if (ordered) {
12430 r.receiver = null;
12431 r.curFilter = null;
12432 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012433 if (filter.receiverList.app != null) {
12434 filter.receiverList.app.curReceiver = null;
12435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012436 }
12437 }
12438 }
12439 }
12440
Dianne Hackborn12527f92009-11-11 17:39:50 -080012441 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12442 if (r.callingUid < 0) {
12443 // This was from a registerReceiver() call; ignore it.
12444 return;
12445 }
12446 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12447 MAX_BROADCAST_HISTORY-1);
12448 r.finishTime = SystemClock.uptimeMillis();
12449 mBroadcastHistory[0] = r;
12450 }
12451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012452 private final void processNextBroadcast(boolean fromMsg) {
12453 synchronized(this) {
12454 BroadcastRecord r;
12455
Joe Onorato8a9b2202010-02-26 18:56:32 -080012456 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012457 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012458 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459
12460 updateCpuStats();
12461
12462 if (fromMsg) {
12463 mBroadcastsScheduled = false;
12464 }
12465
12466 // First, deliver any non-serialized broadcasts right away.
12467 while (mParallelBroadcasts.size() > 0) {
12468 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012469 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012470 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012471 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012472 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012473 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012474 for (int i=0; i<N; i++) {
12475 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012476 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012477 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012478 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012479 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012480 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012481 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012482 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012483 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012484 }
12485
12486 // Now take care of the next serialized one...
12487
12488 // If we are waiting for a process to come up to handle the next
12489 // broadcast, then do nothing at this point. Just in case, we
12490 // check that the process we're waiting for still exists.
12491 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012492 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012493 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012494 + mPendingBroadcast.curApp);
12495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012496
12497 boolean isDead;
12498 synchronized (mPidsSelfLocked) {
12499 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12500 }
12501 if (!isDead) {
12502 // It's still alive, so keep waiting
12503 return;
12504 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012505 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012506 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012507 mPendingBroadcast.state = BroadcastRecord.IDLE;
12508 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 mPendingBroadcast = null;
12510 }
12511 }
12512
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012513 boolean looped = false;
12514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012515 do {
12516 if (mOrderedBroadcasts.size() == 0) {
12517 // No more broadcasts pending, so all done!
12518 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012519 if (looped) {
12520 // If we had finished the last ordered broadcast, then
12521 // make sure all processes have correct oom and sched
12522 // adjustments.
12523 updateOomAdjLocked();
12524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012525 return;
12526 }
12527 r = mOrderedBroadcasts.get(0);
12528 boolean forceReceive = false;
12529
12530 // Ensure that even if something goes awry with the timeout
12531 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012532 // and continue to make progress.
12533 //
12534 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012535 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012536 // one time heavy lifting after system upgrades and can take
12537 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012538 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012539 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012540 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012541 if ((numReceivers > 0) &&
12542 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012543 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012544 + " now=" + now
12545 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012546 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012547 + " intent=" + r.intent
12548 + " numReceivers=" + numReceivers
12549 + " nextReceiver=" + r.nextReceiver
12550 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012551 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012552 forceReceive = true;
12553 r.state = BroadcastRecord.IDLE;
12554 }
12555 }
12556
12557 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012558 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012559 "processNextBroadcast() called when not idle (state="
12560 + r.state + ")");
12561 return;
12562 }
12563
12564 if (r.receivers == null || r.nextReceiver >= numReceivers
12565 || r.resultAbort || forceReceive) {
12566 // No more receivers for this broadcast! Send the final
12567 // result if requested...
12568 if (r.resultTo != null) {
12569 try {
12570 if (DEBUG_BROADCAST) {
12571 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012572 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012573 + " seq=" + seq + " app=" + r.callerApp);
12574 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012575 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012576 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012577 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012578 // Set this to null so that the reference
12579 // (local and remote) isnt kept in the mBroadcastHistory.
12580 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012582 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012583 }
12584 }
12585
Joe Onorato8a9b2202010-02-26 18:56:32 -080012586 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012587 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012588
Joe Onorato8a9b2202010-02-26 18:56:32 -080012589 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012590 + r);
12591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012592 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012593 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012594 mOrderedBroadcasts.remove(0);
12595 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012596 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012597 continue;
12598 }
12599 } while (r == null);
12600
12601 // Get the next receiver...
12602 int recIdx = r.nextReceiver++;
12603
12604 // Keep track of when this receiver started, and make sure there
12605 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012606 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012607 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012608 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012609 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012610 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012611 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012612 }
12613 if (! mPendingBroadcastTimeoutMessage) {
12614 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012615 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012616 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12617 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012618 }
12619
12620 Object nextReceiver = r.receivers.get(recIdx);
12621 if (nextReceiver instanceof BroadcastFilter) {
12622 // Simple case: this is a registered receiver who gets
12623 // a direct call.
12624 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012625 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012626 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012627 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012628 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012629 if (r.receiver == null || !r.ordered) {
12630 // The receiver has already finished, so schedule to
12631 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012632 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12633 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012634 r.state = BroadcastRecord.IDLE;
12635 scheduleBroadcastsLocked();
12636 }
12637 return;
12638 }
12639
12640 // Hard case: need to instantiate the receiver, possibly
12641 // starting its application process to host it.
12642
12643 ResolveInfo info =
12644 (ResolveInfo)nextReceiver;
12645
12646 boolean skip = false;
12647 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012648 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12649 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012650 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012651 if (!info.activityInfo.exported) {
12652 Slog.w(TAG, "Permission Denial: broadcasting "
12653 + r.intent.toString()
12654 + " from " + r.callerPackage + " (pid=" + r.callingPid
12655 + ", uid=" + r.callingUid + ")"
12656 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12657 + " due to receiver " + info.activityInfo.packageName
12658 + "/" + info.activityInfo.name);
12659 } else {
12660 Slog.w(TAG, "Permission Denial: broadcasting "
12661 + r.intent.toString()
12662 + " from " + r.callerPackage + " (pid=" + r.callingPid
12663 + ", uid=" + r.callingUid + ")"
12664 + " requires " + info.activityInfo.permission
12665 + " due to receiver " + info.activityInfo.packageName
12666 + "/" + info.activityInfo.name);
12667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012668 skip = true;
12669 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012670 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012671 r.requiredPermission != null) {
12672 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012673 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012674 checkPermission(r.requiredPermission,
12675 info.activityInfo.applicationInfo.packageName);
12676 } catch (RemoteException e) {
12677 perm = PackageManager.PERMISSION_DENIED;
12678 }
12679 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012680 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012681 + r.intent + " to "
12682 + info.activityInfo.applicationInfo.packageName
12683 + " requires " + r.requiredPermission
12684 + " due to sender " + r.callerPackage
12685 + " (uid " + r.callingUid + ")");
12686 skip = true;
12687 }
12688 }
12689 if (r.curApp != null && r.curApp.crashing) {
12690 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012691 if (DEBUG_BROADCAST) Slog.v(TAG,
12692 "Skipping deliver ordered " + r + " to " + r.curApp
12693 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 skip = true;
12695 }
12696
12697 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012698 if (DEBUG_BROADCAST) Slog.v(TAG,
12699 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 r.receiver = null;
12701 r.curFilter = null;
12702 r.state = BroadcastRecord.IDLE;
12703 scheduleBroadcastsLocked();
12704 return;
12705 }
12706
12707 r.state = BroadcastRecord.APP_RECEIVE;
12708 String targetProcess = info.activityInfo.processName;
12709 r.curComponent = new ComponentName(
12710 info.activityInfo.applicationInfo.packageName,
12711 info.activityInfo.name);
12712 r.curReceiver = info.activityInfo;
12713
Dianne Hackborne7f97212011-02-24 14:40:20 -080012714 // Broadcast is being executed, its package can't be stopped.
12715 try {
12716 AppGlobals.getPackageManager().setPackageStoppedState(
12717 r.curComponent.getPackageName(), false);
12718 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012719 } catch (IllegalArgumentException e) {
12720 Slog.w(TAG, "Failed trying to unstop package "
12721 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012722 }
12723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012724 // Is this receiver's application already running?
12725 ProcessRecord app = getProcessRecordLocked(targetProcess,
12726 info.activityInfo.applicationInfo.uid);
12727 if (app != null && app.thread != null) {
12728 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012729 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012730 processCurBroadcastLocked(r, app);
12731 return;
12732 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012733 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012734 + r.curComponent, e);
12735 }
12736
12737 // If a dead object exception was thrown -- fall through to
12738 // restart the application.
12739 }
12740
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012741 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012742 if (DEBUG_BROADCAST) Slog.v(TAG,
12743 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012744 if ((r.curApp=startProcessLocked(targetProcess,
12745 info.activityInfo.applicationInfo, true,
12746 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012747 "broadcast", r.curComponent,
12748 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12749 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012750 // Ah, this recipient is unavailable. Finish it if necessary,
12751 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012752 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 + info.activityInfo.applicationInfo.packageName + "/"
12754 + info.activityInfo.applicationInfo.uid + " for broadcast "
12755 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012756 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012757 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12758 r.resultExtras, r.resultAbort, true);
12759 scheduleBroadcastsLocked();
12760 r.state = BroadcastRecord.IDLE;
12761 return;
12762 }
12763
12764 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012765 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012766 }
12767 }
12768
12769 // =========================================================
12770 // INSTRUMENTATION
12771 // =========================================================
12772
12773 public boolean startInstrumentation(ComponentName className,
12774 String profileFile, int flags, Bundle arguments,
12775 IInstrumentationWatcher watcher) {
12776 // Refuse possible leaked file descriptors
12777 if (arguments != null && arguments.hasFileDescriptors()) {
12778 throw new IllegalArgumentException("File descriptors passed in Bundle");
12779 }
12780
12781 synchronized(this) {
12782 InstrumentationInfo ii = null;
12783 ApplicationInfo ai = null;
12784 try {
12785 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012786 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012787 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012788 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012789 } catch (PackageManager.NameNotFoundException e) {
12790 }
12791 if (ii == null) {
12792 reportStartInstrumentationFailure(watcher, className,
12793 "Unable to find instrumentation info for: " + className);
12794 return false;
12795 }
12796 if (ai == null) {
12797 reportStartInstrumentationFailure(watcher, className,
12798 "Unable to find instrumentation target package: " + ii.targetPackage);
12799 return false;
12800 }
12801
12802 int match = mContext.getPackageManager().checkSignatures(
12803 ii.targetPackage, ii.packageName);
12804 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12805 String msg = "Permission Denial: starting instrumentation "
12806 + className + " from pid="
12807 + Binder.getCallingPid()
12808 + ", uid=" + Binder.getCallingPid()
12809 + " not allowed because package " + ii.packageName
12810 + " does not have a signature matching the target "
12811 + ii.targetPackage;
12812 reportStartInstrumentationFailure(watcher, className, msg);
12813 throw new SecurityException(msg);
12814 }
12815
12816 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012817 // Instrumentation can kill and relaunch even persistent processes
12818 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012819 ProcessRecord app = addAppLocked(ai);
12820 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012821 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012822 app.instrumentationProfileFile = profileFile;
12823 app.instrumentationArguments = arguments;
12824 app.instrumentationWatcher = watcher;
12825 app.instrumentationResultClass = className;
12826 Binder.restoreCallingIdentity(origId);
12827 }
12828
12829 return true;
12830 }
12831
12832 /**
12833 * Report errors that occur while attempting to start Instrumentation. Always writes the
12834 * error to the logs, but if somebody is watching, send the report there too. This enables
12835 * the "am" command to report errors with more information.
12836 *
12837 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12838 * @param cn The component name of the instrumentation.
12839 * @param report The error report.
12840 */
12841 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12842 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012843 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012844 try {
12845 if (watcher != null) {
12846 Bundle results = new Bundle();
12847 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12848 results.putString("Error", report);
12849 watcher.instrumentationStatus(cn, -1, results);
12850 }
12851 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012852 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012853 }
12854 }
12855
12856 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12857 if (app.instrumentationWatcher != null) {
12858 try {
12859 // NOTE: IInstrumentationWatcher *must* be oneway here
12860 app.instrumentationWatcher.instrumentationFinished(
12861 app.instrumentationClass,
12862 resultCode,
12863 results);
12864 } catch (RemoteException e) {
12865 }
12866 }
12867 app.instrumentationWatcher = null;
12868 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012869 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012870 app.instrumentationProfileFile = null;
12871 app.instrumentationArguments = null;
12872
Christopher Tate3dacd842011-08-19 14:56:15 -070012873 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012874 }
12875
12876 public void finishInstrumentation(IApplicationThread target,
12877 int resultCode, Bundle results) {
12878 // Refuse possible leaked file descriptors
12879 if (results != null && results.hasFileDescriptors()) {
12880 throw new IllegalArgumentException("File descriptors passed in Intent");
12881 }
12882
12883 synchronized(this) {
12884 ProcessRecord app = getRecordForAppLocked(target);
12885 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012886 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012887 return;
12888 }
12889 final long origId = Binder.clearCallingIdentity();
12890 finishInstrumentationLocked(app, resultCode, results);
12891 Binder.restoreCallingIdentity(origId);
12892 }
12893 }
12894
12895 // =========================================================
12896 // CONFIGURATION
12897 // =========================================================
12898
12899 public ConfigurationInfo getDeviceConfigurationInfo() {
12900 ConfigurationInfo config = new ConfigurationInfo();
12901 synchronized (this) {
12902 config.reqTouchScreen = mConfiguration.touchscreen;
12903 config.reqKeyboardType = mConfiguration.keyboard;
12904 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012905 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12906 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012907 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12908 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012909 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12910 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012911 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12912 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012913 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012914 }
12915 return config;
12916 }
12917
12918 public Configuration getConfiguration() {
12919 Configuration ci;
12920 synchronized(this) {
12921 ci = new Configuration(mConfiguration);
12922 }
12923 return ci;
12924 }
12925
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012926 public void updatePersistentConfiguration(Configuration values) {
12927 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12928 "updateConfiguration()");
12929 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12930 "updateConfiguration()");
12931 if (values == null) {
12932 throw new NullPointerException("Configuration must not be null");
12933 }
12934
12935 synchronized(this) {
12936 final long origId = Binder.clearCallingIdentity();
12937 updateConfigurationLocked(values, null, true);
12938 Binder.restoreCallingIdentity(origId);
12939 }
12940 }
12941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012942 public void updateConfiguration(Configuration values) {
12943 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12944 "updateConfiguration()");
12945
12946 synchronized(this) {
12947 if (values == null && mWindowManager != null) {
12948 // sentinel: fetch the current configuration from the window manager
12949 values = mWindowManager.computeNewConfiguration();
12950 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012951
12952 if (mWindowManager != null) {
12953 mProcessList.applyDisplaySize(mWindowManager);
12954 }
12955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012956 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012957 if (values != null) {
12958 Settings.System.clearConfiguration(values);
12959 }
12960 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012961 Binder.restoreCallingIdentity(origId);
12962 }
12963 }
12964
12965 /**
12966 * Do either or both things: (1) change the current configuration, and (2)
12967 * make sure the given activity is running with the (now) current
12968 * configuration. Returns true if the activity has been left running, or
12969 * false if <var>starting</var> is being destroyed to match the new
12970 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012971 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012972 */
12973 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012974 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012975 int changes = 0;
12976
12977 boolean kept = true;
12978
12979 if (values != null) {
12980 Configuration newConfig = new Configuration(mConfiguration);
12981 changes = newConfig.updateFrom(values);
12982 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012983 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012984 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012985 }
12986
Doug Zongker2bec3d42009-12-04 12:52:44 -080012987 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012988
12989 if (values.locale != null) {
12990 saveLocaleLocked(values.locale,
12991 !values.locale.equals(mConfiguration.locale),
12992 values.userSetLocale);
12993 }
12994
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012995 mConfigurationSeq++;
12996 if (mConfigurationSeq <= 0) {
12997 mConfigurationSeq = 1;
12998 }
12999 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013000 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013001 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013002
13003 AttributeCache ac = AttributeCache.instance();
13004 if (ac != null) {
13005 ac.updateConfiguration(mConfiguration);
13006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013008 // Make sure all resources in our process are updated
13009 // right now, so that anyone who is going to retrieve
13010 // resource values after we return will be sure to get
13011 // the new ones. This is especially important during
13012 // boot, where the first config change needs to guarantee
13013 // all resources have that config before following boot
13014 // code is executed.
13015 mSystemThread.applyConfigurationToResources(newConfig);
13016
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013017 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013018 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13019 msg.obj = new Configuration(mConfiguration);
13020 mHandler.sendMessage(msg);
13021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013022
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013023 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13024 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013025 try {
13026 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013027 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013028 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013029 app.thread.scheduleConfigurationChanged(mConfiguration);
13030 }
13031 } catch (Exception e) {
13032 }
13033 }
13034 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013035 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13036 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013037 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13038 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013039 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13040 broadcastIntentLocked(null, null,
13041 new Intent(Intent.ACTION_LOCALE_CHANGED),
13042 null, null, 0, null, null,
13043 null, false, false, MY_PID, Process.SYSTEM_UID);
13044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013045 }
13046 }
13047
13048 if (changes != 0 && starting == null) {
13049 // If the configuration changed, and the caller is not already
13050 // in the process of starting an activity, then find the top
13051 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013052 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 }
13054
13055 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013056 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013057 // And we need to make sure at this point that all other activities
13058 // are made visible with the correct configuration.
13059 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013060 }
13061
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013062 if (values != null && mWindowManager != null) {
13063 mWindowManager.setNewConfiguration(mConfiguration);
13064 }
13065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013066 return kept;
13067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013068
13069 /**
13070 * Save the locale. You must be inside a synchronized (this) block.
13071 */
13072 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13073 if(isDiff) {
13074 SystemProperties.set("user.language", l.getLanguage());
13075 SystemProperties.set("user.region", l.getCountry());
13076 }
13077
13078 if(isPersist) {
13079 SystemProperties.set("persist.sys.language", l.getLanguage());
13080 SystemProperties.set("persist.sys.country", l.getCountry());
13081 SystemProperties.set("persist.sys.localevar", l.getVariant());
13082 }
13083 }
13084
13085 // =========================================================
13086 // LIFETIME MANAGEMENT
13087 // =========================================================
13088
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013089 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013090 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013091 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013092 // This adjustment has already been computed. If we are calling
13093 // from the top, we may have already computed our adjustment with
13094 // an earlier hidden adjustment that isn't really for us... if
13095 // so, use the new hidden adjustment.
13096 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013097 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013098 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013099 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013100 }
13101
13102 if (app.thread == null) {
13103 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013104 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013105 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013106 }
13107
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013108 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13109 app.adjSource = null;
13110 app.adjTarget = null;
13111 app.empty = false;
13112 app.hidden = false;
13113
13114 final int activitiesSize = app.activities.size();
13115
Dianne Hackborn7d608422011-08-07 16:24:18 -070013116 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013117 // The max adjustment doesn't allow this app to be anything
13118 // below foreground, so it is not worth doing work for it.
13119 app.adjType = "fixed";
13120 app.adjSeq = mAdjSeq;
13121 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013122 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013123 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013124 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013125 // System process can do UI, and when they do we want to have
13126 // them trim their memory after the user leaves the UI. To
13127 // facilitate this, here we need to determine whether or not it
13128 // is currently showing UI.
13129 app.systemNoUi = true;
13130 if (app == TOP_APP) {
13131 app.systemNoUi = false;
13132 } else if (activitiesSize > 0) {
13133 for (int j = 0; j < activitiesSize; j++) {
13134 final ActivityRecord r = app.activities.get(j);
13135 if (r.visible) {
13136 app.systemNoUi = false;
13137 break;
13138 }
13139 }
13140 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013141 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013142 }
13143
13144 final boolean hadForegroundActivities = app.foregroundActivities;
13145
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013146 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013147 app.keeping = false;
13148 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013149
The Android Open Source Project4df24232009-03-05 14:34:35 -080013150 // Determine the importance of the process, starting with most
13151 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013152 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013153 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013154 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013156 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013157 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013158 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013159 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013160 } else if (app.instrumentationClass != null) {
13161 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013162 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013163 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013164 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013165 } else if (app.curReceiver != null ||
13166 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13167 // An app that is currently receiving a broadcast also
13168 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013169 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013170 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013171 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013172 } else if (app.executingServices.size() > 0) {
13173 // An app that is currently executing a service callback also
13174 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013175 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013176 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013177 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013178 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013179 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013180 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013181 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013182 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013183 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013184 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013185 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013186 // A very not-needed process. If this is lower in the lru list,
13187 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013188 adj = hiddenAdj;
13189 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013190 app.hidden = true;
13191 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013192 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013193 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013194
13195 // Examine all activities if not already foreground.
13196 if (!app.foregroundActivities && activitiesSize > 0) {
13197 for (int j = 0; j < activitiesSize; j++) {
13198 final ActivityRecord r = app.activities.get(j);
13199 if (r.visible) {
13200 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013201 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13202 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013203 app.adjType = "visible";
13204 }
13205 schedGroup = Process.THREAD_GROUP_DEFAULT;
13206 app.hidden = false;
13207 app.foregroundActivities = true;
13208 break;
13209 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13210 || r.state == ActivityState.STOPPING) {
13211 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013212 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13213 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013214 app.adjType = "stopping";
13215 }
13216 app.foregroundActivities = true;
13217 }
13218 }
13219 }
13220
Dianne Hackborn7d608422011-08-07 16:24:18 -070013221 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013222 if (app.foregroundServices) {
13223 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013224 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013225 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013226 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013227 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013228 } else if (app.forcingToForeground != null) {
13229 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013230 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013231 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013232 app.adjType = "force-foreground";
13233 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013234 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013235 }
13236 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013237
Dianne Hackborn7d608422011-08-07 16:24:18 -070013238 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013239 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013240 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013241 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013242 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013243 app.adjType = "heavy";
13244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013245
Dianne Hackborn7d608422011-08-07 16:24:18 -070013246 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013247 // This process is hosting what we currently consider to be the
13248 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013249 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013250 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013251 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013252 app.adjType = "home";
13253 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013254
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013255 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13256 && app.activities.size() > 0) {
13257 // This was the previous process that showed UI to the user.
13258 // We want to try to keep it around more aggressively, to give
13259 // a good experience around switching between two apps.
13260 adj = ProcessList.PREVIOUS_APP_ADJ;
13261 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13262 app.hidden = false;
13263 app.adjType = "previous";
13264 }
13265
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013266 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13267 + " reason=" + app.adjType);
13268
The Android Open Source Project4df24232009-03-05 14:34:35 -080013269 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013270 // there are applications dependent on our services or providers, but
13271 // this gives us a baseline and makes sure we don't get into an
13272 // infinite recursion.
13273 app.adjSeq = mAdjSeq;
13274 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013275
Christopher Tate6fa95972009-06-05 18:43:55 -070013276 if (mBackupTarget != null && app == mBackupTarget.app) {
13277 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013278 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013279 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013280 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013281 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013282 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013283 }
13284 }
13285
Dianne Hackborn7d608422011-08-07 16:24:18 -070013286 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013287 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 final long now = SystemClock.uptimeMillis();
13289 // This process is more important if the top activity is
13290 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013291 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013292 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013293 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013294 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013295 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013296 // If this process has shown some UI, let it immediately
13297 // go to the LRU list because it may be pretty heavy with
13298 // UI stuff. We'll tag it with a label just to help
13299 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013300 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013301 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013302 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013303 } else {
13304 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13305 // This service has seen some activity within
13306 // recent memory, so we will keep its process ahead
13307 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013308 if (adj > ProcessList.SERVICE_ADJ) {
13309 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013310 app.adjType = "started-services";
13311 app.hidden = false;
13312 }
13313 }
13314 // If we have let the service slide into the background
13315 // state, still have some text describing what it is doing
13316 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013317 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013318 app.adjType = "started-bg-services";
13319 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013320 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013321 // Don't kill this process because it is doing work; it
13322 // has said it is doing work.
13323 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013324 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013325 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013326 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013327 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013328 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013329 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013330 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013331 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013332 // XXX should compute this based on the max of
13333 // all connected clients.
13334 ConnectionRecord cr = clist.get(i);
13335 if (cr.binding.client == app) {
13336 // Binding to ourself is not interesting.
13337 continue;
13338 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013339 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013340 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013341 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013342 int myHiddenAdj = hiddenAdj;
13343 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013344 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013345 myHiddenAdj = client.hiddenAdj;
13346 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013347 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013348 }
13349 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013350 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013351 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013352 String adjType = null;
13353 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13354 // Not doing bind OOM management, so treat
13355 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013356 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013357 // If this process has shown some UI, let it immediately
13358 // go to the LRU list because it may be pretty heavy with
13359 // UI stuff. We'll tag it with a label just to help
13360 // debug and understand what is going on.
13361 if (adj > clientAdj) {
13362 adjType = "bound-bg-ui-services";
13363 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013364 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013365 clientAdj = adj;
13366 } else {
13367 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13368 // This service has not seen activity within
13369 // recent memory, so allow it to drop to the
13370 // LRU list if there is no other reason to keep
13371 // it around. We'll also tag it with a label just
13372 // to help debug and undertand what is going on.
13373 if (adj > clientAdj) {
13374 adjType = "bound-bg-services";
13375 }
13376 clientAdj = adj;
13377 }
13378 }
13379 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013380 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013381 // If this process has recently shown UI, and
13382 // the process that is binding to it is less
13383 // important than being visible, then we don't
13384 // care about the binding as much as we care
13385 // about letting this process get into the LRU
13386 // list to be killed and restarted if needed for
13387 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013388 if (app.hasShownUi && app != mHomeProcess
13389 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013390 adjType = "bound-bg-ui-services";
13391 } else {
13392 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13393 |Context.BIND_IMPORTANT)) != 0) {
13394 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013395 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13396 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13397 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13398 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13399 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013400 adj = clientAdj;
13401 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013402 app.pendingUiClean = true;
13403 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13404 adj = ProcessList.VISIBLE_APP_ADJ;
13405 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013406 }
13407 if (!client.hidden) {
13408 app.hidden = false;
13409 }
13410 if (client.keeping) {
13411 app.keeping = true;
13412 }
13413 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013414 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013415 }
13416 if (adjType != null) {
13417 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013418 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13419 .REASON_SERVICE_IN_USE;
13420 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013421 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013422 app.adjTarget = s.name;
13423 }
13424 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13425 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13426 schedGroup = Process.THREAD_GROUP_DEFAULT;
13427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013428 }
13429 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013430 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13431 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013432 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013433 (a.visible || a.state == ActivityState.RESUMED
13434 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013435 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013436 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13437 schedGroup = Process.THREAD_GROUP_DEFAULT;
13438 }
13439 app.hidden = false;
13440 app.adjType = "service";
13441 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13442 .REASON_SERVICE_IN_USE;
13443 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013444 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013445 app.adjTarget = s.name;
13446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013448 }
13449 }
13450 }
13451 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013452
Dianne Hackborn287952c2010-09-22 22:34:31 -070013453 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013454 // would like to avoid killing it unless it would prevent the current
13455 // application from running. By default we put the process in
13456 // with the rest of the background processes; as we scan through
13457 // its services we may bump it up from there.
13458 if (adj > hiddenAdj) {
13459 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013460 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013461 app.adjType = "bg-services";
13462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013463 }
13464
Dianne Hackborn7d608422011-08-07 16:24:18 -070013465 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013466 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013467 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013468 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013469 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013470 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013471 if (cpr.clients.size() != 0) {
13472 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013473 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013474 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013475 if (client == app) {
13476 // Being our own client is not interesting.
13477 continue;
13478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013479 int myHiddenAdj = hiddenAdj;
13480 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013481 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013482 myHiddenAdj = client.hiddenAdj;
13483 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013484 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013485 }
13486 }
13487 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013488 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013489 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013490 if (app.hasShownUi && app != mHomeProcess
13491 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013492 app.adjType = "bg-ui-provider";
13493 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013494 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13495 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013496 app.adjType = "provider";
13497 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013498 if (!client.hidden) {
13499 app.hidden = false;
13500 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013501 if (client.keeping) {
13502 app.keeping = true;
13503 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013504 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13505 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013506 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013507 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013508 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013509 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013510 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13511 schedGroup = Process.THREAD_GROUP_DEFAULT;
13512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013513 }
13514 }
13515 // If the provider has external (non-framework) process
13516 // dependencies, ensure that its adjustment is at least
13517 // FOREGROUND_APP_ADJ.
13518 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013519 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13520 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013521 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013522 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013523 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013524 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013525 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013526 }
13527 }
13528 }
13529 }
13530
13531 app.curRawAdj = adj;
13532
Joe Onorato8a9b2202010-02-26 18:56:32 -080013533 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013534 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13535 if (adj > app.maxAdj) {
13536 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013537 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013538 schedGroup = Process.THREAD_GROUP_DEFAULT;
13539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013540 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013541 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013542 app.keeping = true;
13543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013544
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013545 if (app.hasAboveClient) {
13546 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13547 // then we need to drop its adjustment to be lower than the service's
13548 // in order to honor the request. We want to drop it by one adjustment
13549 // level... but there is special meaning applied to various levels so
13550 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013551 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013552 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013553 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13554 adj = ProcessList.VISIBLE_APP_ADJ;
13555 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13556 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13557 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13558 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013559 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013560 adj++;
13561 }
13562 }
13563
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013564 if (adj == ProcessList.SERVICE_ADJ) {
13565 if (doingAll) {
13566 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13567 mNewNumServiceProcs++;
13568 }
13569 if (app.serviceb) {
13570 adj = ProcessList.SERVICE_B_ADJ;
13571 }
13572 } else {
13573 app.serviceb = false;
13574 }
13575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013576 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013577 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013578
13579 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013580 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13581 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013582 }
13583
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013584 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013585 }
13586
13587 /**
13588 * Ask a given process to GC right now.
13589 */
13590 final void performAppGcLocked(ProcessRecord app) {
13591 try {
13592 app.lastRequestedGc = SystemClock.uptimeMillis();
13593 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013594 if (app.reportLowMemory) {
13595 app.reportLowMemory = false;
13596 app.thread.scheduleLowMemory();
13597 } else {
13598 app.thread.processInBackground();
13599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013600 }
13601 } catch (Exception e) {
13602 // whatever.
13603 }
13604 }
13605
13606 /**
13607 * Returns true if things are idle enough to perform GCs.
13608 */
Josh Bartel7f208742010-02-25 11:01:44 -060013609 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013610 return mParallelBroadcasts.size() == 0
13611 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013612 && (mSleeping || (mMainStack.mResumedActivity != null &&
13613 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013614 }
13615
13616 /**
13617 * Perform GCs on all processes that are waiting for it, but only
13618 * if things are idle.
13619 */
13620 final void performAppGcsLocked() {
13621 final int N = mProcessesToGc.size();
13622 if (N <= 0) {
13623 return;
13624 }
Josh Bartel7f208742010-02-25 11:01:44 -060013625 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013626 while (mProcessesToGc.size() > 0) {
13627 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013628 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013629 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13630 <= SystemClock.uptimeMillis()) {
13631 // To avoid spamming the system, we will GC processes one
13632 // at a time, waiting a few seconds between each.
13633 performAppGcLocked(proc);
13634 scheduleAppGcsLocked();
13635 return;
13636 } else {
13637 // It hasn't been long enough since we last GCed this
13638 // process... put it in the list to wait for its time.
13639 addProcessToGcListLocked(proc);
13640 break;
13641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013642 }
13643 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013644
13645 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013646 }
13647 }
13648
13649 /**
13650 * If all looks good, perform GCs on all processes waiting for them.
13651 */
13652 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013653 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013654 performAppGcsLocked();
13655 return;
13656 }
13657 // Still not idle, wait some more.
13658 scheduleAppGcsLocked();
13659 }
13660
13661 /**
13662 * Schedule the execution of all pending app GCs.
13663 */
13664 final void scheduleAppGcsLocked() {
13665 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013666
13667 if (mProcessesToGc.size() > 0) {
13668 // Schedule a GC for the time to the next process.
13669 ProcessRecord proc = mProcessesToGc.get(0);
13670 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13671
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013672 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013673 long now = SystemClock.uptimeMillis();
13674 if (when < (now+GC_TIMEOUT)) {
13675 when = now + GC_TIMEOUT;
13676 }
13677 mHandler.sendMessageAtTime(msg, when);
13678 }
13679 }
13680
13681 /**
13682 * Add a process to the array of processes waiting to be GCed. Keeps the
13683 * list in sorted order by the last GC time. The process can't already be
13684 * on the list.
13685 */
13686 final void addProcessToGcListLocked(ProcessRecord proc) {
13687 boolean added = false;
13688 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13689 if (mProcessesToGc.get(i).lastRequestedGc <
13690 proc.lastRequestedGc) {
13691 added = true;
13692 mProcessesToGc.add(i+1, proc);
13693 break;
13694 }
13695 }
13696 if (!added) {
13697 mProcessesToGc.add(0, proc);
13698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013699 }
13700
13701 /**
13702 * Set up to ask a process to GC itself. This will either do it
13703 * immediately, or put it on the list of processes to gc the next
13704 * time things are idle.
13705 */
13706 final void scheduleAppGcLocked(ProcessRecord app) {
13707 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013708 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013709 return;
13710 }
13711 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013712 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013713 scheduleAppGcsLocked();
13714 }
13715 }
13716
Dianne Hackborn287952c2010-09-22 22:34:31 -070013717 final void checkExcessivePowerUsageLocked(boolean doKills) {
13718 updateCpuStatsNow();
13719
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013720 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013721 boolean doWakeKills = doKills;
13722 boolean doCpuKills = doKills;
13723 if (mLastPowerCheckRealtime == 0) {
13724 doWakeKills = false;
13725 }
13726 if (mLastPowerCheckUptime == 0) {
13727 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013728 }
13729 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013730 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013731 }
13732 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013733 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13734 final long curUptime = SystemClock.uptimeMillis();
13735 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13736 mLastPowerCheckRealtime = curRealtime;
13737 mLastPowerCheckUptime = curUptime;
13738 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13739 doWakeKills = false;
13740 }
13741 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13742 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013743 }
13744 int i = mLruProcesses.size();
13745 while (i > 0) {
13746 i--;
13747 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013748 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013749 long wtime;
13750 synchronized (stats) {
13751 wtime = stats.getProcessWakeTime(app.info.uid,
13752 app.pid, curRealtime);
13753 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013754 long wtimeUsed = wtime - app.lastWakeTime;
13755 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13756 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013757 StringBuilder sb = new StringBuilder(128);
13758 sb.append("Wake for ");
13759 app.toShortString(sb);
13760 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013761 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013762 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013763 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013764 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013765 sb.append((wtimeUsed*100)/realtimeSince);
13766 sb.append("%)");
13767 Slog.i(TAG, sb.toString());
13768 sb.setLength(0);
13769 sb.append("CPU for ");
13770 app.toShortString(sb);
13771 sb.append(": over ");
13772 TimeUtils.formatDuration(uptimeSince, sb);
13773 sb.append(" used ");
13774 TimeUtils.formatDuration(cputimeUsed, sb);
13775 sb.append(" (");
13776 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013777 sb.append("%)");
13778 Slog.i(TAG, sb.toString());
13779 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013780 // If a process has held a wake lock for more
13781 // than 50% of the time during this period,
13782 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013783 if (doWakeKills && realtimeSince > 0
13784 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13785 synchronized (stats) {
13786 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13787 realtimeSince, wtimeUsed);
13788 }
13789 Slog.w(TAG, "Excessive wake lock in " + app.processName
13790 + " (pid " + app.pid + "): held " + wtimeUsed
13791 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013792 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13793 app.processName, app.setAdj, "excessive wake lock");
13794 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013795 } else if (doCpuKills && uptimeSince > 0
13796 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13797 synchronized (stats) {
13798 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13799 uptimeSince, cputimeUsed);
13800 }
13801 Slog.w(TAG, "Excessive CPU in " + app.processName
13802 + " (pid " + app.pid + "): used " + cputimeUsed
13803 + " during " + uptimeSince);
13804 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13805 app.processName, app.setAdj, "excessive cpu");
13806 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013807 } else {
13808 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013809 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013810 }
13811 }
13812 }
13813 }
13814
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013815 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013816 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013817 app.hiddenAdj = hiddenAdj;
13818
13819 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013820 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013821 }
13822
Dianne Hackborn287952c2010-09-22 22:34:31 -070013823 final boolean wasKeeping = app.keeping;
13824
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013825 boolean success = true;
13826
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013827 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013828
Jeff Brown10e89712011-07-08 18:52:57 -070013829 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013830 if (false) {
13831 // Removing for now. Forcing GCs is not so useful anymore
13832 // with Dalvik, and the new memory level hint facility is
13833 // better for what we need to do these days.
13834 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13835 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13836 // If this app is transitioning from foreground to
13837 // non-foreground, have it do a gc.
13838 scheduleAppGcLocked(app);
13839 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13840 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13841 // Likewise do a gc when an app is moving in to the
13842 // background (such as a service stopping).
13843 scheduleAppGcLocked(app);
13844 }
Jeff Brown10e89712011-07-08 18:52:57 -070013845 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013846
Jeff Brown10e89712011-07-08 18:52:57 -070013847 if (wasKeeping && !app.keeping) {
13848 // This app is no longer something we want to keep. Note
13849 // its current wake lock time to later know to kill it if
13850 // it is not behaving well.
13851 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13852 synchronized (stats) {
13853 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13854 app.pid, SystemClock.elapsedRealtime());
13855 }
13856 app.lastCpuTime = app.curCpuTime;
13857 }
13858
13859 app.setRawAdj = app.curRawAdj;
13860 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013861
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013862 if (app.curAdj != app.setAdj) {
13863 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013864 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13865 TAG, "Set " + app.pid + " " + app.processName +
13866 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013867 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013868 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013869 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013870 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013871 }
13872 }
13873 if (app.setSchedGroup != app.curSchedGroup) {
13874 app.setSchedGroup = app.curSchedGroup;
13875 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13876 "Setting process group of " + app.processName
13877 + " to " + app.curSchedGroup);
13878 if (app.waitingToKill != null &&
13879 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13880 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13881 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13882 app.processName, app.setAdj, app.waitingToKill);
13883 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013884 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013885 } else {
13886 if (true) {
13887 long oldId = Binder.clearCallingIdentity();
13888 try {
13889 Process.setProcessGroup(app.pid, app.curSchedGroup);
13890 } catch (Exception e) {
13891 Slog.w(TAG, "Failed setting process group of " + app.pid
13892 + " to " + app.curSchedGroup);
13893 e.printStackTrace();
13894 } finally {
13895 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013896 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013897 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013898 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013899 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013900 app.thread.setSchedulingGroup(app.curSchedGroup);
13901 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013902 }
13903 }
13904 }
13905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013906 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013907 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013908 }
13909
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013910 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013911 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013912 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013913 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013914 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013915 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013916 }
13917 }
13918 return resumedActivity;
13919 }
13920
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013921 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013922 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013923 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13924 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013925 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13926 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013927
13928 mAdjSeq++;
13929
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013930 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013931 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13932 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013933 if (nowHidden != wasHidden) {
13934 // Changed to/from hidden state, so apps after it in the LRU
13935 // list may also be changed.
13936 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013937 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013938 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013939 }
13940
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013941 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013942 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013943 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13944
13945 if (false) {
13946 RuntimeException e = new RuntimeException();
13947 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013948 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013949 }
13950
13951 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013952 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013953
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013954 // Let's determine how many processes we have running vs.
13955 // how many slots we have for background processes; we may want
13956 // to put multiple processes in a slot of there are enough of
13957 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013958 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013959 int factor = (mLruProcesses.size()-4)/numSlots;
13960 if (factor < 1) factor = 1;
13961 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013962 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013963
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013964 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013965 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013966 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013967 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013968 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013969 while (i > 0) {
13970 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013971 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013972 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013973 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
13974 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013975 && app.curAdj == curHiddenAdj) {
13976 step++;
13977 if (step >= factor) {
13978 step = 0;
13979 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013980 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013981 }
13982 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013983 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013984 numHidden++;
13985 if (numHidden > mProcessLimit) {
13986 Slog.i(TAG, "No longer want " + app.processName
13987 + " (pid " + app.pid + "): hidden #" + numHidden);
13988 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13989 app.processName, app.setAdj, "too many background");
13990 app.killedBackground = true;
13991 Process.killProcessQuiet(app.pid);
13992 } else {
13993 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013994 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013995 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ
13996 && app.curAdj != ProcessList.SERVICE_B_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013997 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013999 }
14000 }
14001
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014002 mNumServiceProcs = mNewNumServiceProcs;
14003
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014004 // Now determine the memory trimming level of background processes.
14005 // Unfortunately we need to start at the back of the list to do this
14006 // properly. We only do this if the number of background apps we
14007 // are managing to keep around is less than half the maximum we desire;
14008 // if we are keeping a good number around, we'll let them use whatever
14009 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014010 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014011 final int N = mLruProcesses.size();
14012 factor = numBg/3;
14013 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014014 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014015 for (i=0; i<N; i++) {
14016 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014017 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014018 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14019 try {
14020 app.thread.scheduleTrimMemory(curLevel);
14021 } catch (RemoteException e) {
14022 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014023 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014024 // For these apps we will also finish their activities
14025 // to help them free memory.
Dianne Hackborn28695e02011-11-02 21:59:51 -070014026 mMainStack.destroyActivitiesLocked(app, false, "trim");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014027 }
14028 }
14029 app.trimMemoryLevel = curLevel;
14030 step++;
14031 if (step >= factor) {
14032 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014033 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14034 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014035 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014036 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14037 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014038 break;
14039 }
14040 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014041 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014042 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014043 && app.thread != null) {
14044 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014045 app.thread.scheduleTrimMemory(
14046 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014047 } catch (RemoteException e) {
14048 }
14049 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014050 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014051 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014052 && app.pendingUiClean) {
14053 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14054 && app.thread != null) {
14055 try {
14056 app.thread.scheduleTrimMemory(
14057 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14058 } catch (RemoteException e) {
14059 }
14060 }
14061 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14062 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014063 } else {
14064 app.trimMemoryLevel = 0;
14065 }
14066 }
14067 } else {
14068 final int N = mLruProcesses.size();
14069 for (i=0; i<N; i++) {
14070 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014071 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014072 && app.pendingUiClean) {
14073 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14074 && app.thread != null) {
14075 try {
14076 app.thread.scheduleTrimMemory(
14077 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14078 } catch (RemoteException e) {
14079 }
14080 }
14081 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14082 app.pendingUiClean = false;
14083 } else {
14084 app.trimMemoryLevel = 0;
14085 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014086 }
14087 }
14088
14089 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014090 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014091 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014092 }
14093
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014094 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014095 synchronized (this) {
14096 int i;
14097
14098 // First remove any unused application processes whose package
14099 // has been removed.
14100 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14101 final ProcessRecord app = mRemovedProcesses.get(i);
14102 if (app.activities.size() == 0
14103 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014104 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014105 TAG, "Exiting empty application process "
14106 + app.processName + " ("
14107 + (app.thread != null ? app.thread.asBinder() : null)
14108 + ")\n");
14109 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014110 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14111 app.processName, app.setAdj, "empty");
14112 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014113 } else {
14114 try {
14115 app.thread.scheduleExit();
14116 } catch (Exception e) {
14117 // Ignore exceptions.
14118 }
14119 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014120 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014121 mRemovedProcesses.remove(i);
14122
14123 if (app.persistent) {
14124 if (app.persistent) {
14125 addAppLocked(app.info);
14126 }
14127 }
14128 }
14129 }
14130
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014131 // Now update the oom adj for all processes.
14132 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014133 }
14134 }
14135
14136 /** This method sends the specified signal to each of the persistent apps */
14137 public void signalPersistentProcesses(int sig) throws RemoteException {
14138 if (sig != Process.SIGNAL_USR1) {
14139 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14140 }
14141
14142 synchronized (this) {
14143 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14144 != PackageManager.PERMISSION_GRANTED) {
14145 throw new SecurityException("Requires permission "
14146 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14147 }
14148
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014149 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14150 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014151 if (r.thread != null && r.persistent) {
14152 Process.sendSignal(r.pid, sig);
14153 }
14154 }
14155 }
14156 }
14157
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014158 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14159 if (proc == null || proc == mProfileProc) {
14160 proc = mProfileProc;
14161 path = mProfileFile;
14162 profileType = mProfileType;
14163 clearProfilerLocked();
14164 }
14165 if (proc == null) {
14166 return;
14167 }
14168 try {
14169 proc.thread.profilerControl(false, path, null, profileType);
14170 } catch (RemoteException e) {
14171 throw new IllegalStateException("Process disappeared");
14172 }
14173 }
14174
14175 private void clearProfilerLocked() {
14176 if (mProfileFd != null) {
14177 try {
14178 mProfileFd.close();
14179 } catch (IOException e) {
14180 }
14181 }
14182 mProfileApp = null;
14183 mProfileProc = null;
14184 mProfileFile = null;
14185 mProfileType = 0;
14186 mAutoStopProfiler = false;
14187 }
14188
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014189 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014190 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014191
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014192 try {
14193 synchronized (this) {
14194 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14195 // its own permission.
14196 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14197 != PackageManager.PERMISSION_GRANTED) {
14198 throw new SecurityException("Requires permission "
14199 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014200 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014201
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014202 if (start && fd == null) {
14203 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014204 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014205
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014206 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014207 if (process != null) {
14208 try {
14209 int pid = Integer.parseInt(process);
14210 synchronized (mPidsSelfLocked) {
14211 proc = mPidsSelfLocked.get(pid);
14212 }
14213 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014214 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014215
14216 if (proc == null) {
14217 HashMap<String, SparseArray<ProcessRecord>> all
14218 = mProcessNames.getMap();
14219 SparseArray<ProcessRecord> procs = all.get(process);
14220 if (procs != null && procs.size() > 0) {
14221 proc = procs.valueAt(0);
14222 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014223 }
14224 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014225
14226 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014227 throw new IllegalArgumentException("Unknown process: " + process);
14228 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014229
14230 if (start) {
14231 stopProfilerLocked(null, null, 0);
14232 setProfileApp(proc.info, proc.processName, path, fd, false);
14233 mProfileProc = proc;
14234 mProfileType = profileType;
14235 try {
14236 fd = fd.dup();
14237 } catch (IOException e) {
14238 fd = null;
14239 }
14240 proc.thread.profilerControl(start, path, fd, profileType);
14241 fd = null;
14242 mProfileFd = null;
14243 } else {
14244 stopProfilerLocked(proc, path, profileType);
14245 if (fd != null) {
14246 try {
14247 fd.close();
14248 } catch (IOException e) {
14249 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014250 }
14251 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014252
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014253 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014254 }
14255 } catch (RemoteException e) {
14256 throw new IllegalStateException("Process disappeared");
14257 } finally {
14258 if (fd != null) {
14259 try {
14260 fd.close();
14261 } catch (IOException e) {
14262 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014263 }
14264 }
14265 }
Andy McFadden824c5102010-07-09 16:26:57 -070014266
14267 public boolean dumpHeap(String process, boolean managed,
14268 String path, ParcelFileDescriptor fd) throws RemoteException {
14269
14270 try {
14271 synchronized (this) {
14272 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14273 // its own permission (same as profileControl).
14274 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14275 != PackageManager.PERMISSION_GRANTED) {
14276 throw new SecurityException("Requires permission "
14277 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14278 }
14279
14280 if (fd == null) {
14281 throw new IllegalArgumentException("null fd");
14282 }
14283
14284 ProcessRecord proc = null;
14285 try {
14286 int pid = Integer.parseInt(process);
14287 synchronized (mPidsSelfLocked) {
14288 proc = mPidsSelfLocked.get(pid);
14289 }
14290 } catch (NumberFormatException e) {
14291 }
14292
14293 if (proc == null) {
14294 HashMap<String, SparseArray<ProcessRecord>> all
14295 = mProcessNames.getMap();
14296 SparseArray<ProcessRecord> procs = all.get(process);
14297 if (procs != null && procs.size() > 0) {
14298 proc = procs.valueAt(0);
14299 }
14300 }
14301
14302 if (proc == null || proc.thread == null) {
14303 throw new IllegalArgumentException("Unknown process: " + process);
14304 }
14305
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014306 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14307 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014308 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14309 throw new SecurityException("Process not debuggable: " + proc);
14310 }
14311 }
14312
14313 proc.thread.dumpHeap(managed, path, fd);
14314 fd = null;
14315 return true;
14316 }
14317 } catch (RemoteException e) {
14318 throw new IllegalStateException("Process disappeared");
14319 } finally {
14320 if (fd != null) {
14321 try {
14322 fd.close();
14323 } catch (IOException e) {
14324 }
14325 }
14326 }
14327 }
14328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014329 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14330 public void monitor() {
14331 synchronized (this) { }
14332 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014333
14334 public void onCoreSettingsChange(Bundle settings) {
14335 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14336 ProcessRecord processRecord = mLruProcesses.get(i);
14337 try {
14338 if (processRecord.thread != null) {
14339 processRecord.thread.setCoreSettings(settings);
14340 }
14341 } catch (RemoteException re) {
14342 /* ignore */
14343 }
14344 }
14345 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014346
14347 // Multi-user methods
14348
14349 public boolean switchUser(int userid) {
14350 // TODO
14351 return true;
14352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014353}