blob: 80234771b46627cb0b57d08712d6a324d40df878 [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();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001214 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1215 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001216 // 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);
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08001251 String[] emptyArgs = new String[] { };
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001252 StringBuilder tag = new StringBuilder(128);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001253 synchronized (ActivityManagerService.this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001254 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001255 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001256 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001257 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001258 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001259 catPw.println();
1260 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001261 tag.append("Low on memory -- ");
1262 dumpApplicationMemoryUsage(null, pw, " ", emptyArgs, true, catPw, tag);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001263 String memUsage = sw.toString();
1264 dropBuilder.append('\n');
1265 dropBuilder.append(memUsage);
1266 dropBuilder.append(catSw.toString());
1267 logBuilder.append(memUsage);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001268 addErrorToDropBox("lowmem", null, "system_server", null,
1269 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001270 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001271 synchronized (ActivityManagerService.this) {
1272 long now = SystemClock.uptimeMillis();
1273 if (mLastMemUsageReportTime < now) {
1274 mLastMemUsageReportTime = now;
1275 }
1276 }
1277 }
1278 };
1279 thread.start();
1280 break;
1281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 }
1283 }
1284 };
1285
1286 public static void setSystemProcess() {
1287 try {
1288 ActivityManagerService m = mSelf;
1289
1290 ServiceManager.addService("activity", m);
1291 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001292 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 if (MONITOR_CPU_USAGE) {
1294 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 ServiceManager.addService("permission", new PermissionController(m));
1297
1298 ApplicationInfo info =
1299 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001300 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001301 mSystemThread.installSystemApplicationInfo(info);
1302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 synchronized (mSelf) {
1304 ProcessRecord app = mSelf.newProcessRecordLocked(
1305 mSystemThread.getApplicationThread(), info,
1306 info.processName);
1307 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001308 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001309 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1311 synchronized (mSelf.mPidsSelfLocked) {
1312 mSelf.mPidsSelfLocked.put(app.pid, app);
1313 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001314 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 }
1316 } catch (PackageManager.NameNotFoundException e) {
1317 throw new RuntimeException(
1318 "Unable to find android system package", e);
1319 }
1320 }
1321
1322 public void setWindowManager(WindowManagerService wm) {
1323 mWindowManager = wm;
1324 }
1325
1326 public static final Context main(int factoryTest) {
1327 AThread thr = new AThread();
1328 thr.start();
1329
1330 synchronized (thr) {
1331 while (thr.mService == null) {
1332 try {
1333 thr.wait();
1334 } catch (InterruptedException e) {
1335 }
1336 }
1337 }
1338
1339 ActivityManagerService m = thr.mService;
1340 mSelf = m;
1341 ActivityThread at = ActivityThread.systemMain();
1342 mSystemThread = at;
1343 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001344 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 m.mContext = context;
1346 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001347 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348
1349 m.mBatteryStatsService.publish(context);
1350 m.mUsageStatsService.publish(context);
1351
1352 synchronized (thr) {
1353 thr.mReady = true;
1354 thr.notifyAll();
1355 }
1356
1357 m.startRunning(null, null, null, null);
1358
1359 return context;
1360 }
1361
1362 public static ActivityManagerService self() {
1363 return mSelf;
1364 }
1365
1366 static class AThread extends Thread {
1367 ActivityManagerService mService;
1368 boolean mReady = false;
1369
1370 public AThread() {
1371 super("ActivityManager");
1372 }
1373
1374 public void run() {
1375 Looper.prepare();
1376
1377 android.os.Process.setThreadPriority(
1378 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001379 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380
1381 ActivityManagerService m = new ActivityManagerService();
1382
1383 synchronized (this) {
1384 mService = m;
1385 notifyAll();
1386 }
1387
1388 synchronized (this) {
1389 while (!mReady) {
1390 try {
1391 wait();
1392 } catch (InterruptedException e) {
1393 }
1394 }
1395 }
1396
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001397 // For debug builds, log event loop stalls to dropbox for analysis.
1398 if (StrictMode.conditionallyEnableDebugLogging()) {
1399 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1400 }
1401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 Looper.loop();
1403 }
1404 }
1405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 static class MemBinder extends Binder {
1407 ActivityManagerService mActivityManagerService;
1408 MemBinder(ActivityManagerService activityManagerService) {
1409 mActivityManagerService = activityManagerService;
1410 }
1411
1412 @Override
1413 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001414 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1415 != PackageManager.PERMISSION_GRANTED) {
1416 pw.println("Permission Denial: can't dump meminfo from from pid="
1417 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1418 + " without permission " + android.Manifest.permission.DUMP);
1419 return;
1420 }
1421
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001422 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
1423 false, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 }
1425 }
1426
Chet Haase9c1e23b2011-03-24 10:51:31 -07001427 static class GraphicsBinder extends Binder {
1428 ActivityManagerService mActivityManagerService;
1429 GraphicsBinder(ActivityManagerService activityManagerService) {
1430 mActivityManagerService = activityManagerService;
1431 }
1432
1433 @Override
1434 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001435 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1436 != PackageManager.PERMISSION_GRANTED) {
1437 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1438 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1439 + " without permission " + android.Manifest.permission.DUMP);
1440 return;
1441 }
1442
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001443 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001444 }
1445 }
1446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 static class CpuBinder extends Binder {
1448 ActivityManagerService mActivityManagerService;
1449 CpuBinder(ActivityManagerService activityManagerService) {
1450 mActivityManagerService = activityManagerService;
1451 }
1452
1453 @Override
1454 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001455 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1456 != PackageManager.PERMISSION_GRANTED) {
1457 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1458 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1459 + " without permission " + android.Manifest.permission.DUMP);
1460 return;
1461 }
1462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001464 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1465 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1466 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 }
1468 }
1469 }
1470
1471 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001472 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 File dataDir = Environment.getDataDirectory();
1475 File systemDir = new File(dataDir, "system");
1476 systemDir.mkdirs();
1477 mBatteryStatsService = new BatteryStatsService(new File(
1478 systemDir, "batterystats.bin").toString());
1479 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001480 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001481 mOnBattery = DEBUG_POWER ? true
1482 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001483 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001485 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001486 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487
Jack Palevichb90d28c2009-07-22 15:35:24 -07001488 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1489 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1490
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001491 mConfiguration.setToDefaults();
1492 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001493 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 mProcessStats.init();
1495
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001496 mCompatModePackages = new CompatModePackages(this, systemDir);
1497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 // Add ourself to the Watchdog monitors.
1499 Watchdog.getInstance().addMonitor(this);
1500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 mProcessStatsThread = new Thread("ProcessStats") {
1502 public void run() {
1503 while (true) {
1504 try {
1505 try {
1506 synchronized(this) {
1507 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001508 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001510 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 // + ", write delay=" + nextWriteDelay);
1512 if (nextWriteDelay < nextCpuDelay) {
1513 nextCpuDelay = nextWriteDelay;
1514 }
1515 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001516 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 this.wait(nextCpuDelay);
1518 }
1519 }
1520 } catch (InterruptedException e) {
1521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 updateCpuStatsNow();
1523 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001524 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 }
1526 }
1527 }
1528 };
1529 mProcessStatsThread.start();
1530 }
1531
1532 @Override
1533 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1534 throws RemoteException {
1535 try {
1536 return super.onTransact(code, data, reply, flags);
1537 } catch (RuntimeException e) {
1538 // The activity manager only throws security exceptions, so let's
1539 // log all others.
1540 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001541 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 }
1543 throw e;
1544 }
1545 }
1546
1547 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001548 final long now = SystemClock.uptimeMillis();
1549 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1550 return;
1551 }
1552 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1553 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 mProcessStatsThread.notify();
1555 }
1556 }
1557 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 void updateCpuStatsNow() {
1560 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001561 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 final long now = SystemClock.uptimeMillis();
1563 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001566 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1567 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 haveNewCpuStats = true;
1569 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001570 //Slog.i(TAG, mProcessStats.printCurrentState());
1571 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 // + mProcessStats.getTotalCpuPercent() + "%");
1573
Joe Onorato8a9b2202010-02-26 18:56:32 -08001574 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 if ("true".equals(SystemProperties.get("events.cpu"))) {
1576 int user = mProcessStats.getLastUserTime();
1577 int system = mProcessStats.getLastSystemTime();
1578 int iowait = mProcessStats.getLastIoWaitTime();
1579 int irq = mProcessStats.getLastIrqTime();
1580 int softIrq = mProcessStats.getLastSoftIrqTime();
1581 int idle = mProcessStats.getLastIdleTime();
1582
1583 int total = user + system + iowait + irq + softIrq + idle;
1584 if (total == 0) total = 1;
1585
Doug Zongker2bec3d42009-12-04 12:52:44 -08001586 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 ((user+system+iowait+irq+softIrq) * 100) / total,
1588 (user * 100) / total,
1589 (system * 100) / total,
1590 (iowait * 100) / total,
1591 (irq * 100) / total,
1592 (softIrq * 100) / total);
1593 }
1594 }
1595
Amith Yamasanie43530a2009-08-21 13:11:37 -07001596 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001597 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001598 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 synchronized(mPidsSelfLocked) {
1600 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001601 if (mOnBattery) {
1602 int perc = bstats.startAddingCpuLocked();
1603 int totalUTime = 0;
1604 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001605 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001607 ProcessStats.Stats st = mProcessStats.getStats(i);
1608 if (!st.working) {
1609 continue;
1610 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001612 int otherUTime = (st.rel_utime*perc)/100;
1613 int otherSTime = (st.rel_stime*perc)/100;
1614 totalUTime += otherUTime;
1615 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616 if (pr != null) {
1617 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001618 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1619 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001620 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001621 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001622 } else {
1623 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001624 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001625 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001626 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1627 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001628 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 }
1631 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001632 bstats.finishAddingCpuLocked(perc, totalUTime,
1633 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 }
1635 }
1636 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1639 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001640 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 }
1642 }
1643 }
1644 }
1645
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001646 @Override
1647 public void batteryNeedsCpuUpdate() {
1648 updateCpuStatsNow();
1649 }
1650
1651 @Override
1652 public void batteryPowerChanged(boolean onBattery) {
1653 // When plugging in, update the CPU stats first before changing
1654 // the plug state.
1655 updateCpuStatsNow();
1656 synchronized (this) {
1657 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001658 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001659 }
1660 }
1661 }
1662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 /**
1664 * Initialize the application bind args. These are passed to each
1665 * process when the bindApplication() IPC is sent to the process. They're
1666 * lazily setup to make sure the services are running when they're asked for.
1667 */
1668 private HashMap<String, IBinder> getCommonServicesLocked() {
1669 if (mAppBindArgs == null) {
1670 mAppBindArgs = new HashMap<String, IBinder>();
1671
1672 // Setup the application init args
1673 mAppBindArgs.put("package", ServiceManager.getService("package"));
1674 mAppBindArgs.put("window", ServiceManager.getService("window"));
1675 mAppBindArgs.put(Context.ALARM_SERVICE,
1676 ServiceManager.getService(Context.ALARM_SERVICE));
1677 }
1678 return mAppBindArgs;
1679 }
1680
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001681 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 if (mFocusedActivity != r) {
1683 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001684 if (r != null) {
1685 mWindowManager.setFocusedApp(r.appToken, true);
1686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 }
1688 }
1689
Dianne Hackborn906497c2010-05-10 15:57:38 -07001690 private final void updateLruProcessInternalLocked(ProcessRecord app,
1691 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001692 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001693 int lrui = mLruProcesses.indexOf(app);
1694 if (lrui >= 0) mLruProcesses.remove(lrui);
1695
1696 int i = mLruProcesses.size()-1;
1697 int skipTop = 0;
1698
Dianne Hackborn906497c2010-05-10 15:57:38 -07001699 app.lruSeq = mLruSeq;
1700
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001701 // compute the new weight for this process.
1702 if (updateActivityTime) {
1703 app.lastActivityTime = SystemClock.uptimeMillis();
1704 }
1705 if (app.activities.size() > 0) {
1706 // If this process has activities, we more strongly want to keep
1707 // it around.
1708 app.lruWeight = app.lastActivityTime;
1709 } else if (app.pubProviders.size() > 0) {
1710 // If this process contains content providers, we want to keep
1711 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001712 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001713 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001714 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001715 } else {
1716 // If this process doesn't have activities, we less strongly
1717 // want to keep it around, and generally want to avoid getting
1718 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001719 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001720 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001721 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001722 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001723
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 while (i >= 0) {
1725 ProcessRecord p = mLruProcesses.get(i);
1726 // If this app shouldn't be in front of the first N background
1727 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001728 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001729 skipTop--;
1730 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001731 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001732 mLruProcesses.add(i+1, app);
1733 break;
1734 }
1735 i--;
1736 }
1737 if (i < 0) {
1738 mLruProcesses.add(0, app);
1739 }
1740
Dianne Hackborn906497c2010-05-10 15:57:38 -07001741 // If the app is currently using a content provider or service,
1742 // bump those processes as well.
1743 if (app.connections.size() > 0) {
1744 for (ConnectionRecord cr : app.connections) {
1745 if (cr.binding != null && cr.binding.service != null
1746 && cr.binding.service.app != null
1747 && cr.binding.service.app.lruSeq != mLruSeq) {
1748 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1749 updateActivityTime, i+1);
1750 }
1751 }
1752 }
1753 if (app.conProviders.size() > 0) {
1754 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001755 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1756 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001757 updateActivityTime, i+1);
1758 }
1759 }
1760 }
1761
Joe Onorato8a9b2202010-02-26 18:56:32 -08001762 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763 if (oomAdj) {
1764 updateOomAdjLocked();
1765 }
1766 }
1767
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001768 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001769 boolean oomAdj, boolean updateActivityTime) {
1770 mLruSeq++;
1771 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1772 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001773
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001774 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 String processName, int uid) {
1776 if (uid == Process.SYSTEM_UID) {
1777 // The system gets to run in any process. If there are multiple
1778 // processes with the same uid, just pick the first (this
1779 // should never happen).
1780 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1781 processName);
1782 return procs != null ? procs.valueAt(0) : null;
1783 }
1784 ProcessRecord proc = mProcessNames.get(processName, uid);
1785 return proc;
1786 }
1787
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001788 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001789 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001790 try {
1791 if (pm.performDexOpt(packageName)) {
1792 mDidDexOpt = true;
1793 }
1794 } catch (RemoteException e) {
1795 }
1796 }
1797
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001798 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 int transit = mWindowManager.getPendingAppTransition();
1800 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1801 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1802 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1803 }
1804
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001805 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001807 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1809 // We don't have to do anything more if:
1810 // (1) There is an existing application record; and
1811 // (2) The caller doesn't think it is dead, OR there is no thread
1812 // object attached to it so we know it couldn't have crashed; and
1813 // (3) There is a pid assigned to it, so it is either starting or
1814 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001815 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 + " app=" + app + " knownToBeDead=" + knownToBeDead
1817 + " thread=" + (app != null ? app.thread : null)
1818 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001819 if (app != null && app.pid > 0) {
1820 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001821 // We already have the app running, or are waiting for it to
1822 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001823 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001824 // If this is a new package in the process, add the package to the list
1825 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001826 return app;
1827 } else {
1828 // An application record is attached to a previous process,
1829 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001830 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001831 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 String hostingNameStr = hostingName != null
1836 ? hostingName.flattenToShortString() : null;
1837
1838 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1839 // If we are in the background, then check to see if this process
1840 // is bad. If so, we will just silently fail.
1841 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001842 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1843 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844 return null;
1845 }
1846 } else {
1847 // When the user is explicitly starting a process, then clear its
1848 // crash count so that we won't make it bad until they see at
1849 // least one crash dialog again, and make the process good again
1850 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001851 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1852 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 mProcessCrashTimes.remove(info.processName, info.uid);
1854 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001855 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 info.processName);
1857 mBadProcesses.remove(info.processName, info.uid);
1858 if (app != null) {
1859 app.bad = false;
1860 }
1861 }
1862 }
1863
1864 if (app == null) {
1865 app = newProcessRecordLocked(null, info, processName);
1866 mProcessNames.put(processName, info.uid, app);
1867 } else {
1868 // If this is a new package in the process, add the package to the list
1869 app.addPackage(info.packageName);
1870 }
1871
1872 // If the system is not ready yet, then hold off on starting this
1873 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001874 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001875 && !isAllowedWhileBooting(info)
1876 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001877 if (!mProcessesOnHold.contains(app)) {
1878 mProcessesOnHold.add(app);
1879 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001880 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 return app;
1882 }
1883
1884 startProcessLocked(app, hostingType, hostingNameStr);
1885 return (app.pid != 0) ? app : null;
1886 }
1887
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001888 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1889 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1890 }
1891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 private final void startProcessLocked(ProcessRecord app,
1893 String hostingType, String hostingNameStr) {
1894 if (app.pid > 0 && app.pid != MY_PID) {
1895 synchronized (mPidsSelfLocked) {
1896 mPidsSelfLocked.remove(app.pid);
1897 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1898 }
1899 app.pid = 0;
1900 }
1901
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001902 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1903 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001904 mProcessesOnHold.remove(app);
1905
1906 updateCpuStats();
1907
1908 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1909 mProcDeaths[0] = 0;
1910
1911 try {
1912 int uid = app.info.uid;
1913 int[] gids = null;
1914 try {
1915 gids = mContext.getPackageManager().getPackageGids(
1916 app.info.packageName);
1917 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001918 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001919 }
1920 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1921 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1922 && mTopComponent != null
1923 && app.processName.equals(mTopComponent.getPackageName())) {
1924 uid = 0;
1925 }
1926 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1927 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1928 uid = 0;
1929 }
1930 }
1931 int debugFlags = 0;
1932 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1933 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001934 // Also turn on CheckJNI for debuggable apps. It's quite
1935 // awkward to turn on otherwise.
1936 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001937 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001938 // Run the app in safe mode if its manifest requests so or the
1939 // system is booted in safe mode.
1940 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1941 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001942 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001944 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1945 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1946 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001947 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1948 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001950 if ("1".equals(SystemProperties.get("debug.assert"))) {
1951 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1952 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001953
1954 // Start the process. It will either succeed and return a result containing
1955 // the PID of the new process, or else throw a RuntimeException.
1956 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001957 app.processName, uid, uid, gids, debugFlags,
1958 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1961 synchronized (bs) {
1962 if (bs.isOnBattery()) {
1963 app.batteryStats.incStartsLocked();
1964 }
1965 }
1966
Jeff Brown3f9dd282011-07-08 20:02:19 -07001967 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 app.processName, hostingType,
1969 hostingNameStr != null ? hostingNameStr : "");
1970
1971 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001972 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001973 }
1974
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001975 StringBuilder buf = mStringBuilder;
1976 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 buf.append("Start proc ");
1978 buf.append(app.processName);
1979 buf.append(" for ");
1980 buf.append(hostingType);
1981 if (hostingNameStr != null) {
1982 buf.append(" ");
1983 buf.append(hostingNameStr);
1984 }
1985 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001986 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 buf.append(" uid=");
1988 buf.append(uid);
1989 buf.append(" gids={");
1990 if (gids != null) {
1991 for (int gi=0; gi<gids.length; gi++) {
1992 if (gi != 0) buf.append(", ");
1993 buf.append(gids[gi]);
1994
1995 }
1996 }
1997 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001998 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001999 app.pid = startResult.pid;
2000 app.usingWrapper = startResult.usingWrapper;
2001 app.removed = false;
2002 synchronized (mPidsSelfLocked) {
2003 this.mPidsSelfLocked.put(startResult.pid, app);
2004 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2005 msg.obj = app;
2006 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2007 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008 }
2009 } catch (RuntimeException e) {
2010 // XXX do better error recovery.
2011 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002012 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 }
2014 }
2015
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002016 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 if (resumed) {
2018 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2019 } else {
2020 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2021 }
2022 }
2023
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002024 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002025 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2026 && mTopAction == null) {
2027 // We are running in factory test mode, but unable to find
2028 // the factory test app, so just sit around displaying the
2029 // error message and don't try to start anything.
2030 return false;
2031 }
2032 Intent intent = new Intent(
2033 mTopAction,
2034 mTopData != null ? Uri.parse(mTopData) : null);
2035 intent.setComponent(mTopComponent);
2036 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2037 intent.addCategory(Intent.CATEGORY_HOME);
2038 }
2039 ActivityInfo aInfo =
2040 intent.resolveActivityInfo(mContext.getPackageManager(),
2041 STOCK_PM_FLAGS);
2042 if (aInfo != null) {
2043 intent.setComponent(new ComponentName(
2044 aInfo.applicationInfo.packageName, aInfo.name));
2045 // Don't do this if the home app is currently being
2046 // instrumented.
2047 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2048 aInfo.applicationInfo.uid);
2049 if (app == null || app.instrumentationClass == null) {
2050 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002051 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002052 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002053 }
2054 }
2055
2056
2057 return true;
2058 }
2059
2060 /**
2061 * Starts the "new version setup screen" if appropriate.
2062 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002063 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002064 // Only do this once per boot.
2065 if (mCheckedForSetup) {
2066 return;
2067 }
2068
2069 // We will show this screen if the current one is a different
2070 // version than the last one shown, and we are not running in
2071 // low-level factory test mode.
2072 final ContentResolver resolver = mContext.getContentResolver();
2073 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2074 Settings.Secure.getInt(resolver,
2075 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2076 mCheckedForSetup = true;
2077
2078 // See if we should be showing the platform update setup UI.
2079 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2080 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2081 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2082
2083 // We don't allow third party apps to replace this.
2084 ResolveInfo ri = null;
2085 for (int i=0; ris != null && i<ris.size(); i++) {
2086 if ((ris.get(i).activityInfo.applicationInfo.flags
2087 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2088 ri = ris.get(i);
2089 break;
2090 }
2091 }
2092
2093 if (ri != null) {
2094 String vers = ri.activityInfo.metaData != null
2095 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2096 : null;
2097 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2098 vers = ri.activityInfo.applicationInfo.metaData.getString(
2099 Intent.METADATA_SETUP_VERSION);
2100 }
2101 String lastVers = Settings.Secure.getString(
2102 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2103 if (vers != null && !vers.equals(lastVers)) {
2104 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2105 intent.setComponent(new ComponentName(
2106 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002107 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002108 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002109 }
2110 }
2111 }
2112 }
2113
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002114 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002115 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002116 }
2117
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002118 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002119 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002120 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2121 }
2122 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002123
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002124 public void setFrontActivityScreenCompatMode(int mode) {
2125 synchronized (this) {
2126 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2127 }
2128 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002129
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002130 public int getPackageScreenCompatMode(String packageName) {
2131 synchronized (this) {
2132 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2133 }
2134 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002135
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002136 public void setPackageScreenCompatMode(String packageName, int mode) {
2137 synchronized (this) {
2138 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002139 }
2140 }
2141
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002142 public boolean getPackageAskScreenCompat(String packageName) {
2143 synchronized (this) {
2144 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2145 }
2146 }
2147
2148 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2149 synchronized (this) {
2150 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2151 }
2152 }
2153
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002154 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002155 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002156
2157 final int identHash = System.identityHashCode(r);
2158 updateUsageStats(r, true);
2159
2160 int i = mWatchers.beginBroadcast();
2161 while (i > 0) {
2162 i--;
2163 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2164 if (w != null) {
2165 try {
2166 w.activityResuming(identHash);
2167 } catch (RemoteException e) {
2168 }
2169 }
2170 }
2171 mWatchers.finishBroadcast();
2172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173
Jeff Sharkeya4620792011-05-20 15:29:23 -07002174 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2175 int i = mProcessObservers.beginBroadcast();
2176 while (i > 0) {
2177 i--;
2178 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2179 if (observer != null) {
2180 try {
2181 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2182 } catch (RemoteException e) {
2183 }
2184 }
2185 }
2186 mProcessObservers.finishBroadcast();
2187 }
2188
2189 private void dispatchProcessDied(int pid, int uid) {
2190 int i = mProcessObservers.beginBroadcast();
2191 while (i > 0) {
2192 i--;
2193 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2194 if (observer != null) {
2195 try {
2196 observer.onProcessDied(pid, uid);
2197 } catch (RemoteException e) {
2198 }
2199 }
2200 }
2201 mProcessObservers.finishBroadcast();
2202 }
2203
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002204 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002205 final int N = mPendingActivityLaunches.size();
2206 if (N <= 0) {
2207 return;
2208 }
2209 for (int i=0; i<N; i++) {
2210 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002211 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002212 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2213 doResume && i == (N-1));
2214 }
2215 mPendingActivityLaunches.clear();
2216 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002217
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002218 public final int startActivity(IApplicationThread caller,
2219 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2220 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002221 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2222 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002223 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002224 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002225 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2226 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002227 }
2228
2229 public final WaitResult startActivityAndWait(IApplicationThread caller,
2230 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2231 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002232 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2233 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002234 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002235 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002236 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002237 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2238 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002239 return res;
2240 }
2241
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002242 public final int startActivityWithConfig(IApplicationThread caller,
2243 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2244 int grantedMode, IBinder resultTo,
2245 String resultWho, int requestCode, boolean onlyIfNeeded,
2246 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002247 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002248 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002249 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002250 }
2251
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002252 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002253 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002254 IBinder resultTo, String resultWho, int requestCode,
2255 int flagsMask, int flagsValues) {
2256 // Refuse possible leaked file descriptors
2257 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2258 throw new IllegalArgumentException("File descriptors passed in Intent");
2259 }
2260
2261 IIntentSender sender = intent.getTarget();
2262 if (!(sender instanceof PendingIntentRecord)) {
2263 throw new IllegalArgumentException("Bad PendingIntent object");
2264 }
2265
2266 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002267
2268 synchronized (this) {
2269 // If this is coming from the currently resumed activity, it is
2270 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002271 if (mMainStack.mResumedActivity != null
2272 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002273 Binder.getCallingUid()) {
2274 mAppSwitchesAllowedTime = 0;
2275 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002276 }
2277
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002278 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002279 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2280 }
2281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 public boolean startNextMatchingActivity(IBinder callingActivity,
2283 Intent intent) {
2284 // Refuse possible leaked file descriptors
2285 if (intent != null && intent.hasFileDescriptors() == true) {
2286 throw new IllegalArgumentException("File descriptors passed in Intent");
2287 }
2288
2289 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002290 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2291 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 return false;
2293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 if (r.app == null || r.app.thread == null) {
2295 // The caller is not running... d'oh!
2296 return false;
2297 }
2298 intent = new Intent(intent);
2299 // The caller is not allowed to change the data.
2300 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2301 // And we are resetting to find the next component...
2302 intent.setComponent(null);
2303
2304 ActivityInfo aInfo = null;
2305 try {
2306 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002307 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002308 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002309 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310
2311 // Look for the original activity in the list...
2312 final int N = resolves != null ? resolves.size() : 0;
2313 for (int i=0; i<N; i++) {
2314 ResolveInfo rInfo = resolves.get(i);
2315 if (rInfo.activityInfo.packageName.equals(r.packageName)
2316 && rInfo.activityInfo.name.equals(r.info.name)) {
2317 // We found the current one... the next matching is
2318 // after it.
2319 i++;
2320 if (i<N) {
2321 aInfo = resolves.get(i).activityInfo;
2322 }
2323 break;
2324 }
2325 }
2326 } catch (RemoteException e) {
2327 }
2328
2329 if (aInfo == null) {
2330 // Nobody who is next!
2331 return false;
2332 }
2333
2334 intent.setComponent(new ComponentName(
2335 aInfo.applicationInfo.packageName, aInfo.name));
2336 intent.setFlags(intent.getFlags()&~(
2337 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2338 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2339 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2340 Intent.FLAG_ACTIVITY_NEW_TASK));
2341
2342 // Okay now we need to start the new activity, replacing the
2343 // currently running activity. This is a little tricky because
2344 // we want to start the new one as if the current one is finished,
2345 // but not finish the current one first so that there is no flicker.
2346 // And thus...
2347 final boolean wasFinishing = r.finishing;
2348 r.finishing = true;
2349
2350 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002351 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 final String resultWho = r.resultWho;
2353 final int requestCode = r.requestCode;
2354 r.resultTo = null;
2355 if (resultTo != null) {
2356 resultTo.removeResultsLocked(r, resultWho, requestCode);
2357 }
2358
2359 final long origId = Binder.clearCallingIdentity();
2360 // XXX we are not dealing with propagating grantedUriPermissions...
2361 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002362 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002363 r.resolvedType, null, 0, aInfo,
2364 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002365 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 Binder.restoreCallingIdentity(origId);
2367
2368 r.finishing = wasFinishing;
2369 if (res != START_SUCCESS) {
2370 return false;
2371 }
2372 return true;
2373 }
2374 }
2375
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002376 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 Intent intent, String resolvedType, IBinder resultTo,
2378 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002379
2380 // This is so super not safe, that only the system (or okay root)
2381 // can do it.
2382 final int callingUid = Binder.getCallingUid();
2383 if (callingUid != 0 && callingUid != Process.myUid()) {
2384 throw new SecurityException(
2385 "startActivityInPackage only available to the system");
2386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002388 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002389 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2390 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002391 }
2392
2393 public final int startActivities(IApplicationThread caller,
2394 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2395 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2396 }
2397
2398 public final int startActivitiesInPackage(int uid,
2399 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2400
2401 // This is so super not safe, that only the system (or okay root)
2402 // can do it.
2403 final int callingUid = Binder.getCallingUid();
2404 if (callingUid != 0 && callingUid != Process.myUid()) {
2405 throw new SecurityException(
2406 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 }
2408
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002409 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002410 }
2411
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002412 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002414 // Quick case: check if the top-most recent task is the same.
2415 if (N > 0 && mRecentTasks.get(0) == task) {
2416 return;
2417 }
2418 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 for (int i=0; i<N; i++) {
2420 TaskRecord tr = mRecentTasks.get(i);
2421 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2422 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2423 mRecentTasks.remove(i);
2424 i--;
2425 N--;
2426 if (task.intent == null) {
2427 // If the new recent task we are adding is not fully
2428 // specified, then replace it with the existing recent task.
2429 task = tr;
2430 }
2431 }
2432 }
2433 if (N >= MAX_RECENT_TASKS) {
2434 mRecentTasks.remove(N-1);
2435 }
2436 mRecentTasks.add(0, task);
2437 }
2438
2439 public void setRequestedOrientation(IBinder token,
2440 int requestedOrientation) {
2441 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002442 ActivityRecord r = mMainStack.isInStackLocked(token);
2443 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 return;
2445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002447 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002449 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002450 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 if (config != null) {
2452 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002453 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002454 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 }
2456 }
2457 Binder.restoreCallingIdentity(origId);
2458 }
2459 }
2460
2461 public int getRequestedOrientation(IBinder token) {
2462 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002463 ActivityRecord r = mMainStack.isInStackLocked(token);
2464 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2466 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002467 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 }
2469 }
2470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002471 /**
2472 * This is the internal entry point for handling Activity.finish().
2473 *
2474 * @param token The Binder token referencing the Activity we want to finish.
2475 * @param resultCode Result code, if any, from this Activity.
2476 * @param resultData Result data (Intent), if any, from this Activity.
2477 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002478 * @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 -08002479 */
2480 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2481 // Refuse possible leaked file descriptors
2482 if (resultData != null && resultData.hasFileDescriptors() == true) {
2483 throw new IllegalArgumentException("File descriptors passed in Intent");
2484 }
2485
2486 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002487 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002489 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 if (next != null) {
2491 // ask watcher if this is allowed
2492 boolean resumeOK = true;
2493 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002494 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002496 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 }
2498
2499 if (!resumeOK) {
2500 return false;
2501 }
2502 }
2503 }
2504 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002505 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 resultData, "app-request");
2507 Binder.restoreCallingIdentity(origId);
2508 return res;
2509 }
2510 }
2511
Dianne Hackborn860755f2010-06-03 18:47:52 -07002512 public final void finishHeavyWeightApp() {
2513 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2514 != PackageManager.PERMISSION_GRANTED) {
2515 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2516 + Binder.getCallingPid()
2517 + ", uid=" + Binder.getCallingUid()
2518 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2519 Slog.w(TAG, msg);
2520 throw new SecurityException(msg);
2521 }
2522
2523 synchronized(this) {
2524 if (mHeavyWeightProcess == null) {
2525 return;
2526 }
2527
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002528 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002529 mHeavyWeightProcess.activities);
2530 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002531 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002532 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002533 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002534 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002535 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002536 null, "finish-heavy");
2537 }
2538 }
2539 }
2540
2541 mHeavyWeightProcess = null;
2542 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2543 }
2544 }
2545
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002546 public void crashApplication(int uid, int initialPid, String packageName,
2547 String message) {
2548 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2549 != PackageManager.PERMISSION_GRANTED) {
2550 String msg = "Permission Denial: crashApplication() from pid="
2551 + Binder.getCallingPid()
2552 + ", uid=" + Binder.getCallingUid()
2553 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2554 Slog.w(TAG, msg);
2555 throw new SecurityException(msg);
2556 }
2557
2558 synchronized(this) {
2559 ProcessRecord proc = null;
2560
2561 // Figure out which process to kill. We don't trust that initialPid
2562 // still has any relation to current pids, so must scan through the
2563 // list.
2564 synchronized (mPidsSelfLocked) {
2565 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2566 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2567 if (p.info.uid != uid) {
2568 continue;
2569 }
2570 if (p.pid == initialPid) {
2571 proc = p;
2572 break;
2573 }
2574 for (String str : p.pkgList) {
2575 if (str.equals(packageName)) {
2576 proc = p;
2577 }
2578 }
2579 }
2580 }
2581
2582 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002583 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002584 + " initialPid=" + initialPid
2585 + " packageName=" + packageName);
2586 return;
2587 }
2588
2589 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002590 if (proc.pid == Process.myPid()) {
2591 Log.w(TAG, "crashApplication: trying to crash self!");
2592 return;
2593 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002594 long ident = Binder.clearCallingIdentity();
2595 try {
2596 proc.thread.scheduleCrash(message);
2597 } catch (RemoteException e) {
2598 }
2599 Binder.restoreCallingIdentity(ident);
2600 }
2601 }
2602 }
2603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002604 public final void finishSubActivity(IBinder token, String resultWho,
2605 int requestCode) {
2606 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002607 ActivityRecord self = mMainStack.isInStackLocked(token);
2608 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 return;
2610 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611
2612 final long origId = Binder.clearCallingIdentity();
2613
2614 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002615 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2616 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 if (r.resultTo == self && r.requestCode == requestCode) {
2618 if ((r.resultWho == null && resultWho == null) ||
2619 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002620 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 Activity.RESULT_CANCELED, null, "request-sub");
2622 }
2623 }
2624 }
2625
2626 Binder.restoreCallingIdentity(origId);
2627 }
2628 }
2629
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002630 public boolean willActivityBeVisible(IBinder token) {
2631 synchronized(this) {
2632 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002633 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2634 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002635 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002636 return true;
2637 }
2638 if (r.fullscreen && !r.finishing) {
2639 return false;
2640 }
2641 }
2642 return true;
2643 }
2644 }
2645
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002646 public void overridePendingTransition(IBinder token, String packageName,
2647 int enterAnim, int exitAnim) {
2648 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002649 ActivityRecord self = mMainStack.isInStackLocked(token);
2650 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002651 return;
2652 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002653
2654 final long origId = Binder.clearCallingIdentity();
2655
2656 if (self.state == ActivityState.RESUMED
2657 || self.state == ActivityState.PAUSING) {
2658 mWindowManager.overridePendingAppTransition(packageName,
2659 enterAnim, exitAnim);
2660 }
2661
2662 Binder.restoreCallingIdentity(origId);
2663 }
2664 }
2665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 * Main function for removing an existing process from the activity manager
2668 * as a result of that process going away. Clears out all connections
2669 * to the process.
2670 */
2671 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002672 boolean restarting, boolean allowRestart) {
2673 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002675 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 }
2677
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002678 if (mProfileProc == app) {
2679 clearProfilerLocked();
2680 }
2681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002683 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2684 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2685 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002687 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2688 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689 }
2690
2691 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002692 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002693
2694 boolean atTop = true;
2695 boolean hasVisibleActivities = false;
2696
2697 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002698 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002699 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002700 TAG, "Removing app " + app + " from history with " + i + " entries");
2701 while (i > 0) {
2702 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002703 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002704 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2706 if (r.app == app) {
2707 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002708 if (ActivityStack.DEBUG_ADD_REMOVE) {
2709 RuntimeException here = new RuntimeException("here");
2710 here.fillInStackTrace();
2711 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2712 + ": haveState=" + r.haveState
2713 + " stateNotNeeded=" + r.stateNotNeeded
2714 + " finishing=" + r.finishing
2715 + " state=" + r.state, here);
2716 }
2717 if (!r.finishing) {
2718 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2719 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002720 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002721 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002722 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002723 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002725 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002727 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002728
2729 } else {
2730 // We have the current state for this activity, so
2731 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002732 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 TAG, "Keeping entry, setting app to null");
2734 if (r.visible) {
2735 hasVisibleActivities = true;
2736 }
2737 r.app = null;
2738 r.nowVisible = false;
2739 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002740 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2741 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 r.icicle = null;
2743 }
2744 }
2745
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002746 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 }
2748 atTop = false;
2749 }
2750
2751 app.activities.clear();
2752
2753 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002754 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 + " running instrumentation " + app.instrumentationClass);
2756 Bundle info = new Bundle();
2757 info.putString("shortMsg", "Process crashed.");
2758 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2759 }
2760
2761 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002762 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 // If there was nothing to resume, and we are not already
2764 // restarting this process, but there is a visible activity that
2765 // is hosted by the process... then make sure all visible
2766 // activities are running, taking care of restarting this
2767 // process.
2768 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002769 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 }
2771 }
2772 }
2773 }
2774
2775 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2776 IBinder threadBinder = thread.asBinder();
2777
2778 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002779 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2780 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002781 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2782 return i;
2783 }
2784 }
2785 return -1;
2786 }
2787
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002788 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 IApplicationThread thread) {
2790 if (thread == null) {
2791 return null;
2792 }
2793
2794 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002795 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796 }
2797
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002798 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002799 IApplicationThread thread) {
2800
2801 mProcDeaths[0]++;
2802
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002803 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2804 synchronized (stats) {
2805 stats.noteProcessDiedLocked(app.info.uid, pid);
2806 }
2807
Magnus Edlund7bb25812010-02-24 15:45:06 +01002808 // Clean up already done if the process has been re-started.
2809 if (app.pid == pid && app.thread != null &&
2810 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002811 if (!app.killedBackground) {
2812 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2813 + ") has died.");
2814 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002815 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002816 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817 TAG, "Dying app: " + app + ", pid: " + pid
2818 + ", thread: " + thread.asBinder());
2819 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002820 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821
2822 if (doLowMem) {
2823 // If there are no longer any background processes running,
2824 // and the app that died was not running instrumentation,
2825 // then tell everyone we are now low on memory.
2826 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002827 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2828 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002829 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 haveBg = true;
2831 break;
2832 }
2833 }
2834
2835 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002836 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002837 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002838 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2839 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002840 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002841 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2842 // The low memory report is overriding any current
2843 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002844 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002845 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002846 rec.lastRequestedGc = 0;
2847 } else {
2848 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002849 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002850 rec.reportLowMemory = true;
2851 rec.lastLowMemory = now;
2852 mProcessesToGc.remove(rec);
2853 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854 }
2855 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002856 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002857 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 }
2859 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002860 } else if (app.pid != pid) {
2861 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002862 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002863 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002864 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002865 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002866 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002867 + thread.asBinder());
2868 }
2869 }
2870
Dan Egnor42471dd2010-01-07 17:25:22 -08002871 /**
2872 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002873 * @param clearTraces causes the dump file to be erased prior to the new
2874 * traces being written, if true; when false, the new traces will be
2875 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002876 * @param firstPids of dalvik VM processes to dump stack traces for first
2877 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002878 * @return file containing stack traces, or null if no dump file is configured
2879 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002880 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2881 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002882 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2883 if (tracesPath == null || tracesPath.length() == 0) {
2884 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002885 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002886
2887 File tracesFile = new File(tracesPath);
2888 try {
2889 File tracesDir = tracesFile.getParentFile();
2890 if (!tracesDir.exists()) tracesFile.mkdirs();
2891 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2892
Christopher Tate6ee412d2010-05-28 12:01:56 -07002893 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002894 tracesFile.createNewFile();
2895 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2896 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002897 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002898 return null;
2899 }
2900
2901 // Use a FileObserver to detect when traces finish writing.
2902 // The order of traces is considered important to maintain for legibility.
2903 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2904 public synchronized void onEvent(int event, String path) { notify(); }
2905 };
2906
2907 try {
2908 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002909
2910 // First collect all of the stacks of the most important pids.
2911 try {
2912 int num = firstPids.size();
2913 for (int i = 0; i < num; i++) {
2914 synchronized (observer) {
2915 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2916 observer.wait(200); // Wait for write-close, give up after 200msec
2917 }
2918 }
2919 } catch (InterruptedException e) {
2920 Log.wtf(TAG, e);
2921 }
2922
2923 // Next measure CPU usage.
2924 if (processStats != null) {
2925 processStats.init();
2926 System.gc();
2927 processStats.update();
2928 try {
2929 synchronized (processStats) {
2930 processStats.wait(500); // measure over 1/2 second.
2931 }
2932 } catch (InterruptedException e) {
2933 }
2934 processStats.update();
2935
2936 // We'll take the stack crawls of just the top apps using CPU.
2937 final int N = processStats.countWorkingStats();
2938 int numProcs = 0;
2939 for (int i=0; i<N && numProcs<5; i++) {
2940 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2941 if (lastPids.indexOfKey(stats.pid) >= 0) {
2942 numProcs++;
2943 try {
2944 synchronized (observer) {
2945 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2946 observer.wait(200); // Wait for write-close, give up after 200msec
2947 }
2948 } catch (InterruptedException e) {
2949 Log.wtf(TAG, e);
2950 }
2951
2952 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 }
2954 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002955
2956 return tracesFile;
2957
Dan Egnor42471dd2010-01-07 17:25:22 -08002958 } finally {
2959 observer.stopWatching();
2960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 }
2962
Jeff Brown4d94a762010-09-23 11:33:28 -07002963 private final class AppNotResponding implements Runnable {
2964 private final ProcessRecord mApp;
2965 private final String mAnnotation;
2966
2967 public AppNotResponding(ProcessRecord app, String annotation) {
2968 mApp = app;
2969 mAnnotation = annotation;
2970 }
2971
2972 @Override
2973 public void run() {
2974 appNotResponding(mApp, null, null, mAnnotation);
2975 }
2976 }
2977
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002978 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2979 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002980 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2981 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2982
Dianne Hackborn287952c2010-09-22 22:34:31 -07002983 if (mController != null) {
2984 try {
2985 // 0 == continue, -1 = kill process immediately
2986 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2987 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2988 } catch (RemoteException e) {
2989 mController = null;
2990 }
2991 }
2992
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002993 long anrTime = SystemClock.uptimeMillis();
2994 if (MONITOR_CPU_USAGE) {
2995 updateCpuStatsNow();
2996 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002997
2998 synchronized (this) {
2999 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3000 if (mShuttingDown) {
3001 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3002 return;
3003 } else if (app.notResponding) {
3004 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3005 return;
3006 } else if (app.crashing) {
3007 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3008 return;
3009 }
3010
3011 // In case we come through here for the same app before completing
3012 // this one, mark as anring now so we will bail out.
3013 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003014
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003015 // Log the ANR to the event log.
3016 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3017 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003018
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003019 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003020 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003021
3022 int parentPid = app.pid;
3023 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003024 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003025
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003026 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003027
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003028 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3029 ProcessRecord r = mLruProcesses.get(i);
3030 if (r != null && r.thread != null) {
3031 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003032 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3033 if (r.persistent) {
3034 firstPids.add(pid);
3035 } else {
3036 lastPids.put(pid, Boolean.TRUE);
3037 }
3038 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 }
3041 }
3042
Dan Egnor42471dd2010-01-07 17:25:22 -08003043 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003044 StringBuilder info = mStringBuilder;
3045 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003046 info.append("ANR in ").append(app.processName);
3047 if (activity != null && activity.shortComponentName != null) {
3048 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003049 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003050 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003051 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003052 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003054 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003055 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057
Dianne Hackborn287952c2010-09-22 22:34:31 -07003058 final ProcessStats processStats = new ProcessStats(true);
3059
3060 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3061
Dan Egnor42471dd2010-01-07 17:25:22 -08003062 String cpuInfo = null;
3063 if (MONITOR_CPU_USAGE) {
3064 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003065 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003066 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003067 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003068 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003069 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003070 }
3071
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003072 info.append(processStats.printCurrentState(anrTime));
3073
Joe Onorato8a9b2202010-02-26 18:56:32 -08003074 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003075 if (tracesFile == null) {
3076 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3077 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3078 }
3079
Jeff Sharkeya353d262011-10-28 11:12:06 -07003080 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3081 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003082
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003083 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003085 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3086 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003088 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3089 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003090 }
3091 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003092 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 }
3094 }
3095
Dan Egnor42471dd2010-01-07 17:25:22 -08003096 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3097 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3098 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003099
3100 synchronized (this) {
3101 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003102 Slog.w(TAG, "Killing " + app + ": background ANR");
3103 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3104 app.processName, app.setAdj, "background ANR");
3105 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003106 return;
3107 }
3108
3109 // Set the app's notResponding state, and look up the errorReportReceiver
3110 makeAppNotRespondingLocked(app,
3111 activity != null ? activity.shortComponentName : null,
3112 annotation != null ? "ANR " + annotation : "ANR",
3113 info.toString());
3114
3115 // Bring up the infamous App Not Responding dialog
3116 Message msg = Message.obtain();
3117 HashMap map = new HashMap();
3118 msg.what = SHOW_NOT_RESPONDING_MSG;
3119 msg.obj = map;
3120 map.put("app", app);
3121 if (activity != null) {
3122 map.put("activity", activity);
3123 }
3124
3125 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 }
3128
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003129 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3130 if (!mLaunchWarningShown) {
3131 mLaunchWarningShown = true;
3132 mHandler.post(new Runnable() {
3133 @Override
3134 public void run() {
3135 synchronized (ActivityManagerService.this) {
3136 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3137 d.show();
3138 mHandler.postDelayed(new Runnable() {
3139 @Override
3140 public void run() {
3141 synchronized (ActivityManagerService.this) {
3142 d.dismiss();
3143 mLaunchWarningShown = false;
3144 }
3145 }
3146 }, 4000);
3147 }
3148 }
3149 });
3150 }
3151 }
3152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 public boolean clearApplicationUserData(final String packageName,
3154 final IPackageDataObserver observer) {
3155 int uid = Binder.getCallingUid();
3156 int pid = Binder.getCallingPid();
3157 long callingId = Binder.clearCallingIdentity();
3158 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003159 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 int pkgUid = -1;
3161 synchronized(this) {
3162 try {
3163 pkgUid = pm.getPackageUid(packageName);
3164 } catch (RemoteException e) {
3165 }
3166 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003167 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003168 return false;
3169 }
3170 if (uid == pkgUid || checkComponentPermission(
3171 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003172 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003174 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003175 } else {
3176 throw new SecurityException(pid+" does not have permission:"+
3177 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3178 "for process:"+packageName);
3179 }
3180 }
3181
3182 try {
3183 //clear application user data
3184 pm.clearApplicationUserData(packageName, observer);
3185 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3186 Uri.fromParts("package", packageName, null));
3187 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003188 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3189 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 } catch (RemoteException e) {
3191 }
3192 } finally {
3193 Binder.restoreCallingIdentity(callingId);
3194 }
3195 return true;
3196 }
3197
Dianne Hackborn03abb812010-01-04 18:43:19 -08003198 public void killBackgroundProcesses(final String packageName) {
3199 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3200 != PackageManager.PERMISSION_GRANTED &&
3201 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3202 != PackageManager.PERMISSION_GRANTED) {
3203 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003204 + Binder.getCallingPid()
3205 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003206 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003207 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 throw new SecurityException(msg);
3209 }
3210
3211 long callingId = Binder.clearCallingIdentity();
3212 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003213 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 int pkgUid = -1;
3215 synchronized(this) {
3216 try {
3217 pkgUid = pm.getPackageUid(packageName);
3218 } catch (RemoteException e) {
3219 }
3220 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003221 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003222 return;
3223 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003224 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003225 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3226 }
3227 } finally {
3228 Binder.restoreCallingIdentity(callingId);
3229 }
3230 }
3231
3232 public void killAllBackgroundProcesses() {
3233 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3234 != PackageManager.PERMISSION_GRANTED) {
3235 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3236 + Binder.getCallingPid()
3237 + ", uid=" + Binder.getCallingUid()
3238 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3239 Slog.w(TAG, msg);
3240 throw new SecurityException(msg);
3241 }
3242
3243 long callingId = Binder.clearCallingIdentity();
3244 try {
3245 synchronized(this) {
3246 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3247 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3248 final int NA = apps.size();
3249 for (int ia=0; ia<NA; ia++) {
3250 ProcessRecord app = apps.valueAt(ia);
3251 if (app.persistent) {
3252 // we don't kill persistent processes
3253 continue;
3254 }
3255 if (app.removed) {
3256 procs.add(app);
3257 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3258 app.removed = true;
3259 procs.add(app);
3260 }
3261 }
3262 }
3263
3264 int N = procs.size();
3265 for (int i=0; i<N; i++) {
3266 removeProcessLocked(procs.get(i), false, true, "kill all background");
3267 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003268 }
3269 } finally {
3270 Binder.restoreCallingIdentity(callingId);
3271 }
3272 }
3273
3274 public void forceStopPackage(final String packageName) {
3275 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3276 != PackageManager.PERMISSION_GRANTED) {
3277 String msg = "Permission Denial: forceStopPackage() from pid="
3278 + Binder.getCallingPid()
3279 + ", uid=" + Binder.getCallingUid()
3280 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003281 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003282 throw new SecurityException(msg);
3283 }
3284
3285 long callingId = Binder.clearCallingIdentity();
3286 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003287 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003288 int pkgUid = -1;
3289 synchronized(this) {
3290 try {
3291 pkgUid = pm.getPackageUid(packageName);
3292 } catch (RemoteException e) {
3293 }
3294 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003295 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003296 return;
3297 }
3298 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003299 try {
3300 pm.setPackageStoppedState(packageName, true);
3301 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003302 } catch (IllegalArgumentException e) {
3303 Slog.w(TAG, "Failed trying to unstop package "
3304 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306 }
3307 } finally {
3308 Binder.restoreCallingIdentity(callingId);
3309 }
3310 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003311
3312 /*
3313 * The pkg name and uid have to be specified.
3314 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3315 */
3316 public void killApplicationWithUid(String pkg, int uid) {
3317 if (pkg == null) {
3318 return;
3319 }
3320 // Make sure the uid is valid.
3321 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003322 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003323 return;
3324 }
3325 int callerUid = Binder.getCallingUid();
3326 // Only the system server can kill an application
3327 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003328 // Post an aysnc message to kill the application
3329 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3330 msg.arg1 = uid;
3331 msg.arg2 = 0;
3332 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003333 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003334 } else {
3335 throw new SecurityException(callerUid + " cannot kill pkg: " +
3336 pkg);
3337 }
3338 }
3339
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003340 public void closeSystemDialogs(String reason) {
3341 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003342 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003343 if (reason != null) {
3344 intent.putExtra("reason", reason);
3345 }
3346
3347 final int uid = Binder.getCallingUid();
3348 final long origId = Binder.clearCallingIdentity();
3349 synchronized (this) {
3350 int i = mWatchers.beginBroadcast();
3351 while (i > 0) {
3352 i--;
3353 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3354 if (w != null) {
3355 try {
3356 w.closingSystemDialogs(reason);
3357 } catch (RemoteException e) {
3358 }
3359 }
3360 }
3361 mWatchers.finishBroadcast();
3362
Dianne Hackbornffa42482009-09-23 22:20:11 -07003363 mWindowManager.closeSystemDialogs(reason);
3364
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003365 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3366 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003367 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003368 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003369 Activity.RESULT_CANCELED, null, "close-sys");
3370 }
3371 }
3372
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003373 broadcastIntentLocked(null, null, intent, null,
3374 null, 0, null, null, null, false, false, -1, uid);
3375 }
3376 Binder.restoreCallingIdentity(origId);
3377 }
3378
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003379 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003380 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003381 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3382 for (int i=pids.length-1; i>=0; i--) {
3383 infos[i] = new Debug.MemoryInfo();
3384 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003385 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003386 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003387 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003388
Dianne Hackbornb437e092011-08-05 17:50:29 -07003389 public long[] getProcessPss(int[] pids) throws RemoteException {
3390 long[] pss = new long[pids.length];
3391 for (int i=pids.length-1; i>=0; i--) {
3392 pss[i] = Debug.getPss(pids[i]);
3393 }
3394 return pss;
3395 }
3396
Christopher Tate5e1ab332009-09-01 20:32:49 -07003397 public void killApplicationProcess(String processName, int uid) {
3398 if (processName == null) {
3399 return;
3400 }
3401
3402 int callerUid = Binder.getCallingUid();
3403 // Only the system server can kill an application
3404 if (callerUid == Process.SYSTEM_UID) {
3405 synchronized (this) {
3406 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003407 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003408 try {
3409 app.thread.scheduleSuicide();
3410 } catch (RemoteException e) {
3411 // If the other end already died, then our work here is done.
3412 }
3413 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003414 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003415 + processName + " / " + uid);
3416 }
3417 }
3418 } else {
3419 throw new SecurityException(callerUid + " cannot kill app process: " +
3420 processName);
3421 }
3422 }
3423
Dianne Hackborn03abb812010-01-04 18:43:19 -08003424 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003425 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3427 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003428 if (!mProcessesReady) {
3429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003431 intent.putExtra(Intent.EXTRA_UID, uid);
3432 broadcastIntentLocked(null, null, intent,
3433 null, null, 0, null, null, null,
3434 false, false, MY_PID, Process.SYSTEM_UID);
3435 }
3436
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003437 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003438 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003439 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003440 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441
Dianne Hackborn03abb812010-01-04 18:43:19 -08003442 // Remove all processes this package may have touched: all with the
3443 // same UID (except for the system or root user), and all whose name
3444 // matches the package name.
3445 final String procNamePrefix = packageName + ":";
3446 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3447 final int NA = apps.size();
3448 for (int ia=0; ia<NA; ia++) {
3449 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003450 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003451 // we don't kill persistent processes
3452 continue;
3453 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003454 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003455 if (doit) {
3456 procs.add(app);
3457 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003458 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3459 || app.processName.equals(packageName)
3460 || app.processName.startsWith(procNamePrefix)) {
3461 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003462 if (!doit) {
3463 return true;
3464 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003465 app.removed = true;
3466 procs.add(app);
3467 }
3468 }
3469 }
3470 }
3471
3472 int N = procs.size();
3473 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003474 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003475 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003476 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003477 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003478
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003479 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003480 boolean callerWillRestart, boolean purgeCache, boolean doit,
3481 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003482 int i;
3483 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003485 if (uid < 0) {
3486 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003487 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 } catch (RemoteException e) {
3489 }
3490 }
3491
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003492 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003493 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003494
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003495 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3496 while (badApps.hasNext()) {
3497 SparseArray<Long> ba = badApps.next();
3498 if (ba.get(uid) != null) {
3499 badApps.remove();
3500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 }
3502 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003503
3504 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003505 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003507 TaskRecord lastTask = null;
3508 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003509 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003510 final boolean samePackage = r.packageName.equals(name);
3511 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003512 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003513 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003514 if (r.finishing) {
3515 // If this activity is just finishing, then it is not
3516 // interesting as far as something to stop.
3517 continue;
3518 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003519 return true;
3520 }
3521 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003522 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003523 if (samePackage) {
3524 if (r.app != null) {
3525 r.app.removed = true;
3526 }
3527 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003529 lastTask = r.task;
3530 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3531 null, "force-stop")) {
3532 i--;
3533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 }
3535 }
3536
3537 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3538 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003539 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003540 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003541 if (!doit) {
3542 return true;
3543 }
3544 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003545 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 if (service.app != null) {
3547 service.app.removed = true;
3548 }
3549 service.app = null;
3550 services.add(service);
3551 }
3552 }
3553
3554 N = services.size();
3555 for (i=0; i<N; i++) {
3556 bringDownServiceLocked(services.get(i), true);
3557 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003558
3559 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3560 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3561 if (provider.info.packageName.equals(name)
3562 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3563 if (!doit) {
3564 return true;
3565 }
3566 didSomething = true;
3567 providers.add(provider);
3568 }
3569 }
3570
3571 N = providers.size();
3572 for (i=0; i<N; i++) {
3573 removeDyingProviderLocked(null, providers.get(i));
3574 }
3575
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003576 if (doit) {
3577 if (purgeCache) {
3578 AttributeCache ac = AttributeCache.instance();
3579 if (ac != null) {
3580 ac.removePackage(name);
3581 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003582 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003583 if (mBooted) {
3584 mMainStack.resumeTopActivityLocked(null);
3585 mMainStack.scheduleIdleLocked();
3586 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003587 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003588
3589 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003590 }
3591
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003592 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003593 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 final String name = app.processName;
3595 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003596 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003597 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 + "/" + uid + ")");
3599
3600 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003601 if (mHeavyWeightProcess == app) {
3602 mHeavyWeightProcess = null;
3603 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 boolean needRestart = false;
3606 if (app.pid > 0 && app.pid != MY_PID) {
3607 int pid = app.pid;
3608 synchronized (mPidsSelfLocked) {
3609 mPidsSelfLocked.remove(pid);
3610 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3611 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003612 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003613 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003614 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003615 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616
3617 if (app.persistent) {
3618 if (!callerWillRestart) {
3619 addAppLocked(app.info);
3620 } else {
3621 needRestart = true;
3622 }
3623 }
3624 } else {
3625 mRemovedProcesses.add(app);
3626 }
3627
3628 return needRestart;
3629 }
3630
3631 private final void processStartTimedOutLocked(ProcessRecord app) {
3632 final int pid = app.pid;
3633 boolean gone = false;
3634 synchronized (mPidsSelfLocked) {
3635 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3636 if (knownApp != null && knownApp.thread == null) {
3637 mPidsSelfLocked.remove(pid);
3638 gone = true;
3639 }
3640 }
3641
3642 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003643 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003644 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003645 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003647 if (mHeavyWeightProcess == app) {
3648 mHeavyWeightProcess = null;
3649 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3650 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003651 // Take care of any launching providers waiting for this process.
3652 checkAppInLaunchingProvidersLocked(app, true);
3653 // Take care of any services that are waiting for the process.
3654 for (int i=0; i<mPendingServices.size(); i++) {
3655 ServiceRecord sr = mPendingServices.get(i);
3656 if (app.info.uid == sr.appInfo.uid
3657 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003658 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003659 mPendingServices.remove(i);
3660 i--;
3661 bringDownServiceLocked(sr, true);
3662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003664 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3665 app.processName, app.setAdj, "start timeout");
3666 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003667 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003668 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003669 try {
3670 IBackupManager bm = IBackupManager.Stub.asInterface(
3671 ServiceManager.getService(Context.BACKUP_SERVICE));
3672 bm.agentDisconnected(app.info.packageName);
3673 } catch (RemoteException e) {
3674 // Can't happen; the backup manager is local
3675 }
3676 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003677 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003678 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003679 mPendingBroadcast.state = BroadcastRecord.IDLE;
3680 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003681 mPendingBroadcast = null;
3682 scheduleBroadcastsLocked();
3683 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003685 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003686 }
3687 }
3688
3689 private final boolean attachApplicationLocked(IApplicationThread thread,
3690 int pid) {
3691
3692 // Find the application record that is being attached... either via
3693 // the pid if we are running in multiple processes, or just pull the
3694 // next app record if we are emulating process with anonymous threads.
3695 ProcessRecord app;
3696 if (pid != MY_PID && pid >= 0) {
3697 synchronized (mPidsSelfLocked) {
3698 app = mPidsSelfLocked.get(pid);
3699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003700 } else {
3701 app = null;
3702 }
3703
3704 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003705 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003707 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003709 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 } else {
3711 try {
3712 thread.scheduleExit();
3713 } catch (Exception e) {
3714 // Ignore exceptions.
3715 }
3716 }
3717 return false;
3718 }
3719
3720 // If this application record is still attached to a previous
3721 // process, clean it up now.
3722 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003723 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 }
3725
3726 // Tell the process all about itself.
3727
Joe Onorato8a9b2202010-02-26 18:56:32 -08003728 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 TAG, "Binding process pid " + pid + " to record " + app);
3730
3731 String processName = app.processName;
3732 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003733 AppDeathRecipient adr = new AppDeathRecipient(
3734 app, pid, thread);
3735 thread.asBinder().linkToDeath(adr, 0);
3736 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 } catch (RemoteException e) {
3738 app.resetPackageList();
3739 startProcessLocked(app, "link fail", processName);
3740 return false;
3741 }
3742
Doug Zongker2bec3d42009-12-04 12:52:44 -08003743 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744
3745 app.thread = thread;
3746 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003747 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3748 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 app.forcingToForeground = null;
3750 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003751 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752 app.debugging = false;
3753
3754 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3755
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003756 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003757 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003759 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003760 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003761 }
3762
Joe Onorato8a9b2202010-02-26 18:56:32 -08003763 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 TAG, "New app record " + app
3765 + " thread=" + thread.asBinder() + " pid=" + pid);
3766 try {
3767 int testMode = IApplicationThread.DEBUG_OFF;
3768 if (mDebugApp != null && mDebugApp.equals(processName)) {
3769 testMode = mWaitForDebugger
3770 ? IApplicationThread.DEBUG_WAIT
3771 : IApplicationThread.DEBUG_ON;
3772 app.debugging = true;
3773 if (mDebugTransient) {
3774 mDebugApp = mOrigDebugApp;
3775 mWaitForDebugger = mOrigWaitForDebugger;
3776 }
3777 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003778 String profileFile = app.instrumentationProfileFile;
3779 ParcelFileDescriptor profileFd = null;
3780 boolean profileAutoStop = false;
3781 if (mProfileApp != null && mProfileApp.equals(processName)) {
3782 mProfileProc = app;
3783 profileFile = mProfileFile;
3784 profileFd = mProfileFd;
3785 profileAutoStop = mAutoStopProfiler;
3786 }
3787
Christopher Tate181fafa2009-05-14 11:12:14 -07003788 // If the app is being launched for restore or full backup, set it up specially
3789 boolean isRestrictedBackupMode = false;
3790 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3791 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003792 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003793 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3794 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003795
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003796 ensurePackageDexOpt(app.instrumentationInfo != null
3797 ? app.instrumentationInfo.packageName
3798 : app.info.packageName);
3799 if (app.instrumentationClass != null) {
3800 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003801 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003802 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003803 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003804 ApplicationInfo appInfo = app.instrumentationInfo != null
3805 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003806 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003807 if (profileFd != null) {
3808 profileFd = profileFd.dup();
3809 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003810 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003811 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003813 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003814 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003815 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003816 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003817 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003818 } catch (Exception e) {
3819 // todo: Yikes! What should we do? For now we will try to
3820 // start another process, but that could easily get us in
3821 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003822 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003823
3824 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003825 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 startProcessLocked(app, "bind fail", processName);
3827 return false;
3828 }
3829
3830 // Remove this record from the list of starting applications.
3831 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003832 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3833 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 mProcessesOnHold.remove(app);
3835
3836 boolean badApp = false;
3837 boolean didSomething = false;
3838
3839 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003840 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003841 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3843 && processName.equals(hr.processName)) {
3844 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003845 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 didSomething = true;
3847 }
3848 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003849 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 + hr.intent.getComponent().flattenToShortString(), e);
3851 badApp = true;
3852 }
3853 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003854 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 }
3856 }
3857
3858 // Find any services that should be running in this process...
3859 if (!badApp && mPendingServices.size() > 0) {
3860 ServiceRecord sr = null;
3861 try {
3862 for (int i=0; i<mPendingServices.size(); i++) {
3863 sr = mPendingServices.get(i);
3864 if (app.info.uid != sr.appInfo.uid
3865 || !processName.equals(sr.processName)) {
3866 continue;
3867 }
3868
3869 mPendingServices.remove(i);
3870 i--;
3871 realStartServiceLocked(sr, app);
3872 didSomething = true;
3873 }
3874 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003875 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 + sr.shortName, e);
3877 badApp = true;
3878 }
3879 }
3880
3881 // Check if the next broadcast receiver is in this process...
3882 BroadcastRecord br = mPendingBroadcast;
3883 if (!badApp && br != null && br.curApp == app) {
3884 try {
3885 mPendingBroadcast = null;
3886 processCurBroadcastLocked(br, app);
3887 didSomething = true;
3888 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003889 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 + br.curComponent.flattenToShortString(), e);
3891 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003892 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003893 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3894 br.resultExtras, br.resultAbort, true);
3895 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003896 // We need to reset the state if we fails to start the receiver.
3897 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 }
3899 }
3900
Christopher Tate181fafa2009-05-14 11:12:14 -07003901 // Check whether the next backup agent is in this process...
3902 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003903 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003904 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003905 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003906 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3907 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3908 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003909 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003910 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003911 e.printStackTrace();
3912 }
3913 }
3914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 if (badApp) {
3916 // todo: Also need to kill application to deal with all
3917 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003918 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 return false;
3920 }
3921
3922 if (!didSomething) {
3923 updateOomAdjLocked();
3924 }
3925
3926 return true;
3927 }
3928
3929 public final void attachApplication(IApplicationThread thread) {
3930 synchronized (this) {
3931 int callingPid = Binder.getCallingPid();
3932 final long origId = Binder.clearCallingIdentity();
3933 attachApplicationLocked(thread, callingPid);
3934 Binder.restoreCallingIdentity(origId);
3935 }
3936 }
3937
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003938 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003940 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3941 if (stopProfiling) {
3942 synchronized (this) {
3943 if (mProfileProc == r.app) {
3944 if (mProfileFd != null) {
3945 try {
3946 mProfileFd.close();
3947 } catch (IOException e) {
3948 }
3949 clearProfilerLocked();
3950 }
3951 }
3952 }
3953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 Binder.restoreCallingIdentity(origId);
3955 }
3956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003958 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003959 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003960 mWindowManager.enableScreenAfterBoot();
3961 }
3962
Dianne Hackborn661cd522011-08-22 00:26:20 -07003963 public void showBootMessage(final CharSequence msg, final boolean always) {
3964 mWindowManager.showBootMessage(msg, always);
3965 }
3966
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003967 public void dismissKeyguardOnNextActivity() {
3968 synchronized (this) {
3969 mMainStack.dismissKeyguardOnNextActivityLocked();
3970 }
3971 }
3972
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003973 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003974 IntentFilter pkgFilter = new IntentFilter();
3975 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3976 pkgFilter.addDataScheme("package");
3977 mContext.registerReceiver(new BroadcastReceiver() {
3978 @Override
3979 public void onReceive(Context context, Intent intent) {
3980 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3981 if (pkgs != null) {
3982 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003983 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003984 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003985 setResultCode(Activity.RESULT_OK);
3986 return;
3987 }
3988 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003989 }
3990 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003991 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003992 }, pkgFilter);
3993
3994 synchronized (this) {
3995 // Ensure that any processes we had put on hold are now started
3996 // up.
3997 final int NP = mProcessesOnHold.size();
3998 if (NP > 0) {
3999 ArrayList<ProcessRecord> procs =
4000 new ArrayList<ProcessRecord>(mProcessesOnHold);
4001 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004002 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4003 + procs.get(ip));
4004 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004005 }
4006 }
4007
4008 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004009 // Start looking for apps that are abusing wake locks.
4010 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004011 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004012 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004013 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004014 broadcastIntentLocked(null, null,
4015 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4016 null, null, 0, null, null,
4017 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4018 false, false, MY_PID, Process.SYSTEM_UID);
4019 }
4020 }
4021 }
4022
4023 final void ensureBootCompleted() {
4024 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004025 boolean enableScreen;
4026 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004027 booting = mBooting;
4028 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004029 enableScreen = !mBooted;
4030 mBooted = true;
4031 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004032
4033 if (booting) {
4034 finishBooting();
4035 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004036
4037 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004038 enableScreenAfterBoot();
4039 }
4040 }
4041
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004042 public final void activityPaused(IBinder token) {
4043 final long origId = Binder.clearCallingIdentity();
4044 mMainStack.activityPaused(token, false);
4045 Binder.restoreCallingIdentity(origId);
4046 }
4047
4048 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4049 CharSequence description) {
4050 if (localLOGV) Slog.v(
4051 TAG, "Activity stopped: token=" + token);
4052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 // Refuse possible leaked file descriptors
4054 if (icicle != null && icicle.hasFileDescriptors()) {
4055 throw new IllegalArgumentException("File descriptors passed in Bundle");
4056 }
4057
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004058 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004059
4060 final long origId = Binder.clearCallingIdentity();
4061
4062 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004063 r = mMainStack.isInStackLocked(token);
4064 if (r != null) {
4065 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004066 }
4067 }
4068
4069 if (r != null) {
4070 sendPendingThumbnail(r, null, null, null, false);
4071 }
4072
4073 trimApplications();
4074
4075 Binder.restoreCallingIdentity(origId);
4076 }
4077
4078 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004079 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004080 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004081 }
4082
4083 public String getCallingPackage(IBinder token) {
4084 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004085 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004086 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 }
4088 }
4089
4090 public ComponentName getCallingActivity(IBinder token) {
4091 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004092 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 return r != null ? r.intent.getComponent() : null;
4094 }
4095 }
4096
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004097 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004098 ActivityRecord r = mMainStack.isInStackLocked(token);
4099 if (r == null) {
4100 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004102 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103 }
4104
4105 public ComponentName getActivityClassForToken(IBinder token) {
4106 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004107 ActivityRecord r = mMainStack.isInStackLocked(token);
4108 if (r == null) {
4109 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004111 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 }
4113 }
4114
4115 public String getPackageForToken(IBinder token) {
4116 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004117 ActivityRecord r = mMainStack.isInStackLocked(token);
4118 if (r == null) {
4119 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004120 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004121 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 }
4123 }
4124
4125 public IIntentSender getIntentSender(int type,
4126 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004127 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004129 if (intents != null) {
4130 if (intents.length < 1) {
4131 throw new IllegalArgumentException("Intents array length must be >= 1");
4132 }
4133 for (int i=0; i<intents.length; i++) {
4134 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004135 if (intent != null) {
4136 if (intent.hasFileDescriptors()) {
4137 throw new IllegalArgumentException("File descriptors passed in Intent");
4138 }
4139 if (type == INTENT_SENDER_BROADCAST &&
4140 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4141 throw new IllegalArgumentException(
4142 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4143 }
4144 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004145 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004146 }
4147 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004148 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004149 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004150 }
4151 }
4152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004153 synchronized(this) {
4154 int callingUid = Binder.getCallingUid();
4155 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004156 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004157 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004158 .getPackageUid(packageName);
4159 if (uid != Binder.getCallingUid()) {
4160 String msg = "Permission Denial: getIntentSender() from pid="
4161 + Binder.getCallingPid()
4162 + ", uid=" + Binder.getCallingUid()
4163 + ", (need uid=" + uid + ")"
4164 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 throw new SecurityException(msg);
4167 }
4168 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004169
4170 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004171 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004173 } catch (RemoteException e) {
4174 throw new SecurityException(e);
4175 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004176 }
4177 }
4178
4179 IIntentSender getIntentSenderLocked(int type,
4180 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004181 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004182 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004183 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004184 activity = mMainStack.isInStackLocked(token);
4185 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004186 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004187 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004188 if (activity.finishing) {
4189 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004191 }
4192
4193 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4194 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4195 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4196 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4197 |PendingIntent.FLAG_UPDATE_CURRENT);
4198
4199 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4200 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004201 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004202 WeakReference<PendingIntentRecord> ref;
4203 ref = mIntentSenderRecords.get(key);
4204 PendingIntentRecord rec = ref != null ? ref.get() : null;
4205 if (rec != null) {
4206 if (!cancelCurrent) {
4207 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004208 if (rec.key.requestIntent != null) {
4209 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4210 }
4211 if (intents != null) {
4212 intents[intents.length-1] = rec.key.requestIntent;
4213 rec.key.allIntents = intents;
4214 rec.key.allResolvedTypes = resolvedTypes;
4215 } else {
4216 rec.key.allIntents = null;
4217 rec.key.allResolvedTypes = null;
4218 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 return rec;
4221 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004222 rec.canceled = true;
4223 mIntentSenderRecords.remove(key);
4224 }
4225 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004226 return rec;
4227 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004228 rec = new PendingIntentRecord(this, key, callingUid);
4229 mIntentSenderRecords.put(key, rec.ref);
4230 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4231 if (activity.pendingResults == null) {
4232 activity.pendingResults
4233 = new HashSet<WeakReference<PendingIntentRecord>>();
4234 }
4235 activity.pendingResults.add(rec.ref);
4236 }
4237 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 }
4239
4240 public void cancelIntentSender(IIntentSender sender) {
4241 if (!(sender instanceof PendingIntentRecord)) {
4242 return;
4243 }
4244 synchronized(this) {
4245 PendingIntentRecord rec = (PendingIntentRecord)sender;
4246 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004247 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004248 .getPackageUid(rec.key.packageName);
4249 if (uid != Binder.getCallingUid()) {
4250 String msg = "Permission Denial: cancelIntentSender() from pid="
4251 + Binder.getCallingPid()
4252 + ", uid=" + Binder.getCallingUid()
4253 + " is not allowed to cancel packges "
4254 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004255 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 throw new SecurityException(msg);
4257 }
4258 } catch (RemoteException e) {
4259 throw new SecurityException(e);
4260 }
4261 cancelIntentSenderLocked(rec, true);
4262 }
4263 }
4264
4265 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4266 rec.canceled = true;
4267 mIntentSenderRecords.remove(rec.key);
4268 if (cleanActivity && rec.key.activity != null) {
4269 rec.key.activity.pendingResults.remove(rec.ref);
4270 }
4271 }
4272
4273 public String getPackageForIntentSender(IIntentSender pendingResult) {
4274 if (!(pendingResult instanceof PendingIntentRecord)) {
4275 return null;
4276 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004277 try {
4278 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4279 return res.key.packageName;
4280 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 }
4282 return null;
4283 }
4284
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004285 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4286 if (!(pendingResult instanceof PendingIntentRecord)) {
4287 return false;
4288 }
4289 try {
4290 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4291 if (res.key.allIntents == null) {
4292 return false;
4293 }
4294 for (int i=0; i<res.key.allIntents.length; i++) {
4295 Intent intent = res.key.allIntents[i];
4296 if (intent.getPackage() != null && intent.getComponent() != null) {
4297 return false;
4298 }
4299 }
4300 return true;
4301 } catch (ClassCastException e) {
4302 }
4303 return false;
4304 }
4305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 public void setProcessLimit(int max) {
4307 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4308 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004309 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004310 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004311 mProcessLimitOverride = max;
4312 }
4313 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004314 }
4315
4316 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004317 synchronized (this) {
4318 return mProcessLimitOverride;
4319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 }
4321
4322 void foregroundTokenDied(ForegroundToken token) {
4323 synchronized (ActivityManagerService.this) {
4324 synchronized (mPidsSelfLocked) {
4325 ForegroundToken cur
4326 = mForegroundProcesses.get(token.pid);
4327 if (cur != token) {
4328 return;
4329 }
4330 mForegroundProcesses.remove(token.pid);
4331 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4332 if (pr == null) {
4333 return;
4334 }
4335 pr.forcingToForeground = null;
4336 pr.foregroundServices = false;
4337 }
4338 updateOomAdjLocked();
4339 }
4340 }
4341
4342 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4343 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4344 "setProcessForeground()");
4345 synchronized(this) {
4346 boolean changed = false;
4347
4348 synchronized (mPidsSelfLocked) {
4349 ProcessRecord pr = mPidsSelfLocked.get(pid);
4350 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004351 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 return;
4353 }
4354 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4355 if (oldToken != null) {
4356 oldToken.token.unlinkToDeath(oldToken, 0);
4357 mForegroundProcesses.remove(pid);
4358 pr.forcingToForeground = null;
4359 changed = true;
4360 }
4361 if (isForeground && token != null) {
4362 ForegroundToken newToken = new ForegroundToken() {
4363 public void binderDied() {
4364 foregroundTokenDied(this);
4365 }
4366 };
4367 newToken.pid = pid;
4368 newToken.token = token;
4369 try {
4370 token.linkToDeath(newToken, 0);
4371 mForegroundProcesses.put(pid, newToken);
4372 pr.forcingToForeground = token;
4373 changed = true;
4374 } catch (RemoteException e) {
4375 // If the process died while doing this, we will later
4376 // do the cleanup with the process death link.
4377 }
4378 }
4379 }
4380
4381 if (changed) {
4382 updateOomAdjLocked();
4383 }
4384 }
4385 }
4386
4387 // =========================================================
4388 // PERMISSIONS
4389 // =========================================================
4390
4391 static class PermissionController extends IPermissionController.Stub {
4392 ActivityManagerService mActivityManagerService;
4393 PermissionController(ActivityManagerService activityManagerService) {
4394 mActivityManagerService = activityManagerService;
4395 }
4396
4397 public boolean checkPermission(String permission, int pid, int uid) {
4398 return mActivityManagerService.checkPermission(permission, pid,
4399 uid) == PackageManager.PERMISSION_GRANTED;
4400 }
4401 }
4402
4403 /**
4404 * This can be called with or without the global lock held.
4405 */
4406 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004407 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 // We might be performing an operation on behalf of an indirect binder
4409 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4410 // client identity accordingly before proceeding.
4411 Identity tlsIdentity = sCallerIdentity.get();
4412 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004413 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4415 uid = tlsIdentity.uid;
4416 pid = tlsIdentity.pid;
4417 }
4418
4419 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004420 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 return PackageManager.PERMISSION_GRANTED;
4422 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004423 // If there is a uid that owns whatever is being accessed, it has
4424 // blanket access to it regardless of the permissions it requires.
4425 if (owningUid >= 0 && uid == owningUid) {
4426 return PackageManager.PERMISSION_GRANTED;
4427 }
4428 // If the target is not exported, then nobody else can get to it.
4429 if (!exported) {
4430 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 return PackageManager.PERMISSION_DENIED;
4432 }
4433 if (permission == null) {
4434 return PackageManager.PERMISSION_GRANTED;
4435 }
4436 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004437 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 .checkUidPermission(permission, uid);
4439 } catch (RemoteException e) {
4440 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004441 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 }
4443 return PackageManager.PERMISSION_DENIED;
4444 }
4445
4446 /**
4447 * As the only public entry point for permissions checking, this method
4448 * can enforce the semantic that requesting a check on a null global
4449 * permission is automatically denied. (Internally a null permission
4450 * string is used when calling {@link #checkComponentPermission} in cases
4451 * when only uid-based security is needed.)
4452 *
4453 * This can be called with or without the global lock held.
4454 */
4455 public int checkPermission(String permission, int pid, int uid) {
4456 if (permission == null) {
4457 return PackageManager.PERMISSION_DENIED;
4458 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004459 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 }
4461
4462 /**
4463 * Binder IPC calls go through the public entry point.
4464 * This can be called with or without the global lock held.
4465 */
4466 int checkCallingPermission(String permission) {
4467 return checkPermission(permission,
4468 Binder.getCallingPid(),
4469 Binder.getCallingUid());
4470 }
4471
4472 /**
4473 * This can be called with or without the global lock held.
4474 */
4475 void enforceCallingPermission(String permission, String func) {
4476 if (checkCallingPermission(permission)
4477 == PackageManager.PERMISSION_GRANTED) {
4478 return;
4479 }
4480
4481 String msg = "Permission Denial: " + func + " from pid="
4482 + Binder.getCallingPid()
4483 + ", uid=" + Binder.getCallingUid()
4484 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004485 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 throw new SecurityException(msg);
4487 }
4488
4489 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004490 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4491 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4492 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4493 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4494 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004496 // Is the component private from the target uid?
4497 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4498
4499 // Acceptable if the there is no read permission needed from the
4500 // target or the target is holding the read permission.
4501 if (!readPerm) {
4502 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004504 == PackageManager.PERMISSION_GRANTED)) {
4505 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 }
4507 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004508
4509 // Acceptable if the there is no write permission needed from the
4510 // target or the target is holding the read permission.
4511 if (!writePerm) {
4512 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004514 == PackageManager.PERMISSION_GRANTED)) {
4515 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 }
4517 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004518
4519 // Acceptable if there is a path permission matching the URI that
4520 // the target holds the permission on.
4521 PathPermission[] pps = pi.pathPermissions;
4522 if (pps != null && (!readPerm || !writePerm)) {
4523 final String path = uri.getPath();
4524 int i = pps.length;
4525 while (i > 0 && (!readPerm || !writePerm)) {
4526 i--;
4527 PathPermission pp = pps[i];
4528 if (!readPerm) {
4529 final String pprperm = pp.getReadPermission();
4530 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4531 + pprperm + " for " + pp.getPath()
4532 + ": match=" + pp.match(path)
4533 + " check=" + pm.checkUidPermission(pprperm, uid));
4534 if (pprperm != null && pp.match(path) &&
4535 (pm.checkUidPermission(pprperm, uid)
4536 == PackageManager.PERMISSION_GRANTED)) {
4537 readPerm = true;
4538 }
4539 }
4540 if (!writePerm) {
4541 final String ppwperm = pp.getWritePermission();
4542 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4543 + ppwperm + " for " + pp.getPath()
4544 + ": match=" + pp.match(path)
4545 + " check=" + pm.checkUidPermission(ppwperm, uid));
4546 if (ppwperm != null && pp.match(path) &&
4547 (pm.checkUidPermission(ppwperm, uid)
4548 == PackageManager.PERMISSION_GRANTED)) {
4549 writePerm = true;
4550 }
4551 }
4552 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 } catch (RemoteException e) {
4555 return false;
4556 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004557
4558 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 }
4560
4561 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4562 int modeFlags) {
4563 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004564 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004565 return true;
4566 }
4567 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4568 if (perms == null) return false;
4569 UriPermission perm = perms.get(uri);
4570 if (perm == null) return false;
4571 return (modeFlags&perm.modeFlags) == modeFlags;
4572 }
4573
4574 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4575 // Another redirected-binder-call permissions check as in
4576 // {@link checkComponentPermission}.
4577 Identity tlsIdentity = sCallerIdentity.get();
4578 if (tlsIdentity != null) {
4579 uid = tlsIdentity.uid;
4580 pid = tlsIdentity.pid;
4581 }
4582
4583 // Our own process gets to do everything.
4584 if (pid == MY_PID) {
4585 return PackageManager.PERMISSION_GRANTED;
4586 }
4587 synchronized(this) {
4588 return checkUriPermissionLocked(uri, uid, modeFlags)
4589 ? PackageManager.PERMISSION_GRANTED
4590 : PackageManager.PERMISSION_DENIED;
4591 }
4592 }
4593
Dianne Hackborn39792d22010-08-19 18:01:52 -07004594 /**
4595 * Check if the targetPkg can be granted permission to access uri by
4596 * the callingUid using the given modeFlags. Throws a security exception
4597 * if callingUid is not allowed to do this. Returns the uid of the target
4598 * if the URI permission grant should be performed; returns -1 if it is not
4599 * needed (for example targetPkg already has permission to access the URI).
4600 */
4601 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4602 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4604 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4605 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004606 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 }
4608
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004609 if (targetPkg != null) {
4610 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4611 "Checking grant " + targetPkg + " permission to " + uri);
4612 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004613
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004614 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615
4616 // If this is not a content: uri, we can't do anything with it.
4617 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004618 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004619 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004620 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 }
4622
4623 String name = uri.getAuthority();
4624 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004625 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 if (cpr != null) {
4627 pi = cpr.info;
4628 } else {
4629 try {
4630 pi = pm.resolveContentProvider(name,
4631 PackageManager.GET_URI_PERMISSION_PATTERNS);
4632 } catch (RemoteException ex) {
4633 }
4634 }
4635 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004636 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004637 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 }
4639
4640 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004641 if (targetPkg != null) {
4642 try {
4643 targetUid = pm.getPackageUid(targetPkg);
4644 if (targetUid < 0) {
4645 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4646 "Can't grant URI permission no uid for: " + targetPkg);
4647 return -1;
4648 }
4649 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004650 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004652 } else {
4653 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 }
4655
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004656 if (targetUid >= 0) {
4657 // First... does the target actually need this permission?
4658 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4659 // No need to grant the target this permission.
4660 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4661 "Target " + targetPkg + " already has full permission to " + uri);
4662 return -1;
4663 }
4664 } else {
4665 // First... there is no target package, so can anyone access it?
4666 boolean allowed = pi.exported;
4667 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4668 if (pi.readPermission != null) {
4669 allowed = false;
4670 }
4671 }
4672 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4673 if (pi.writePermission != null) {
4674 allowed = false;
4675 }
4676 }
4677 if (allowed) {
4678 return -1;
4679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 }
4681
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004682 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 if (!pi.grantUriPermissions) {
4684 throw new SecurityException("Provider " + pi.packageName
4685 + "/" + pi.name
4686 + " does not allow granting of Uri permissions (uri "
4687 + uri + ")");
4688 }
4689 if (pi.uriPermissionPatterns != null) {
4690 final int N = pi.uriPermissionPatterns.length;
4691 boolean allowed = false;
4692 for (int i=0; i<N; i++) {
4693 if (pi.uriPermissionPatterns[i] != null
4694 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4695 allowed = true;
4696 break;
4697 }
4698 }
4699 if (!allowed) {
4700 throw new SecurityException("Provider " + pi.packageName
4701 + "/" + pi.name
4702 + " does not allow granting of permission to path of Uri "
4703 + uri);
4704 }
4705 }
4706
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004707 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004709 if (callingUid != Process.myUid()) {
4710 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4711 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4712 throw new SecurityException("Uid " + callingUid
4713 + " does not have permission to uri " + uri);
4714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 }
4716 }
4717
Dianne Hackborn39792d22010-08-19 18:01:52 -07004718 return targetUid;
4719 }
4720
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004721 public int checkGrantUriPermission(int callingUid, String targetPkg,
4722 Uri uri, int modeFlags) {
4723 synchronized(this) {
4724 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4725 }
4726 }
4727
Dianne Hackborn39792d22010-08-19 18:01:52 -07004728 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4729 Uri uri, int modeFlags, UriPermissionOwner owner) {
4730 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4731 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4732 if (modeFlags == 0) {
4733 return;
4734 }
4735
4736 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 // to the uri, and the target doesn't. Let's now give this to
4738 // the target.
4739
Joe Onorato8a9b2202010-02-26 18:56:32 -08004740 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004741 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 HashMap<Uri, UriPermission> targetUris
4744 = mGrantedUriPermissions.get(targetUid);
4745 if (targetUris == null) {
4746 targetUris = new HashMap<Uri, UriPermission>();
4747 mGrantedUriPermissions.put(targetUid, targetUris);
4748 }
4749
4750 UriPermission perm = targetUris.get(uri);
4751 if (perm == null) {
4752 perm = new UriPermission(targetUid, uri);
4753 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004757 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004759 } else {
4760 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4761 perm.readOwners.add(owner);
4762 owner.addReadPermission(perm);
4763 }
4764 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4765 perm.writeOwners.add(owner);
4766 owner.addWritePermission(perm);
4767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004768 }
4769 }
4770
Dianne Hackborn39792d22010-08-19 18:01:52 -07004771 void grantUriPermissionLocked(int callingUid,
4772 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004773 if (targetPkg == null) {
4774 throw new NullPointerException("targetPkg");
4775 }
4776
Dianne Hackborn39792d22010-08-19 18:01:52 -07004777 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4778 if (targetUid < 0) {
4779 return;
4780 }
4781
4782 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4783 }
4784
4785 /**
4786 * Like checkGrantUriPermissionLocked, but takes an Intent.
4787 */
4788 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4789 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004790 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004791 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004792 + " from " + intent + "; flags=0x"
4793 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4794
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004795 if (targetPkg == null) {
4796 throw new NullPointerException("targetPkg");
4797 }
4798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004800 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004801 }
4802 Uri data = intent.getData();
4803 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004804 return -1;
4805 }
4806 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4807 intent.getFlags());
4808 }
4809
4810 /**
4811 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4812 */
4813 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4814 String targetPkg, Intent intent, UriPermissionOwner owner) {
4815 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4816 intent.getFlags(), owner);
4817 }
4818
4819 void grantUriPermissionFromIntentLocked(int callingUid,
4820 String targetPkg, Intent intent, UriPermissionOwner owner) {
4821 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4822 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823 return;
4824 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004825
4826 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 }
4828
4829 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4830 Uri uri, int modeFlags) {
4831 synchronized(this) {
4832 final ProcessRecord r = getRecordForAppLocked(caller);
4833 if (r == null) {
4834 throw new SecurityException("Unable to find app for caller "
4835 + caller
4836 + " when granting permission to uri " + uri);
4837 }
4838 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004839 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 }
4841 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004842 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 }
4844
4845 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4846 null);
4847 }
4848 }
4849
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004850 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4852 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4853 HashMap<Uri, UriPermission> perms
4854 = mGrantedUriPermissions.get(perm.uid);
4855 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004856 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004857 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 perms.remove(perm.uri);
4859 if (perms.size() == 0) {
4860 mGrantedUriPermissions.remove(perm.uid);
4861 }
4862 }
4863 }
4864 }
4865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4867 int modeFlags) {
4868 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4869 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4870 if (modeFlags == 0) {
4871 return;
4872 }
4873
Joe Onorato8a9b2202010-02-26 18:56:32 -08004874 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004875 "Revoking all granted permissions to " + uri);
4876
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004877 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878
4879 final String authority = uri.getAuthority();
4880 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004881 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 if (cpr != null) {
4883 pi = cpr.info;
4884 } else {
4885 try {
4886 pi = pm.resolveContentProvider(authority,
4887 PackageManager.GET_URI_PERMISSION_PATTERNS);
4888 } catch (RemoteException ex) {
4889 }
4890 }
4891 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004892 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 return;
4894 }
4895
4896 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004897 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 // Right now, if you are not the original owner of the permission,
4899 // you are not allowed to revoke it.
4900 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4901 throw new SecurityException("Uid " + callingUid
4902 + " does not have permission to uri " + uri);
4903 //}
4904 }
4905
4906 // Go through all of the permissions and remove any that match.
4907 final List<String> SEGMENTS = uri.getPathSegments();
4908 if (SEGMENTS != null) {
4909 final int NS = SEGMENTS.size();
4910 int N = mGrantedUriPermissions.size();
4911 for (int i=0; i<N; i++) {
4912 HashMap<Uri, UriPermission> perms
4913 = mGrantedUriPermissions.valueAt(i);
4914 Iterator<UriPermission> it = perms.values().iterator();
4915 toploop:
4916 while (it.hasNext()) {
4917 UriPermission perm = it.next();
4918 Uri targetUri = perm.uri;
4919 if (!authority.equals(targetUri.getAuthority())) {
4920 continue;
4921 }
4922 List<String> targetSegments = targetUri.getPathSegments();
4923 if (targetSegments == null) {
4924 continue;
4925 }
4926 if (targetSegments.size() < NS) {
4927 continue;
4928 }
4929 for (int j=0; j<NS; j++) {
4930 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4931 continue toploop;
4932 }
4933 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004934 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004935 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004936 perm.clearModes(modeFlags);
4937 if (perm.modeFlags == 0) {
4938 it.remove();
4939 }
4940 }
4941 if (perms.size() == 0) {
4942 mGrantedUriPermissions.remove(
4943 mGrantedUriPermissions.keyAt(i));
4944 N--;
4945 i--;
4946 }
4947 }
4948 }
4949 }
4950
4951 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4952 int modeFlags) {
4953 synchronized(this) {
4954 final ProcessRecord r = getRecordForAppLocked(caller);
4955 if (r == null) {
4956 throw new SecurityException("Unable to find app for caller "
4957 + caller
4958 + " when revoking permission to uri " + uri);
4959 }
4960 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004961 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 return;
4963 }
4964
4965 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4966 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4967 if (modeFlags == 0) {
4968 return;
4969 }
4970
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004971 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972
4973 final String authority = uri.getAuthority();
4974 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004975 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 if (cpr != null) {
4977 pi = cpr.info;
4978 } else {
4979 try {
4980 pi = pm.resolveContentProvider(authority,
4981 PackageManager.GET_URI_PERMISSION_PATTERNS);
4982 } catch (RemoteException ex) {
4983 }
4984 }
4985 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004986 Slog.w(TAG, "No content provider found for permission revoke: "
4987 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004988 return;
4989 }
4990
4991 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4992 }
4993 }
4994
Dianne Hackborn7e269642010-08-25 19:50:20 -07004995 @Override
4996 public IBinder newUriPermissionOwner(String name) {
4997 synchronized(this) {
4998 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4999 return owner.getExternalTokenLocked();
5000 }
5001 }
5002
5003 @Override
5004 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5005 Uri uri, int modeFlags) {
5006 synchronized(this) {
5007 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5008 if (owner == null) {
5009 throw new IllegalArgumentException("Unknown owner: " + token);
5010 }
5011 if (fromUid != Binder.getCallingUid()) {
5012 if (Binder.getCallingUid() != Process.myUid()) {
5013 // Only system code can grant URI permissions on behalf
5014 // of other users.
5015 throw new SecurityException("nice try");
5016 }
5017 }
5018 if (targetPkg == null) {
5019 throw new IllegalArgumentException("null target");
5020 }
5021 if (uri == null) {
5022 throw new IllegalArgumentException("null uri");
5023 }
5024
5025 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5026 }
5027 }
5028
5029 @Override
5030 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5031 synchronized(this) {
5032 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5033 if (owner == null) {
5034 throw new IllegalArgumentException("Unknown owner: " + token);
5035 }
5036
5037 if (uri == null) {
5038 owner.removeUriPermissionsLocked(mode);
5039 } else {
5040 owner.removeUriPermissionLocked(uri, mode);
5041 }
5042 }
5043 }
5044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5046 synchronized (this) {
5047 ProcessRecord app =
5048 who != null ? getRecordForAppLocked(who) : null;
5049 if (app == null) return;
5050
5051 Message msg = Message.obtain();
5052 msg.what = WAIT_FOR_DEBUGGER_MSG;
5053 msg.obj = app;
5054 msg.arg1 = waiting ? 1 : 0;
5055 mHandler.sendMessage(msg);
5056 }
5057 }
5058
5059 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005060 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5061 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005062 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005063 outInfo.threshold = homeAppMem;
5064 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5065 outInfo.hiddenAppThreshold = hiddenAppMem;
5066 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005067 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005068 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5069 ProcessList.VISIBLE_APP_ADJ);
5070 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5071 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005072 }
5073
5074 // =========================================================
5075 // TASK MANAGEMENT
5076 // =========================================================
5077
5078 public List getTasks(int maxNum, int flags,
5079 IThumbnailReceiver receiver) {
5080 ArrayList list = new ArrayList();
5081
5082 PendingThumbnailsRecord pending = null;
5083 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005084 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085
5086 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005087 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005088 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5089 + ", receiver=" + receiver);
5090
5091 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5092 != PackageManager.PERMISSION_GRANTED) {
5093 if (receiver != null) {
5094 // If the caller wants to wait for pending thumbnails,
5095 // it ain't gonna get them.
5096 try {
5097 receiver.finished();
5098 } catch (RemoteException ex) {
5099 }
5100 }
5101 String msg = "Permission Denial: getTasks() from pid="
5102 + Binder.getCallingPid()
5103 + ", uid=" + Binder.getCallingUid()
5104 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005105 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106 throw new SecurityException(msg);
5107 }
5108
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005109 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005110 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005111 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005112 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005113 TaskRecord curTask = null;
5114 int numActivities = 0;
5115 int numRunning = 0;
5116 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005117 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005118 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005119 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120
5121 // Initialize state for next task if needed.
5122 if (top == null ||
5123 (top.state == ActivityState.INITIALIZING
5124 && top.task == r.task)) {
5125 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 curTask = r.task;
5127 numActivities = numRunning = 0;
5128 }
5129
5130 // Add 'r' into the current task.
5131 numActivities++;
5132 if (r.app != null && r.app.thread != null) {
5133 numRunning++;
5134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005135
Joe Onorato8a9b2202010-02-26 18:56:32 -08005136 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005137 TAG, r.intent.getComponent().flattenToShortString()
5138 + ": task=" + r.task);
5139
5140 // If the next one is a different task, generate a new
5141 // TaskInfo entry for what we have.
5142 if (next == null || next.task != curTask) {
5143 ActivityManager.RunningTaskInfo ci
5144 = new ActivityManager.RunningTaskInfo();
5145 ci.id = curTask.taskId;
5146 ci.baseActivity = r.intent.getComponent();
5147 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005148 if (top.thumbHolder != null) {
5149 ci.description = top.thumbHolder.lastDescription;
5150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005151 ci.numActivities = numActivities;
5152 ci.numRunning = numRunning;
5153 //System.out.println(
5154 // "#" + maxNum + ": " + " descr=" + ci.description);
5155 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005156 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005157 TAG, "State=" + top.state + "Idle=" + top.idle
5158 + " app=" + top.app
5159 + " thr=" + (top.app != null ? top.app.thread : null));
5160 if (top.state == ActivityState.RESUMED
5161 || top.state == ActivityState.PAUSING) {
5162 if (top.idle && top.app != null
5163 && top.app.thread != null) {
5164 topRecord = top;
5165 topThumbnail = top.app.thread;
5166 } else {
5167 top.thumbnailNeeded = true;
5168 }
5169 }
5170 if (pending == null) {
5171 pending = new PendingThumbnailsRecord(receiver);
5172 }
5173 pending.pendingRecords.add(top);
5174 }
5175 list.add(ci);
5176 maxNum--;
5177 top = null;
5178 }
5179 }
5180
5181 if (pending != null) {
5182 mPendingThumbnails.add(pending);
5183 }
5184 }
5185
Joe Onorato8a9b2202010-02-26 18:56:32 -08005186 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005187
5188 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005189 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005190 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005191 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005193 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005194 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005195 }
5196 }
5197
5198 if (pending == null && receiver != null) {
5199 // In this case all thumbnails were available and the client
5200 // is being asked to be told when the remaining ones come in...
5201 // which is unusually, since the top-most currently running
5202 // activity should never have a canned thumbnail! Oh well.
5203 try {
5204 receiver.finished();
5205 } catch (RemoteException ex) {
5206 }
5207 }
5208
5209 return list;
5210 }
5211
5212 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5213 int flags) {
5214 synchronized (this) {
5215 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5216 "getRecentTasks()");
5217
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005218 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005220 final int N = mRecentTasks.size();
5221 ArrayList<ActivityManager.RecentTaskInfo> res
5222 = new ArrayList<ActivityManager.RecentTaskInfo>(
5223 maxNum < N ? maxNum : N);
5224 for (int i=0; i<N && maxNum > 0; i++) {
5225 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005226 // Return the entry if desired by the caller. We always return
5227 // the first entry, because callers always expect this to be the
5228 // forground app. We may filter others if the caller has
5229 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5230 // we should exclude the entry.
5231 if (i == 0
5232 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 || (tr.intent == null)
5234 || ((tr.intent.getFlags()
5235 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5236 ActivityManager.RecentTaskInfo rti
5237 = new ActivityManager.RecentTaskInfo();
5238 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005239 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005240 rti.baseIntent = new Intent(
5241 tr.intent != null ? tr.intent : tr.affinityIntent);
5242 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005243 rti.description = tr.lastDescription;
5244
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005245 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5246 // Check whether this activity is currently available.
5247 try {
5248 if (rti.origActivity != null) {
5249 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5250 continue;
5251 }
5252 } else if (rti.baseIntent != null) {
5253 if (pm.queryIntentActivities(rti.baseIntent,
5254 null, 0) == null) {
5255 continue;
5256 }
5257 }
5258 } catch (RemoteException e) {
5259 // Will never happen.
5260 }
5261 }
5262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 res.add(rti);
5264 maxNum--;
5265 }
5266 }
5267 return res;
5268 }
5269 }
5270
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005271 private TaskRecord taskForIdLocked(int id) {
5272 final int N = mRecentTasks.size();
5273 for (int i=0; i<N; i++) {
5274 TaskRecord tr = mRecentTasks.get(i);
5275 if (tr.taskId == id) {
5276 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005277 }
5278 }
5279 return null;
5280 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005281
5282 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5283 synchronized (this) {
5284 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5285 "getTaskThumbnails()");
5286 TaskRecord tr = taskForIdLocked(id);
5287 if (tr != null) {
5288 return mMainStack.getTaskThumbnailsLocked(tr);
5289 }
5290 }
5291 return null;
5292 }
5293
5294 public boolean removeSubTask(int taskId, int subTaskIndex) {
5295 synchronized (this) {
5296 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5297 "removeSubTask()");
5298 long ident = Binder.clearCallingIdentity();
5299 try {
5300 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5301 } finally {
5302 Binder.restoreCallingIdentity(ident);
5303 }
5304 }
5305 }
5306
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005307 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005308 TaskRecord tr = root.task;
5309 Intent baseIntent = new Intent(
5310 tr.intent != null ? tr.intent : tr.affinityIntent);
5311 ComponentName component = baseIntent.getComponent();
5312 if (component == null) {
5313 Slog.w(TAG, "Now component for base intent of task: " + tr);
5314 return;
5315 }
5316
5317 // Find any running services associated with this app.
5318 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5319 for (ServiceRecord sr : mServices.values()) {
5320 if (sr.packageName.equals(component.getPackageName())) {
5321 services.add(sr);
5322 }
5323 }
5324
5325 // Take care of any running services associated with the app.
5326 for (int i=0; i<services.size(); i++) {
5327 ServiceRecord sr = services.get(i);
5328 if (sr.startRequested) {
5329 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005330 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005331 stopServiceLocked(sr);
5332 } else {
5333 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5334 sr.makeNextStartId(), baseIntent, -1));
5335 if (sr.app != null && sr.app.thread != null) {
5336 sendServiceArgsLocked(sr, false);
5337 }
5338 }
5339 }
5340 }
5341
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005342 if (killProcesses) {
5343 // Find any running processes associated with this app.
5344 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5345 SparseArray<ProcessRecord> appProcs
5346 = mProcessNames.getMap().get(component.getPackageName());
5347 if (appProcs != null) {
5348 for (int i=0; i<appProcs.size(); i++) {
5349 procs.add(appProcs.valueAt(i));
5350 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005351 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005352
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005353 // Kill the running processes.
5354 for (int i=0; i<procs.size(); i++) {
5355 ProcessRecord pr = procs.get(i);
5356 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5357 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5358 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5359 pr.processName, pr.setAdj, "remove task");
5360 Process.killProcessQuiet(pr.pid);
5361 } else {
5362 pr.waitingToKill = "remove task";
5363 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005364 }
5365 }
5366 }
5367
5368 public boolean removeTask(int taskId, int flags) {
5369 synchronized (this) {
5370 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5371 "removeTask()");
5372 long ident = Binder.clearCallingIdentity();
5373 try {
5374 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5375 if (r != null) {
5376 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005377 cleanUpRemovedTaskLocked(r,
5378 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005379 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005380 } else {
5381 TaskRecord tr = null;
5382 int i=0;
5383 while (i < mRecentTasks.size()) {
5384 TaskRecord t = mRecentTasks.get(i);
5385 if (t.taskId == taskId) {
5386 tr = t;
5387 break;
5388 }
5389 i++;
5390 }
5391 if (tr != null) {
5392 if (tr.numActivities <= 0) {
5393 // Caller is just removing a recent task that is
5394 // not actively running. That is easy!
5395 mRecentTasks.remove(i);
5396 } else {
5397 Slog.w(TAG, "removeTask: task " + taskId
5398 + " does not have activities to remove, "
5399 + " but numActivities=" + tr.numActivities
5400 + ": " + tr);
5401 }
5402 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005403 }
5404 } finally {
5405 Binder.restoreCallingIdentity(ident);
5406 }
5407 }
5408 return false;
5409 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005411 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5412 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005413 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005414 TaskRecord jt = startTask;
5415
5416 // First look backwards
5417 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005418 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 if (r.task != jt) {
5420 jt = r.task;
5421 if (affinity.equals(jt.affinity)) {
5422 return j;
5423 }
5424 }
5425 }
5426
5427 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005428 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 jt = startTask;
5430 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005431 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 if (r.task != jt) {
5433 if (affinity.equals(jt.affinity)) {
5434 return j;
5435 }
5436 jt = r.task;
5437 }
5438 }
5439
5440 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005441 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005442 return N-1;
5443 }
5444
5445 return -1;
5446 }
5447
5448 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005449 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005451 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005452 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5453 "moveTaskToFront()");
5454
5455 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005456 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5457 Binder.getCallingUid(), "Task to front")) {
5458 return;
5459 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005460 final long origId = Binder.clearCallingIdentity();
5461 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005462 TaskRecord tr = taskForIdLocked(task);
5463 if (tr != null) {
5464 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5465 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005467 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 }
5472 mMainStack.moveTaskToFrontLocked(tr, null);
5473 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005475 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5476 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005478 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5479 mMainStack.mUserLeaving = true;
5480 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005481 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5482 // Caller wants the home activity moved with it. To accomplish this,
5483 // we'll just move the home task to the top first.
5484 mMainStack.moveHomeToFrontLocked();
5485 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005486 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487 return;
5488 }
5489 }
5490 } finally {
5491 Binder.restoreCallingIdentity(origId);
5492 }
5493 }
5494 }
5495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496 public void moveTaskToBack(int task) {
5497 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5498 "moveTaskToBack()");
5499
5500 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005501 if (mMainStack.mResumedActivity != null
5502 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005503 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5504 Binder.getCallingUid(), "Task to back")) {
5505 return;
5506 }
5507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005508 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005509 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 Binder.restoreCallingIdentity(origId);
5511 }
5512 }
5513
5514 /**
5515 * Moves an activity, and all of the other activities within the same task, to the bottom
5516 * of the history stack. The activity's order within the task is unchanged.
5517 *
5518 * @param token A reference to the activity we wish to move
5519 * @param nonRoot If false then this only works if the activity is the root
5520 * of a task; if true it will work for any activity in a task.
5521 * @return Returns true if the move completed, false if not.
5522 */
5523 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5524 synchronized(this) {
5525 final long origId = Binder.clearCallingIdentity();
5526 int taskId = getTaskForActivityLocked(token, !nonRoot);
5527 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005528 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 }
5530 Binder.restoreCallingIdentity(origId);
5531 }
5532 return false;
5533 }
5534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 public void moveTaskBackwards(int task) {
5536 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5537 "moveTaskBackwards()");
5538
5539 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005540 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5541 Binder.getCallingUid(), "Task backwards")) {
5542 return;
5543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005544 final long origId = Binder.clearCallingIdentity();
5545 moveTaskBackwardsLocked(task);
5546 Binder.restoreCallingIdentity(origId);
5547 }
5548 }
5549
5550 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005551 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 }
5553
5554 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5555 synchronized(this) {
5556 return getTaskForActivityLocked(token, onlyRoot);
5557 }
5558 }
5559
5560 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005561 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 TaskRecord lastTask = null;
5563 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005564 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005565 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 if (!onlyRoot || lastTask != r.task) {
5567 return r.task.taskId;
5568 }
5569 return -1;
5570 }
5571 lastTask = r.task;
5572 }
5573
5574 return -1;
5575 }
5576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005577 public void finishOtherInstances(IBinder token, ComponentName className) {
5578 synchronized(this) {
5579 final long origId = Binder.clearCallingIdentity();
5580
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005581 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 TaskRecord lastTask = null;
5583 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005584 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005585 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005586 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005587 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005588 null, "others")) {
5589 i--;
5590 N--;
5591 }
5592 }
5593 lastTask = r.task;
5594 }
5595
5596 Binder.restoreCallingIdentity(origId);
5597 }
5598 }
5599
5600 // =========================================================
5601 // THUMBNAILS
5602 // =========================================================
5603
5604 public void reportThumbnail(IBinder token,
5605 Bitmap thumbnail, CharSequence description) {
5606 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5607 final long origId = Binder.clearCallingIdentity();
5608 sendPendingThumbnail(null, token, thumbnail, description, true);
5609 Binder.restoreCallingIdentity(origId);
5610 }
5611
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005612 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 Bitmap thumbnail, CharSequence description, boolean always) {
5614 TaskRecord task = null;
5615 ArrayList receivers = null;
5616
5617 //System.out.println("Send pending thumbnail: " + r);
5618
5619 synchronized(this) {
5620 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005621 r = mMainStack.isInStackLocked(token);
5622 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 return;
5624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005625 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005626 if (thumbnail == null && r.thumbHolder != null) {
5627 thumbnail = r.thumbHolder.lastThumbnail;
5628 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005629 }
5630 if (thumbnail == null && !always) {
5631 // If there is no thumbnail, and this entry is not actually
5632 // going away, then abort for now and pick up the next
5633 // thumbnail we get.
5634 return;
5635 }
5636 task = r.task;
5637
5638 int N = mPendingThumbnails.size();
5639 int i=0;
5640 while (i<N) {
5641 PendingThumbnailsRecord pr =
5642 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5643 //System.out.println("Looking in " + pr.pendingRecords);
5644 if (pr.pendingRecords.remove(r)) {
5645 if (receivers == null) {
5646 receivers = new ArrayList();
5647 }
5648 receivers.add(pr);
5649 if (pr.pendingRecords.size() == 0) {
5650 pr.finished = true;
5651 mPendingThumbnails.remove(i);
5652 N--;
5653 continue;
5654 }
5655 }
5656 i++;
5657 }
5658 }
5659
5660 if (receivers != null) {
5661 final int N = receivers.size();
5662 for (int i=0; i<N; i++) {
5663 try {
5664 PendingThumbnailsRecord pr =
5665 (PendingThumbnailsRecord)receivers.get(i);
5666 pr.receiver.newThumbnail(
5667 task != null ? task.taskId : -1, thumbnail, description);
5668 if (pr.finished) {
5669 pr.receiver.finished();
5670 }
5671 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005672 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 }
5674 }
5675 }
5676 }
5677
5678 // =========================================================
5679 // CONTENT PROVIDERS
5680 // =========================================================
5681
Jeff Brown10e89712011-07-08 18:52:57 -07005682 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5683 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005684 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005685 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005686 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005687 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 } catch (RemoteException ex) {
5689 }
5690 if (providers != null) {
5691 final int N = providers.size();
5692 for (int i=0; i<N; i++) {
5693 ProviderInfo cpi =
5694 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005695 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5696 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005698 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005699 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005700 }
5701 app.pubProviders.put(cpi.name, cpr);
5702 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005703 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 }
5705 }
5706 return providers;
5707 }
5708
5709 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005710 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005711 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5712 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5713 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005714 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005715 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 return null;
5717 }
5718 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005719 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005720 == PackageManager.PERMISSION_GRANTED) {
5721 return null;
5722 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005723
5724 PathPermission[] pps = cpi.pathPermissions;
5725 if (pps != null) {
5726 int i = pps.length;
5727 while (i > 0) {
5728 i--;
5729 PathPermission pp = pps[i];
5730 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005731 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005732 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005733 return null;
5734 }
5735 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005736 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005737 == PackageManager.PERMISSION_GRANTED) {
5738 return null;
5739 }
5740 }
5741 }
5742
Dianne Hackbornb424b632010-08-18 15:59:05 -07005743 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5744 if (perms != null) {
5745 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5746 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5747 return null;
5748 }
5749 }
5750 }
5751
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005752 String msg;
5753 if (!cpi.exported) {
5754 msg = "Permission Denial: opening provider " + cpi.name
5755 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5756 + ", uid=" + callingUid + ") that is not exported from uid "
5757 + cpi.applicationInfo.uid;
5758 } else {
5759 msg = "Permission Denial: opening provider " + cpi.name
5760 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5761 + ", uid=" + callingUid + ") requires "
5762 + cpi.readPermission + " or " + cpi.writePermission;
5763 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005764 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005765 return msg;
5766 }
5767
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005768 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5769 if (r != null) {
5770 Integer cnt = r.conProviders.get(cpr);
5771 if (DEBUG_PROVIDER) Slog.v(TAG,
5772 "Adding provider requested by "
5773 + r.processName + " from process "
5774 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5775 + " cnt=" + (cnt == null ? 1 : cnt));
5776 if (cnt == null) {
5777 cpr.clients.add(r);
5778 r.conProviders.put(cpr, new Integer(1));
5779 return true;
5780 } else {
5781 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5782 }
5783 } else {
5784 cpr.externals++;
5785 }
5786 return false;
5787 }
5788
5789 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5790 if (r != null) {
5791 Integer cnt = r.conProviders.get(cpr);
5792 if (DEBUG_PROVIDER) Slog.v(TAG,
5793 "Removing provider requested by "
5794 + r.processName + " from process "
5795 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5796 + " cnt=" + cnt);
5797 if (cnt == null || cnt.intValue() <= 1) {
5798 cpr.clients.remove(r);
5799 r.conProviders.remove(cpr);
5800 return true;
5801 } else {
5802 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5803 }
5804 } else {
5805 cpr.externals++;
5806 }
5807 return false;
5808 }
5809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 private final ContentProviderHolder getContentProviderImpl(
5811 IApplicationThread caller, String name) {
5812 ContentProviderRecord cpr;
5813 ProviderInfo cpi = null;
5814
5815 synchronized(this) {
5816 ProcessRecord r = null;
5817 if (caller != null) {
5818 r = getRecordForAppLocked(caller);
5819 if (r == null) {
5820 throw new SecurityException(
5821 "Unable to find app for caller " + caller
5822 + " (pid=" + Binder.getCallingPid()
5823 + ") when getting content provider " + name);
5824 }
5825 }
5826
5827 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005828 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005829 boolean providerRunning = cpr != null;
5830 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005832 String msg;
5833 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5834 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005835 }
5836
5837 if (r != null && cpr.canRunHere(r)) {
5838 // This provider has been published or is in the process
5839 // of being published... but it is also allowed to run
5840 // in the caller's process, so don't make a connection
5841 // and just let the caller instantiate its own instance.
5842 if (cpr.provider != null) {
5843 // don't give caller the provider object, it needs
5844 // to make its own.
5845 cpr = new ContentProviderRecord(cpr);
5846 }
5847 return cpr;
5848 }
5849
5850 final long origId = Binder.clearCallingIdentity();
5851
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005852 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005853 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005854 final boolean countChanged = incProviderCount(r, cpr);
5855 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005856 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005857 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005858 // make sure to count it as being accessed and thus
5859 // back up on the LRU list. This is good because
5860 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005861 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005862 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005863 }
5864
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005865 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005866 if (false) {
5867 if (cpr.name.flattenToShortString().equals(
5868 "com.android.providers.calendar/.CalendarProvider2")) {
5869 Slog.v(TAG, "****************** KILLING "
5870 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005871 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005872 }
5873 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005874 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005875 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5876 // NOTE: there is still a race here where a signal could be
5877 // pending on the process even though we managed to update its
5878 // adj level. Not sure what to do about this, but at least
5879 // the race is now smaller.
5880 if (!success) {
5881 // Uh oh... it looks like the provider's process
5882 // has been killed on us. We need to wait for a new
5883 // process to be started, and make sure its death
5884 // doesn't kill our process.
5885 Slog.i(TAG,
5886 "Existing provider " + cpr.name.flattenToShortString()
5887 + " is crashing; detaching " + r);
5888 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005889 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005890 if (!lastRef) {
5891 // This wasn't the last ref our process had on
5892 // the provider... we have now been killed, bail.
5893 return null;
5894 }
5895 providerRunning = false;
5896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 }
5898
5899 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005901
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005902 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005904 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005905 resolveContentProvider(name,
5906 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 } catch (RemoteException ex) {
5908 }
5909 if (cpi == null) {
5910 return null;
5911 }
5912
Dianne Hackbornb424b632010-08-18 15:59:05 -07005913 String msg;
5914 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5915 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 }
5917
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005918 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005919 && !cpi.processName.equals("system")) {
5920 // If this content provider does not run in the system
5921 // process, and the system is not yet ready to run other
5922 // processes, then fail fast instead of hanging.
5923 throw new IllegalArgumentException(
5924 "Attempt to launch content provider before system ready");
5925 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005926
5927 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5928 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 final boolean firstClass = cpr == null;
5930 if (firstClass) {
5931 try {
5932 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005933 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005934 getApplicationInfo(
5935 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005936 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005938 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 + cpi.name);
5940 return null;
5941 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005942 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005943 } catch (RemoteException ex) {
5944 // pm is in same process, this will never happen.
5945 }
5946 }
5947
5948 if (r != null && cpr.canRunHere(r)) {
5949 // If this is a multiprocess provider, then just return its
5950 // info and allow the caller to instantiate it. Only do
5951 // this if the provider is the same user as the caller's
5952 // process, or can run as root (so can be in any process).
5953 return cpr;
5954 }
5955
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005956 if (DEBUG_PROVIDER) {
5957 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005958 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005959 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005960 }
5961
5962 // This is single process, and our app is now connecting to it.
5963 // See if we are already in the process of launching this
5964 // provider.
5965 final int N = mLaunchingProviders.size();
5966 int i;
5967 for (i=0; i<N; i++) {
5968 if (mLaunchingProviders.get(i) == cpr) {
5969 break;
5970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005971 }
5972
5973 // If the provider is not already being launched, then get it
5974 // started.
5975 if (i >= N) {
5976 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005977
5978 try {
5979 // Content provider is now in use, its package can't be stopped.
5980 try {
5981 AppGlobals.getPackageManager().setPackageStoppedState(
5982 cpr.appInfo.packageName, false);
5983 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005984 } catch (IllegalArgumentException e) {
5985 Slog.w(TAG, "Failed trying to unstop package "
5986 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005987 }
5988
5989 ProcessRecord proc = startProcessLocked(cpi.processName,
5990 cpr.appInfo, false, 0, "content provider",
5991 new ComponentName(cpi.applicationInfo.packageName,
5992 cpi.name), false);
5993 if (proc == null) {
5994 Slog.w(TAG, "Unable to launch app "
5995 + cpi.applicationInfo.packageName + "/"
5996 + cpi.applicationInfo.uid + " for provider "
5997 + name + ": process is bad");
5998 return null;
5999 }
6000 cpr.launchingApp = proc;
6001 mLaunchingProviders.add(cpr);
6002 } finally {
6003 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006005 }
6006
6007 // Make sure the provider is published (the same provider class
6008 // may be published under multiple names).
6009 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006010 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006011 }
6012 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006013 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006014 }
6015 }
6016
6017 // Wait for the provider to be published...
6018 synchronized (cpr) {
6019 while (cpr.provider == null) {
6020 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006021 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006022 + cpi.applicationInfo.packageName + "/"
6023 + cpi.applicationInfo.uid + " for provider "
6024 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006025 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 cpi.applicationInfo.packageName,
6027 cpi.applicationInfo.uid, name);
6028 return null;
6029 }
6030 try {
6031 cpr.wait();
6032 } catch (InterruptedException ex) {
6033 }
6034 }
6035 }
6036 return cpr;
6037 }
6038
6039 public final ContentProviderHolder getContentProvider(
6040 IApplicationThread caller, String name) {
6041 if (caller == null) {
6042 String msg = "null IApplicationThread when getting content provider "
6043 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006044 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006045 throw new SecurityException(msg);
6046 }
6047
6048 return getContentProviderImpl(caller, name);
6049 }
6050
6051 private ContentProviderHolder getContentProviderExternal(String name) {
6052 return getContentProviderImpl(null, name);
6053 }
6054
6055 /**
6056 * Drop a content provider from a ProcessRecord's bookkeeping
6057 * @param cpr
6058 */
6059 public void removeContentProvider(IApplicationThread caller, String name) {
6060 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006061 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006062 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006063 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006064 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006065 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 return;
6067 }
6068 final ProcessRecord r = getRecordForAppLocked(caller);
6069 if (r == null) {
6070 throw new SecurityException(
6071 "Unable to find app for caller " + caller +
6072 " when removing content provider " + name);
6073 }
6074 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006075 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6076 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006077 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006078 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006079 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006080 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 return;
6082 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006083 if (decProviderCount(r, localCpr)) {
6084 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006087 }
6088 }
6089
6090 private void removeContentProviderExternal(String name) {
6091 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006092 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006093 if(cpr == null) {
6094 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006095 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006096 return;
6097 }
6098
6099 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006100 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6101 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 localCpr.externals--;
6103 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006104 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 }
6106 updateOomAdjLocked();
6107 }
6108 }
6109
6110 public final void publishContentProviders(IApplicationThread caller,
6111 List<ContentProviderHolder> providers) {
6112 if (providers == null) {
6113 return;
6114 }
6115
6116 synchronized(this) {
6117 final ProcessRecord r = getRecordForAppLocked(caller);
6118 if (r == null) {
6119 throw new SecurityException(
6120 "Unable to find app for caller " + caller
6121 + " (pid=" + Binder.getCallingPid()
6122 + ") when publishing content providers");
6123 }
6124
6125 final long origId = Binder.clearCallingIdentity();
6126
6127 final int N = providers.size();
6128 for (int i=0; i<N; i++) {
6129 ContentProviderHolder src = providers.get(i);
6130 if (src == null || src.info == null || src.provider == null) {
6131 continue;
6132 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006133 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006134 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006135 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6136 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006137 String names[] = dst.info.authority.split(";");
6138 for (int j = 0; j < names.length; j++) {
6139 mProvidersByName.put(names[j], dst);
6140 }
6141
6142 int NL = mLaunchingProviders.size();
6143 int j;
6144 for (j=0; j<NL; j++) {
6145 if (mLaunchingProviders.get(j) == dst) {
6146 mLaunchingProviders.remove(j);
6147 j--;
6148 NL--;
6149 }
6150 }
6151 synchronized (dst) {
6152 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006153 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 dst.notifyAll();
6155 }
6156 updateOomAdjLocked(r);
6157 }
6158 }
6159
6160 Binder.restoreCallingIdentity(origId);
6161 }
6162 }
6163
6164 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006165 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006166 synchronized (mSelf) {
6167 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6168 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006169 if (providers != null) {
6170 for (int i=providers.size()-1; i>=0; i--) {
6171 ProviderInfo pi = (ProviderInfo)providers.get(i);
6172 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6173 Slog.w(TAG, "Not installing system proc provider " + pi.name
6174 + ": not system .apk");
6175 providers.remove(i);
6176 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006177 }
6178 }
6179 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006180 if (providers != null) {
6181 mSystemThread.installSystemProviders(providers);
6182 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006183
6184 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006185
6186 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006187 }
6188
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006189 /**
6190 * Allows app to retrieve the MIME type of a URI without having permission
6191 * to access its content provider.
6192 *
6193 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6194 *
6195 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6196 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6197 */
6198 public String getProviderMimeType(Uri uri) {
6199 final String name = uri.getAuthority();
6200 final long ident = Binder.clearCallingIdentity();
6201 ContentProviderHolder holder = null;
6202
6203 try {
6204 holder = getContentProviderExternal(name);
6205 if (holder != null) {
6206 return holder.provider.getType(uri);
6207 }
6208 } catch (RemoteException e) {
6209 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6210 return null;
6211 } finally {
6212 if (holder != null) {
6213 removeContentProviderExternal(name);
6214 }
6215 Binder.restoreCallingIdentity(ident);
6216 }
6217
6218 return null;
6219 }
6220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006221 // =========================================================
6222 // GLOBAL MANAGEMENT
6223 // =========================================================
6224
6225 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6226 ApplicationInfo info, String customProcess) {
6227 String proc = customProcess != null ? customProcess : info.processName;
6228 BatteryStatsImpl.Uid.Proc ps = null;
6229 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6230 synchronized (stats) {
6231 ps = stats.getProcessStatsLocked(info.uid, proc);
6232 }
6233 return new ProcessRecord(ps, thread, info, proc);
6234 }
6235
6236 final ProcessRecord addAppLocked(ApplicationInfo info) {
6237 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6238
6239 if (app == null) {
6240 app = newProcessRecordLocked(null, info, null);
6241 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006242 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006243 }
6244
Dianne Hackborne7f97212011-02-24 14:40:20 -08006245 // This package really, really can not be stopped.
6246 try {
6247 AppGlobals.getPackageManager().setPackageStoppedState(
6248 info.packageName, false);
6249 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006250 } catch (IllegalArgumentException e) {
6251 Slog.w(TAG, "Failed trying to unstop package "
6252 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006253 }
6254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6256 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6257 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006258 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 }
6260 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6261 mPersistentStartingProcesses.add(app);
6262 startProcessLocked(app, "added application", app.processName);
6263 }
6264
6265 return app;
6266 }
6267
6268 public void unhandledBack() {
6269 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6270 "unhandledBack()");
6271
6272 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006273 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006274 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 TAG, "Performing unhandledBack(): stack size = " + count);
6276 if (count > 1) {
6277 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006278 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6280 Binder.restoreCallingIdentity(origId);
6281 }
6282 }
6283 }
6284
6285 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6286 String name = uri.getAuthority();
6287 ContentProviderHolder cph = getContentProviderExternal(name);
6288 ParcelFileDescriptor pfd = null;
6289 if (cph != null) {
6290 // We record the binder invoker's uid in thread-local storage before
6291 // going to the content provider to open the file. Later, in the code
6292 // that handles all permissions checks, we look for this uid and use
6293 // that rather than the Activity Manager's own uid. The effect is that
6294 // we do the check against the caller's permissions even though it looks
6295 // to the content provider like the Activity Manager itself is making
6296 // the request.
6297 sCallerIdentity.set(new Identity(
6298 Binder.getCallingPid(), Binder.getCallingUid()));
6299 try {
6300 pfd = cph.provider.openFile(uri, "r");
6301 } catch (FileNotFoundException e) {
6302 // do nothing; pfd will be returned null
6303 } finally {
6304 // Ensure that whatever happens, we clean up the identity state
6305 sCallerIdentity.remove();
6306 }
6307
6308 // We've got the fd now, so we're done with the provider.
6309 removeContentProviderExternal(name);
6310 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006311 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006312 }
6313 return pfd;
6314 }
6315
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006316 // Actually is sleeping or shutting down or whatever else in the future
6317 // is an inactive state.
6318 public boolean isSleeping() {
6319 return mSleeping || mShuttingDown;
6320 }
6321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 public void goingToSleep() {
6323 synchronized(this) {
6324 mSleeping = true;
6325 mWindowManager.setEventDispatching(false);
6326
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006327 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006328
6329 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006330 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006331 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6332 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006333 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006334 }
6335 }
6336
Dianne Hackborn55280a92009-05-07 15:53:46 -07006337 public boolean shutdown(int timeout) {
6338 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6339 != PackageManager.PERMISSION_GRANTED) {
6340 throw new SecurityException("Requires permission "
6341 + android.Manifest.permission.SHUTDOWN);
6342 }
6343
6344 boolean timedout = false;
6345
6346 synchronized(this) {
6347 mShuttingDown = true;
6348 mWindowManager.setEventDispatching(false);
6349
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006350 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006351 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006352 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006353 while (mMainStack.mResumedActivity != null
6354 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006355 long delay = endTime - System.currentTimeMillis();
6356 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006357 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006358 timedout = true;
6359 break;
6360 }
6361 try {
6362 this.wait();
6363 } catch (InterruptedException e) {
6364 }
6365 }
6366 }
6367 }
6368
6369 mUsageStatsService.shutdown();
6370 mBatteryStatsService.shutdown();
6371
6372 return timedout;
6373 }
6374
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006375 public final void activitySlept(IBinder token) {
6376 if (localLOGV) Slog.v(
6377 TAG, "Activity slept: token=" + token);
6378
6379 ActivityRecord r = null;
6380
6381 final long origId = Binder.clearCallingIdentity();
6382
6383 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006384 r = mMainStack.isInStackLocked(token);
6385 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006386 mMainStack.activitySleptLocked(r);
6387 }
6388 }
6389
6390 Binder.restoreCallingIdentity(origId);
6391 }
6392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006393 public void wakingUp() {
6394 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 mWindowManager.setEventDispatching(true);
6396 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006397 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006398 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 }
6400 }
6401
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006402 public void stopAppSwitches() {
6403 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6404 != PackageManager.PERMISSION_GRANTED) {
6405 throw new SecurityException("Requires permission "
6406 + android.Manifest.permission.STOP_APP_SWITCHES);
6407 }
6408
6409 synchronized(this) {
6410 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6411 + APP_SWITCH_DELAY_TIME;
6412 mDidAppSwitch = false;
6413 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6414 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6415 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6416 }
6417 }
6418
6419 public void resumeAppSwitches() {
6420 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6421 != PackageManager.PERMISSION_GRANTED) {
6422 throw new SecurityException("Requires permission "
6423 + android.Manifest.permission.STOP_APP_SWITCHES);
6424 }
6425
6426 synchronized(this) {
6427 // Note that we don't execute any pending app switches... we will
6428 // let those wait until either the timeout, or the next start
6429 // activity request.
6430 mAppSwitchesAllowedTime = 0;
6431 }
6432 }
6433
6434 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6435 String name) {
6436 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6437 return true;
6438 }
6439
6440 final int perm = checkComponentPermission(
6441 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006442 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006443 if (perm == PackageManager.PERMISSION_GRANTED) {
6444 return true;
6445 }
6446
Joe Onorato8a9b2202010-02-26 18:56:32 -08006447 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006448 return false;
6449 }
6450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006451 public void setDebugApp(String packageName, boolean waitForDebugger,
6452 boolean persistent) {
6453 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6454 "setDebugApp()");
6455
6456 // Note that this is not really thread safe if there are multiple
6457 // callers into it at the same time, but that's not a situation we
6458 // care about.
6459 if (persistent) {
6460 final ContentResolver resolver = mContext.getContentResolver();
6461 Settings.System.putString(
6462 resolver, Settings.System.DEBUG_APP,
6463 packageName);
6464 Settings.System.putInt(
6465 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6466 waitForDebugger ? 1 : 0);
6467 }
6468
6469 synchronized (this) {
6470 if (!persistent) {
6471 mOrigDebugApp = mDebugApp;
6472 mOrigWaitForDebugger = mWaitForDebugger;
6473 }
6474 mDebugApp = packageName;
6475 mWaitForDebugger = waitForDebugger;
6476 mDebugTransient = !persistent;
6477 if (packageName != null) {
6478 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006479 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006480 Binder.restoreCallingIdentity(origId);
6481 }
6482 }
6483 }
6484
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006485 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6486 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6487 synchronized (this) {
6488 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6489 if (!isDebuggable) {
6490 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6491 throw new SecurityException("Process not debuggable: " + app.packageName);
6492 }
6493 }
6494 mProfileApp = processName;
6495 mProfileFile = profileFile;
6496 if (mProfileFd != null) {
6497 try {
6498 mProfileFd.close();
6499 } catch (IOException e) {
6500 }
6501 mProfileFd = null;
6502 }
6503 mProfileFd = profileFd;
6504 mProfileType = 0;
6505 mAutoStopProfiler = autoStopProfiler;
6506 }
6507 }
6508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 public void setAlwaysFinish(boolean enabled) {
6510 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6511 "setAlwaysFinish()");
6512
6513 Settings.System.putInt(
6514 mContext.getContentResolver(),
6515 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6516
6517 synchronized (this) {
6518 mAlwaysFinishActivities = enabled;
6519 }
6520 }
6521
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006522 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006523 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006524 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006525 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006526 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006527 }
6528 }
6529
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006530 public boolean isUserAMonkey() {
6531 // For now the fact that there is a controller implies
6532 // we have a monkey.
6533 synchronized (this) {
6534 return mController != null;
6535 }
6536 }
6537
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006538 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006539 synchronized (this) {
6540 mWatchers.register(watcher);
6541 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006542 }
6543
6544 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006545 synchronized (this) {
6546 mWatchers.unregister(watcher);
6547 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006548 }
6549
Jeff Sharkeya4620792011-05-20 15:29:23 -07006550 public void registerProcessObserver(IProcessObserver observer) {
6551 mProcessObservers.register(observer);
6552 }
6553
6554 public void unregisterProcessObserver(IProcessObserver observer) {
6555 mProcessObservers.unregister(observer);
6556 }
6557
Daniel Sandler69a48172010-06-23 16:29:36 -04006558 public void setImmersive(IBinder token, boolean immersive) {
6559 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006560 ActivityRecord r = mMainStack.isInStackLocked(token);
6561 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006562 throw new IllegalArgumentException();
6563 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006564 r.immersive = immersive;
6565 }
6566 }
6567
6568 public boolean isImmersive(IBinder token) {
6569 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006570 ActivityRecord r = mMainStack.isInStackLocked(token);
6571 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006572 throw new IllegalArgumentException();
6573 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006574 return r.immersive;
6575 }
6576 }
6577
6578 public boolean isTopActivityImmersive() {
6579 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006580 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006581 return (r != null) ? r.immersive : false;
6582 }
6583 }
6584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006585 public final void enterSafeMode() {
6586 synchronized(this) {
6587 // It only makes sense to do this before the system is ready
6588 // and started launching other packages.
6589 if (!mSystemReady) {
6590 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006591 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006592 } catch (RemoteException e) {
6593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006594 }
6595 }
6596 }
6597
Jeff Brownb09abc12011-01-13 21:08:27 -08006598 public final void showSafeModeOverlay() {
6599 View v = LayoutInflater.from(mContext).inflate(
6600 com.android.internal.R.layout.safe_mode, null);
6601 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6602 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6603 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6604 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6605 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6606 lp.format = v.getBackground().getOpacity();
6607 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6608 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6609 ((WindowManager)mContext.getSystemService(
6610 Context.WINDOW_SERVICE)).addView(v, lp);
6611 }
6612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 public void noteWakeupAlarm(IIntentSender sender) {
6614 if (!(sender instanceof PendingIntentRecord)) {
6615 return;
6616 }
6617 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6618 synchronized (stats) {
6619 if (mBatteryStatsService.isOnBattery()) {
6620 mBatteryStatsService.enforceCallingPermission();
6621 PendingIntentRecord rec = (PendingIntentRecord)sender;
6622 int MY_UID = Binder.getCallingUid();
6623 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6624 BatteryStatsImpl.Uid.Pkg pkg =
6625 stats.getPackageStatsLocked(uid, rec.key.packageName);
6626 pkg.incWakeupsLocked();
6627 }
6628 }
6629 }
6630
Dianne Hackborn64825172011-03-02 21:32:58 -08006631 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006632 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006633 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006635 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 // XXX Note: don't acquire main activity lock here, because the window
6637 // manager calls in with its locks held.
6638
6639 boolean killed = false;
6640 synchronized (mPidsSelfLocked) {
6641 int[] types = new int[pids.length];
6642 int worstType = 0;
6643 for (int i=0; i<pids.length; i++) {
6644 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6645 if (proc != null) {
6646 int type = proc.setAdj;
6647 types[i] = type;
6648 if (type > worstType) {
6649 worstType = type;
6650 }
6651 }
6652 }
6653
Dianne Hackborn64825172011-03-02 21:32:58 -08006654 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006655 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006656 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6657 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006658 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006659 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006660
6661 // If this is not a secure call, don't let it kill processes that
6662 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006663 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6664 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006665 }
6666
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006667 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 for (int i=0; i<pids.length; i++) {
6669 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6670 if (proc == null) {
6671 continue;
6672 }
6673 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006674 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006675 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006676 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6677 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006678 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006679 proc.killedBackground = true;
6680 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 }
6682 }
6683 }
6684 return killed;
6685 }
6686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006687 public final void startRunning(String pkg, String cls, String action,
6688 String data) {
6689 synchronized(this) {
6690 if (mStartRunning) {
6691 return;
6692 }
6693 mStartRunning = true;
6694 mTopComponent = pkg != null && cls != null
6695 ? new ComponentName(pkg, cls) : null;
6696 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6697 mTopData = data;
6698 if (!mSystemReady) {
6699 return;
6700 }
6701 }
6702
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006703 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006704 }
6705
6706 private void retrieveSettings() {
6707 final ContentResolver resolver = mContext.getContentResolver();
6708 String debugApp = Settings.System.getString(
6709 resolver, Settings.System.DEBUG_APP);
6710 boolean waitForDebugger = Settings.System.getInt(
6711 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6712 boolean alwaysFinishActivities = Settings.System.getInt(
6713 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6714
6715 Configuration configuration = new Configuration();
6716 Settings.System.getConfiguration(resolver, configuration);
6717
6718 synchronized (this) {
6719 mDebugApp = mOrigDebugApp = debugApp;
6720 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6721 mAlwaysFinishActivities = alwaysFinishActivities;
6722 // This happens before any activities are started, so we can
6723 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006724 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006725 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006726 }
6727 }
6728
6729 public boolean testIsSystemReady() {
6730 // no need to synchronize(this) just to read & return the value
6731 return mSystemReady;
6732 }
6733
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006734 private static File getCalledPreBootReceiversFile() {
6735 File dataDir = Environment.getDataDirectory();
6736 File systemDir = new File(dataDir, "system");
6737 File fname = new File(systemDir, "called_pre_boots.dat");
6738 return fname;
6739 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006740
6741 static final int LAST_DONE_VERSION = 10000;
6742
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006743 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6744 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6745 File file = getCalledPreBootReceiversFile();
6746 FileInputStream fis = null;
6747 try {
6748 fis = new FileInputStream(file);
6749 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006750 int fvers = dis.readInt();
6751 if (fvers == LAST_DONE_VERSION) {
6752 String vers = dis.readUTF();
6753 String codename = dis.readUTF();
6754 String build = dis.readUTF();
6755 if (android.os.Build.VERSION.RELEASE.equals(vers)
6756 && android.os.Build.VERSION.CODENAME.equals(codename)
6757 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6758 int num = dis.readInt();
6759 while (num > 0) {
6760 num--;
6761 String pkg = dis.readUTF();
6762 String cls = dis.readUTF();
6763 lastDoneReceivers.add(new ComponentName(pkg, cls));
6764 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006765 }
6766 }
6767 } catch (FileNotFoundException e) {
6768 } catch (IOException e) {
6769 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6770 } finally {
6771 if (fis != null) {
6772 try {
6773 fis.close();
6774 } catch (IOException e) {
6775 }
6776 }
6777 }
6778 return lastDoneReceivers;
6779 }
6780
6781 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6782 File file = getCalledPreBootReceiversFile();
6783 FileOutputStream fos = null;
6784 DataOutputStream dos = null;
6785 try {
6786 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6787 fos = new FileOutputStream(file);
6788 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006789 dos.writeInt(LAST_DONE_VERSION);
6790 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006791 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006792 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006793 dos.writeInt(list.size());
6794 for (int i=0; i<list.size(); i++) {
6795 dos.writeUTF(list.get(i).getPackageName());
6796 dos.writeUTF(list.get(i).getClassName());
6797 }
6798 } catch (IOException e) {
6799 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6800 file.delete();
6801 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006802 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006803 if (dos != null) {
6804 try {
6805 dos.close();
6806 } catch (IOException e) {
6807 // TODO Auto-generated catch block
6808 e.printStackTrace();
6809 }
6810 }
6811 }
6812 }
6813
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006814 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 synchronized(this) {
6816 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006817 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 return;
6819 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006820
6821 // Check to see if there are any update receivers to run.
6822 if (!mDidUpdate) {
6823 if (mWaitingUpdate) {
6824 return;
6825 }
6826 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6827 List<ResolveInfo> ris = null;
6828 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006829 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006830 intent, null, 0);
6831 } catch (RemoteException e) {
6832 }
6833 if (ris != null) {
6834 for (int i=ris.size()-1; i>=0; i--) {
6835 if ((ris.get(i).activityInfo.applicationInfo.flags
6836 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6837 ris.remove(i);
6838 }
6839 }
6840 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006841
6842 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6843
6844 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006845 for (int i=0; i<ris.size(); i++) {
6846 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006847 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6848 if (lastDoneReceivers.contains(comp)) {
6849 ris.remove(i);
6850 i--;
6851 }
6852 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006853
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006854 for (int i=0; i<ris.size(); i++) {
6855 ActivityInfo ai = ris.get(i).activityInfo;
6856 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6857 doneReceivers.add(comp);
6858 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006859 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006860 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006861 finisher = new IIntentReceiver.Stub() {
6862 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006863 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006864 boolean sticky) {
6865 // The raw IIntentReceiver interface is called
6866 // with the AM lock held, so redispatch to
6867 // execute our code without the lock.
6868 mHandler.post(new Runnable() {
6869 public void run() {
6870 synchronized (ActivityManagerService.this) {
6871 mDidUpdate = true;
6872 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006873 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006874 showBootMessage(mContext.getText(
6875 R.string.android_upgrading_complete),
6876 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006877 systemReady(goingCallback);
6878 }
6879 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006880 }
6881 };
6882 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006883 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006884 broadcastIntentLocked(null, null, intent, null, finisher,
6885 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006886 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006887 mWaitingUpdate = true;
6888 }
6889 }
6890 }
6891 if (mWaitingUpdate) {
6892 return;
6893 }
6894 mDidUpdate = true;
6895 }
6896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 mSystemReady = true;
6898 if (!mStartRunning) {
6899 return;
6900 }
6901 }
6902
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006903 ArrayList<ProcessRecord> procsToKill = null;
6904 synchronized(mPidsSelfLocked) {
6905 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6906 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6907 if (!isAllowedWhileBooting(proc.info)){
6908 if (procsToKill == null) {
6909 procsToKill = new ArrayList<ProcessRecord>();
6910 }
6911 procsToKill.add(proc);
6912 }
6913 }
6914 }
6915
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006916 synchronized(this) {
6917 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006918 for (int i=procsToKill.size()-1; i>=0; i--) {
6919 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006920 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006921 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006922 }
6923 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006924
6925 // Now that we have cleaned up any update processes, we
6926 // are ready to start launching real processes and know that
6927 // we won't trample on them any more.
6928 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006929 }
6930
Joe Onorato8a9b2202010-02-26 18:56:32 -08006931 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006932 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 SystemClock.uptimeMillis());
6934
6935 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006936 // Make sure we have no pre-ready processes sitting around.
6937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006938 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6939 ResolveInfo ri = mContext.getPackageManager()
6940 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006941 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006942 CharSequence errorMsg = null;
6943 if (ri != null) {
6944 ActivityInfo ai = ri.activityInfo;
6945 ApplicationInfo app = ai.applicationInfo;
6946 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6947 mTopAction = Intent.ACTION_FACTORY_TEST;
6948 mTopData = null;
6949 mTopComponent = new ComponentName(app.packageName,
6950 ai.name);
6951 } else {
6952 errorMsg = mContext.getResources().getText(
6953 com.android.internal.R.string.factorytest_not_system);
6954 }
6955 } else {
6956 errorMsg = mContext.getResources().getText(
6957 com.android.internal.R.string.factorytest_no_action);
6958 }
6959 if (errorMsg != null) {
6960 mTopAction = null;
6961 mTopData = null;
6962 mTopComponent = null;
6963 Message msg = Message.obtain();
6964 msg.what = SHOW_FACTORY_ERROR_MSG;
6965 msg.getData().putCharSequence("msg", errorMsg);
6966 mHandler.sendMessage(msg);
6967 }
6968 }
6969 }
6970
6971 retrieveSettings();
6972
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006973 if (goingCallback != null) goingCallback.run();
6974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006975 synchronized (this) {
6976 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6977 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006978 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006979 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006980 if (apps != null) {
6981 int N = apps.size();
6982 int i;
6983 for (i=0; i<N; i++) {
6984 ApplicationInfo info
6985 = (ApplicationInfo)apps.get(i);
6986 if (info != null &&
6987 !info.packageName.equals("android")) {
6988 addAppLocked(info);
6989 }
6990 }
6991 }
6992 } catch (RemoteException ex) {
6993 // pm is in same process, this will never happen.
6994 }
6995 }
6996
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006997 // Start up initial activity.
6998 mBooting = true;
6999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007001 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 Message msg = Message.obtain();
7003 msg.what = SHOW_UID_ERROR_MSG;
7004 mHandler.sendMessage(msg);
7005 }
7006 } catch (RemoteException e) {
7007 }
7008
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007009 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 }
7011 }
7012
Dan Egnorb7f03672009-12-09 16:22:32 -08007013 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007014 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007016 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007017 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 startAppProblemLocked(app);
7019 app.stopFreezingAllLocked();
7020 return handleAppCrashLocked(app);
7021 }
7022
Dan Egnorb7f03672009-12-09 16:22:32 -08007023 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007024 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007026 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007027 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7028 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 startAppProblemLocked(app);
7030 app.stopFreezingAllLocked();
7031 }
7032
7033 /**
7034 * Generate a process error record, suitable for attachment to a ProcessRecord.
7035 *
7036 * @param app The ProcessRecord in which the error occurred.
7037 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7038 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007039 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 * @param shortMsg Short message describing the crash.
7041 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007042 * @param stackTrace Full crash stack trace, may be null.
7043 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007044 * @return Returns a fully-formed AppErrorStateInfo record.
7045 */
7046 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007047 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007048 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 report.condition = condition;
7051 report.processName = app.processName;
7052 report.pid = app.pid;
7053 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007054 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007055 report.shortMsg = shortMsg;
7056 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007057 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007058
7059 return report;
7060 }
7061
Dan Egnor42471dd2010-01-07 17:25:22 -08007062 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007063 synchronized (this) {
7064 app.crashing = false;
7065 app.crashingReport = null;
7066 app.notResponding = false;
7067 app.notRespondingReport = null;
7068 if (app.anrDialog == fromDialog) {
7069 app.anrDialog = null;
7070 }
7071 if (app.waitDialog == fromDialog) {
7072 app.waitDialog = null;
7073 }
7074 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007075 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007076 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007077 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7078 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007079 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 }
7082 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007083
Dan Egnorb7f03672009-12-09 16:22:32 -08007084 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 long now = SystemClock.uptimeMillis();
7086
7087 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7088 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007089 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007090 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007091 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007092 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007093 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007094 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007095 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7096 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007097 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007098 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007099 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007100 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007101 }
7102 }
7103 if (!app.persistent) {
7104 // We don't want to start this process again until the user
7105 // explicitly does so... but for persistent process, we really
7106 // need to keep it running. If a persistent process is actually
7107 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007108 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007109 app.info.processName);
7110 mBadProcesses.put(app.info.processName, app.info.uid, now);
7111 app.bad = true;
7112 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7113 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007114 // Don't let services in this process be restarted and potentially
7115 // annoy the user repeatedly. Unless it is persistent, since those
7116 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007117 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007118 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007119 return false;
7120 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007121 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007122 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007123 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007124 if (r.app == app) {
7125 // If the top running activity is from this crashing
7126 // process, then terminate it to avoid getting in a loop.
7127 Slog.w(TAG, " Force finishing activity "
7128 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007129 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007130 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007131 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007132 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007133 // stopped, to avoid a situation where one will get
7134 // re-start our crashing activity once it gets resumed again.
7135 index--;
7136 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007137 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007138 if (r.state == ActivityState.RESUMED
7139 || r.state == ActivityState.PAUSING
7140 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007141 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007142 Slog.w(TAG, " Force finishing activity "
7143 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007144 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007145 Activity.RESULT_CANCELED, null, "crashed");
7146 }
7147 }
7148 }
7149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007150 }
7151
7152 // Bump up the crash count of any services currently running in the proc.
7153 if (app.services.size() != 0) {
7154 // Any services running in the application need to be placed
7155 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007156 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007157 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007158 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007159 sr.crashCount++;
7160 }
7161 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007162
7163 // If the crashing process is what we consider to be the "home process" and it has been
7164 // replaced by a third-party app, clear the package preferred activities from packages
7165 // with a home activity running in the process to prevent a repeatedly crashing app
7166 // from blocking the user to manually clear the list.
7167 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7168 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7169 Iterator it = mHomeProcess.activities.iterator();
7170 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007171 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007172 if (r.isHomeActivity) {
7173 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7174 try {
7175 ActivityThread.getPackageManager()
7176 .clearPackagePreferredActivities(r.packageName);
7177 } catch (RemoteException c) {
7178 // pm is in same process, this will never happen.
7179 }
7180 }
7181 }
7182 }
7183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7185 return true;
7186 }
7187
7188 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007189 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7190 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007191 skipCurrentReceiverLocked(app);
7192 }
7193
7194 void skipCurrentReceiverLocked(ProcessRecord app) {
7195 boolean reschedule = false;
7196 BroadcastRecord r = app.curReceiver;
7197 if (r != null) {
7198 // The current broadcast is waiting for this app's receiver
7199 // to be finished. Looks like that's not going to happen, so
7200 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007201 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7203 r.resultExtras, r.resultAbort, true);
7204 reschedule = true;
7205 }
7206 r = mPendingBroadcast;
7207 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007208 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007209 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007210 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007211 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7212 r.resultExtras, r.resultAbort, true);
7213 reschedule = true;
7214 }
7215 if (reschedule) {
7216 scheduleBroadcastsLocked();
7217 }
7218 }
7219
Dan Egnor60d87622009-12-16 16:32:58 -08007220 /**
7221 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7222 * The application process will exit immediately after this call returns.
7223 * @param app object of the crashing app, null for the system server
7224 * @param crashInfo describing the exception
7225 */
7226 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007227 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007228 final String processName = app == null ? "system_server"
7229 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007230
7231 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007232 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007233 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007234 crashInfo.exceptionClassName,
7235 crashInfo.exceptionMessage,
7236 crashInfo.throwFileName,
7237 crashInfo.throwLineNumber);
7238
Jeff Sharkeya353d262011-10-28 11:12:06 -07007239 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007240
7241 crashApplication(r, crashInfo);
7242 }
7243
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007244 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007245 IBinder app,
7246 int violationMask,
7247 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007248 ProcessRecord r = findAppProcess(app, "StrictMode");
7249 if (r == null) {
7250 return;
7251 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007252
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007253 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007254 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007255 boolean logIt = true;
7256 synchronized (mAlreadyLoggedViolatedStacks) {
7257 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7258 logIt = false;
7259 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007260 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007261 // the relative pain numbers, without logging all
7262 // the stack traces repeatedly. We'd want to do
7263 // likewise in the client code, which also does
7264 // dup suppression, before the Binder call.
7265 } else {
7266 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7267 mAlreadyLoggedViolatedStacks.clear();
7268 }
7269 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7270 }
7271 }
7272 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007273 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007274 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007275 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007276
7277 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7278 AppErrorResult result = new AppErrorResult();
7279 synchronized (this) {
7280 final long origId = Binder.clearCallingIdentity();
7281
7282 Message msg = Message.obtain();
7283 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7284 HashMap<String, Object> data = new HashMap<String, Object>();
7285 data.put("result", result);
7286 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007287 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007288 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007289 msg.obj = data;
7290 mHandler.sendMessage(msg);
7291
7292 Binder.restoreCallingIdentity(origId);
7293 }
7294 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007295 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007296 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007297 }
7298
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007299 // Depending on the policy in effect, there could be a bunch of
7300 // these in quick succession so we try to batch these together to
7301 // minimize disk writes, number of dropbox entries, and maximize
7302 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007303 private void logStrictModeViolationToDropBox(
7304 ProcessRecord process,
7305 StrictMode.ViolationInfo info) {
7306 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007307 return;
7308 }
7309 final boolean isSystemApp = process == null ||
7310 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7311 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007312 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007313 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7314 final DropBoxManager dbox = (DropBoxManager)
7315 mContext.getSystemService(Context.DROPBOX_SERVICE);
7316
7317 // Exit early if the dropbox isn't configured to accept this report type.
7318 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7319
7320 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007321 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007322 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7323 synchronized (sb) {
7324 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007325 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007326 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7327 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007328 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7329 if (info.violationNumThisLoop != 0) {
7330 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7331 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007332 if (info.numAnimationsRunning != 0) {
7333 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7334 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007335 if (info.broadcastIntentAction != null) {
7336 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7337 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007338 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007339 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007340 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007341 if (info.numInstances != -1) {
7342 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7343 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007344 if (info.tags != null) {
7345 for (String tag : info.tags) {
7346 sb.append("Span-Tag: ").append(tag).append("\n");
7347 }
7348 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007349 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007350 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7351 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007352 }
7353 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007354
7355 // Only buffer up to ~64k. Various logging bits truncate
7356 // things at 128k.
7357 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007358 }
7359
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007360 // Flush immediately if the buffer's grown too large, or this
7361 // is a non-system app. Non-system apps are isolated with a
7362 // different tag & policy and not batched.
7363 //
7364 // Batching is useful during internal testing with
7365 // StrictMode settings turned up high. Without batching,
7366 // thousands of separate files could be created on boot.
7367 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007368 new Thread("Error dump: " + dropboxTag) {
7369 @Override
7370 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007371 String report;
7372 synchronized (sb) {
7373 report = sb.toString();
7374 sb.delete(0, sb.length());
7375 sb.trimToSize();
7376 }
7377 if (report.length() != 0) {
7378 dbox.addText(dropboxTag, report);
7379 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007380 }
7381 }.start();
7382 return;
7383 }
7384
7385 // System app batching:
7386 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007387 // An existing dropbox-writing thread is outstanding, so
7388 // we don't need to start it up. The existing thread will
7389 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007390 return;
7391 }
7392
7393 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7394 // (After this point, we shouldn't access AMS internal data structures.)
7395 new Thread("Error dump: " + dropboxTag) {
7396 @Override
7397 public void run() {
7398 // 5 second sleep to let stacks arrive and be batched together
7399 try {
7400 Thread.sleep(5000); // 5 seconds
7401 } catch (InterruptedException e) {}
7402
7403 String errorReport;
7404 synchronized (mStrictModeBuffer) {
7405 errorReport = mStrictModeBuffer.toString();
7406 if (errorReport.length() == 0) {
7407 return;
7408 }
7409 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7410 mStrictModeBuffer.trimToSize();
7411 }
7412 dbox.addText(dropboxTag, errorReport);
7413 }
7414 }.start();
7415 }
7416
Dan Egnor60d87622009-12-16 16:32:58 -08007417 /**
7418 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7419 * @param app object of the crashing app, null for the system server
7420 * @param tag reported by the caller
7421 * @param crashInfo describing the context of the error
7422 * @return true if the process should exit immediately (WTF is fatal)
7423 */
7424 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007425 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007426 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007427 final String processName = app == null ? "system_server"
7428 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007429
7430 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007431 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007432 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007433 tag, crashInfo.exceptionMessage);
7434
Jeff Sharkeya353d262011-10-28 11:12:06 -07007435 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007436
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007437 if (r != null && r.pid != Process.myPid() &&
7438 Settings.Secure.getInt(mContext.getContentResolver(),
7439 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007440 crashApplication(r, crashInfo);
7441 return true;
7442 } else {
7443 return false;
7444 }
7445 }
7446
7447 /**
7448 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7449 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7450 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007451 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007452 if (app == null) {
7453 return null;
7454 }
7455
7456 synchronized (this) {
7457 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7458 final int NA = apps.size();
7459 for (int ia=0; ia<NA; ia++) {
7460 ProcessRecord p = apps.valueAt(ia);
7461 if (p.thread != null && p.thread.asBinder() == app) {
7462 return p;
7463 }
7464 }
7465 }
7466
Dianne Hackborncb44d962011-03-10 17:02:27 -08007467 Slog.w(TAG, "Can't find mystery application for " + reason
7468 + " from pid=" + Binder.getCallingPid()
7469 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007470 return null;
7471 }
7472 }
7473
7474 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007475 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7476 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007477 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007478 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7479 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007480 // Watchdog thread ends up invoking this function (with
7481 // a null ProcessRecord) to add the stack file to dropbox.
7482 // Do not acquire a lock on this (am) in such cases, as it
7483 // could cause a potential deadlock, if and when watchdog
7484 // is invoked due to unavailability of lock on am and it
7485 // would prevent watchdog from killing system_server.
7486 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007487 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007488 return;
7489 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007490 // Note: ProcessRecord 'process' is guarded by the service
7491 // instance. (notably process.pkgList, which could otherwise change
7492 // concurrently during execution of this method)
7493 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007494 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007495 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007496 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007497 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7498 for (String pkg : process.pkgList) {
7499 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007500 try {
Dan Egnora455d192010-03-12 08:52:28 -08007501 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7502 if (pi != null) {
7503 sb.append(" v").append(pi.versionCode);
7504 if (pi.versionName != null) {
7505 sb.append(" (").append(pi.versionName).append(")");
7506 }
7507 }
7508 } catch (RemoteException e) {
7509 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007510 }
Dan Egnora455d192010-03-12 08:52:28 -08007511 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007512 }
Dan Egnora455d192010-03-12 08:52:28 -08007513 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007514 }
7515
7516 private static String processClass(ProcessRecord process) {
7517 if (process == null || process.pid == MY_PID) {
7518 return "system_server";
7519 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7520 return "system_app";
7521 } else {
7522 return "data_app";
7523 }
7524 }
7525
7526 /**
7527 * Write a description of an error (crash, WTF, ANR) to the drop box.
7528 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7529 * @param process which caused the error, null means the system server
7530 * @param activity which triggered the error, null if unknown
7531 * @param parent activity related to the error, null if unknown
7532 * @param subject line related to the error, null if absent
7533 * @param report in long form describing the error, null if absent
7534 * @param logFile to include in the report, null if none
7535 * @param crashInfo giving an application stack trace, null if absent
7536 */
7537 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007538 ProcessRecord process, String processName, ActivityRecord activity,
7539 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007540 final String report, final File logFile,
7541 final ApplicationErrorReport.CrashInfo crashInfo) {
7542 // NOTE -- this must never acquire the ActivityManagerService lock,
7543 // otherwise the watchdog may be prevented from resetting the system.
7544
7545 final String dropboxTag = processClass(process) + "_" + eventType;
7546 final DropBoxManager dbox = (DropBoxManager)
7547 mContext.getSystemService(Context.DROPBOX_SERVICE);
7548
7549 // Exit early if the dropbox isn't configured to accept this report type.
7550 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7551
7552 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007553 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007554 if (activity != null) {
7555 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7556 }
7557 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7558 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7559 }
7560 if (parent != null && parent != activity) {
7561 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7562 }
7563 if (subject != null) {
7564 sb.append("Subject: ").append(subject).append("\n");
7565 }
7566 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007567 if (Debug.isDebuggerConnected()) {
7568 sb.append("Debugger: Connected\n");
7569 }
Dan Egnora455d192010-03-12 08:52:28 -08007570 sb.append("\n");
7571
7572 // Do the rest in a worker thread to avoid blocking the caller on I/O
7573 // (After this point, we shouldn't access AMS internal data structures.)
7574 Thread worker = new Thread("Error dump: " + dropboxTag) {
7575 @Override
7576 public void run() {
7577 if (report != null) {
7578 sb.append(report);
7579 }
7580 if (logFile != null) {
7581 try {
7582 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7583 } catch (IOException e) {
7584 Slog.e(TAG, "Error reading " + logFile, e);
7585 }
7586 }
7587 if (crashInfo != null && crashInfo.stackTrace != null) {
7588 sb.append(crashInfo.stackTrace);
7589 }
7590
7591 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7592 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7593 if (lines > 0) {
7594 sb.append("\n");
7595
7596 // Merge several logcat streams, and take the last N lines
7597 InputStreamReader input = null;
7598 try {
7599 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7600 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7601 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7602
7603 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7604 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7605 input = new InputStreamReader(logcat.getInputStream());
7606
7607 int num;
7608 char[] buf = new char[8192];
7609 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7610 } catch (IOException e) {
7611 Slog.e(TAG, "Error running logcat", e);
7612 } finally {
7613 if (input != null) try { input.close(); } catch (IOException e) {}
7614 }
7615 }
7616
7617 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007618 }
Dan Egnora455d192010-03-12 08:52:28 -08007619 };
7620
7621 if (process == null || process.pid == MY_PID) {
7622 worker.run(); // We may be about to die -- need to run this synchronously
7623 } else {
7624 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007625 }
7626 }
7627
7628 /**
7629 * Bring up the "unexpected error" dialog box for a crashing app.
7630 * Deal with edge cases (intercepts from instrumented applications,
7631 * ActivityController, error intent receivers, that sort of thing).
7632 * @param r the application crashing
7633 * @param crashInfo describing the failure
7634 */
7635 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007636 long timeMillis = System.currentTimeMillis();
7637 String shortMsg = crashInfo.exceptionClassName;
7638 String longMsg = crashInfo.exceptionMessage;
7639 String stackTrace = crashInfo.stackTrace;
7640 if (shortMsg != null && longMsg != null) {
7641 longMsg = shortMsg + ": " + longMsg;
7642 } else if (shortMsg != null) {
7643 longMsg = shortMsg;
7644 }
7645
Dan Egnor60d87622009-12-16 16:32:58 -08007646 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007647 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007648 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007649 try {
7650 String name = r != null ? r.processName : null;
7651 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007652 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007653 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007654 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007655 + " at watcher's request");
7656 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007657 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007658 }
7659 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007660 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007661 }
7662 }
7663
7664 final long origId = Binder.clearCallingIdentity();
7665
7666 // If this process is running instrumentation, finish it.
7667 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007668 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007670 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7671 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 Bundle info = new Bundle();
7673 info.putString("shortMsg", shortMsg);
7674 info.putString("longMsg", longMsg);
7675 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7676 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007677 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007678 }
7679
Dan Egnor60d87622009-12-16 16:32:58 -08007680 // If we can't identify the process or it's already exceeded its crash quota,
7681 // quit right away without showing a crash dialog.
7682 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007683 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007684 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007685 }
7686
7687 Message msg = Message.obtain();
7688 msg.what = SHOW_ERROR_MSG;
7689 HashMap data = new HashMap();
7690 data.put("result", result);
7691 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007692 msg.obj = data;
7693 mHandler.sendMessage(msg);
7694
7695 Binder.restoreCallingIdentity(origId);
7696 }
7697
7698 int res = result.get();
7699
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007700 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007701 synchronized (this) {
7702 if (r != null) {
7703 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7704 SystemClock.uptimeMillis());
7705 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007706 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007707 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007708 }
7709 }
7710
7711 if (appErrorIntent != null) {
7712 try {
7713 mContext.startActivity(appErrorIntent);
7714 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007715 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007719
7720 Intent createAppErrorIntentLocked(ProcessRecord r,
7721 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7722 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007723 if (report == null) {
7724 return null;
7725 }
7726 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7727 result.setComponent(r.errorReportReceiver);
7728 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7729 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7730 return result;
7731 }
7732
Dan Egnorb7f03672009-12-09 16:22:32 -08007733 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7734 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007735 if (r.errorReportReceiver == null) {
7736 return null;
7737 }
7738
7739 if (!r.crashing && !r.notResponding) {
7740 return null;
7741 }
7742
Dan Egnorb7f03672009-12-09 16:22:32 -08007743 ApplicationErrorReport report = new ApplicationErrorReport();
7744 report.packageName = r.info.packageName;
7745 report.installerPackageName = r.errorReportReceiver.getPackageName();
7746 report.processName = r.processName;
7747 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007748 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007749
Dan Egnorb7f03672009-12-09 16:22:32 -08007750 if (r.crashing) {
7751 report.type = ApplicationErrorReport.TYPE_CRASH;
7752 report.crashInfo = crashInfo;
7753 } else if (r.notResponding) {
7754 report.type = ApplicationErrorReport.TYPE_ANR;
7755 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007756
Dan Egnorb7f03672009-12-09 16:22:32 -08007757 report.anrInfo.activity = r.notRespondingReport.tag;
7758 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7759 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007760 }
7761
Dan Egnorb7f03672009-12-09 16:22:32 -08007762 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007763 }
7764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007765 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7766 // assume our apps are happy - lazy create the list
7767 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7768
7769 synchronized (this) {
7770
7771 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007772 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7773 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007774 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7775 // This one's in trouble, so we'll generate a report for it
7776 // crashes are higher priority (in case there's a crash *and* an anr)
7777 ActivityManager.ProcessErrorStateInfo report = null;
7778 if (app.crashing) {
7779 report = app.crashingReport;
7780 } else if (app.notResponding) {
7781 report = app.notRespondingReport;
7782 }
7783
7784 if (report != null) {
7785 if (errList == null) {
7786 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7787 }
7788 errList.add(report);
7789 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007790 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007791 " crashing = " + app.crashing +
7792 " notResponding = " + app.notResponding);
7793 }
7794 }
7795 }
7796 }
7797
7798 return errList;
7799 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007800
7801 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007802 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007803 if (currApp != null) {
7804 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7805 }
7806 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007807 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7808 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007809 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7810 if (currApp != null) {
7811 currApp.lru = 0;
7812 }
7813 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007814 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007815 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7816 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7817 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7818 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7819 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7820 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7821 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7822 } else {
7823 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7824 }
7825 }
7826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007827 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7828 // Lazy instantiation of list
7829 List<ActivityManager.RunningAppProcessInfo> runList = null;
7830 synchronized (this) {
7831 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007832 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7833 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007834 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7835 // Generate process state info for running application
7836 ActivityManager.RunningAppProcessInfo currApp =
7837 new ActivityManager.RunningAppProcessInfo(app.processName,
7838 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007839 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007840 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007841 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007842 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007843 if (app.persistent) {
7844 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007846 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007847 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007848 currApp.importanceReasonCode = app.adjTypeCode;
7849 if (app.adjSource instanceof ProcessRecord) {
7850 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007851 currApp.importanceReasonImportance = oomAdjToImportance(
7852 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007853 } else if (app.adjSource instanceof ActivityRecord) {
7854 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007855 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7856 }
7857 if (app.adjTarget instanceof ComponentName) {
7858 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7859 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007860 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007861 // + " lru=" + currApp.lru);
7862 if (runList == null) {
7863 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7864 }
7865 runList.add(currApp);
7866 }
7867 }
7868 }
7869 return runList;
7870 }
7871
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007872 public List<ApplicationInfo> getRunningExternalApplications() {
7873 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7874 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7875 if (runningApps != null && runningApps.size() > 0) {
7876 Set<String> extList = new HashSet<String>();
7877 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7878 if (app.pkgList != null) {
7879 for (String pkg : app.pkgList) {
7880 extList.add(pkg);
7881 }
7882 }
7883 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007884 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007885 for (String pkg : extList) {
7886 try {
7887 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7888 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7889 retList.add(info);
7890 }
7891 } catch (RemoteException e) {
7892 }
7893 }
7894 }
7895 return retList;
7896 }
7897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007898 @Override
7899 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900 if (checkCallingPermission(android.Manifest.permission.DUMP)
7901 != PackageManager.PERMISSION_GRANTED) {
7902 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7903 + Binder.getCallingPid()
7904 + ", uid=" + Binder.getCallingUid()
7905 + " without permission "
7906 + android.Manifest.permission.DUMP);
7907 return;
7908 }
7909
7910 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007911 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007912 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007913
7914 int opti = 0;
7915 while (opti < args.length) {
7916 String opt = args[opti];
7917 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7918 break;
7919 }
7920 opti++;
7921 if ("-a".equals(opt)) {
7922 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007923 } else if ("-c".equals(opt)) {
7924 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007925 } else if ("-h".equals(opt)) {
7926 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007927 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007928 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007929 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007930 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
7931 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
7932 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007933 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007934 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7935 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007936 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007937 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007938 pw.println(" all: dump all activities");
7939 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007940 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007941 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7942 pw.println(" a partial substring in a component name, a");
7943 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007944 pw.println(" -a: include all available server state.");
7945 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007947 } else {
7948 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007949 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007950 }
7951
7952 // Is the caller requesting to dump a particular piece of data?
7953 if (opti < args.length) {
7954 String cmd = args[opti];
7955 opti++;
7956 if ("activities".equals(cmd) || "a".equals(cmd)) {
7957 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007958 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007959 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007960 return;
7961 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007962 String[] newArgs;
7963 String name;
7964 if (opti >= args.length) {
7965 name = null;
7966 newArgs = EMPTY_STRING_ARRAY;
7967 } else {
7968 name = args[opti];
7969 opti++;
7970 newArgs = new String[args.length - opti];
7971 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7972 args.length - opti);
7973 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007974 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007975 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007976 }
7977 return;
7978 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007979 String[] newArgs;
7980 String name;
7981 if (opti >= args.length) {
7982 name = null;
7983 newArgs = EMPTY_STRING_ARRAY;
7984 } else {
7985 name = args[opti];
7986 opti++;
7987 newArgs = new String[args.length - opti];
7988 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7989 args.length - opti);
7990 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007991 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007992 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007993 }
7994 return;
7995 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007996 String[] newArgs;
7997 String name;
7998 if (opti >= args.length) {
7999 name = null;
8000 newArgs = EMPTY_STRING_ARRAY;
8001 } else {
8002 name = args[opti];
8003 opti++;
8004 newArgs = new String[args.length - opti];
8005 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8006 args.length - opti);
8007 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008008 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008009 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008010 }
8011 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008012 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8013 synchronized (this) {
8014 dumpOomLocked(fd, pw, args, opti, true);
8015 }
8016 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008017 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8018 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008019 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008020 }
8021 return;
8022 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008023 String[] newArgs;
8024 String name;
8025 if (opti >= args.length) {
8026 name = null;
8027 newArgs = EMPTY_STRING_ARRAY;
8028 } else {
8029 name = args[opti];
8030 opti++;
8031 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008032 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8033 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008034 }
8035 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8036 pw.println("No services match: " + name);
8037 pw.println("Use -h for help.");
8038 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008039 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008040 } else if ("package".equals(cmd)) {
8041 String[] newArgs;
8042 if (opti >= args.length) {
8043 pw.println("package: no package name specified");
8044 pw.println("Use -h for help.");
8045 return;
8046 } else {
8047 dumpPackage = args[opti];
8048 opti++;
8049 newArgs = new String[args.length - opti];
8050 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8051 args.length - opti);
8052 args = newArgs;
8053 opti = 0;
8054 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008055 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8056 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008057 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008058 }
8059 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008060 } else {
8061 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008062 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8063 pw.println("Bad activity command, or no activities match: " + cmd);
8064 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008065 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008066 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008067 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008068 }
8069
8070 // No piece of data specified, dump everything.
8071 synchronized (this) {
8072 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008073 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008074 if (needSep) {
8075 pw.println(" ");
8076 }
8077 if (dumpAll) {
8078 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008079 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008080 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008081 if (needSep) {
8082 pw.println(" ");
8083 }
8084 if (dumpAll) {
8085 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008086 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008087 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008088 if (needSep) {
8089 pw.println(" ");
8090 }
8091 if (dumpAll) {
8092 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008093 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008094 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008095 if (needSep) {
8096 pw.println(" ");
8097 }
8098 if (dumpAll) {
8099 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008100 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008101 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008102 if (needSep) {
8103 pw.println(" ");
8104 }
8105 if (dumpAll) {
8106 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008107 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008108 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008109 }
8110 }
8111
8112 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008113 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008114 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8115 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008116 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8117 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008118 pw.println(" ");
8119 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008120 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8121 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008122 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008123 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008124 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008125 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008126 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008127 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008128 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008130 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008131 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008132 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008133 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008134 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8135 pw.println(" ");
8136 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008137 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008138 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008139 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008140 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008141 pw.println(" ");
8142 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008143 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008144 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008147 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008148 if (mMainStack.mPausingActivity != null) {
8149 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8150 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008151 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008152 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008153 if (dumpAll) {
8154 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8155 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008156 pw.println(" mDismissKeyguardOnNextActivity: "
8157 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008159
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008160 if (mRecentTasks.size() > 0) {
8161 pw.println();
8162 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008163
8164 final int N = mRecentTasks.size();
8165 for (int i=0; i<N; i++) {
8166 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008167 if (dumpPackage != null) {
8168 if (tr.realActivity == null ||
8169 !dumpPackage.equals(tr.realActivity)) {
8170 continue;
8171 }
8172 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008173 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8174 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008175 if (dumpAll) {
8176 mRecentTasks.get(i).dump(pw, " ");
8177 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008178 }
8179 }
8180
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008181 if (dumpAll) {
8182 pw.println(" ");
8183 pw.println(" mCurTask: " + mCurTask);
8184 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008185
8186 return true;
8187 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008188
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008189 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008190 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008191 boolean needSep = false;
8192 int numPers = 0;
8193
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008194 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8195
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008196 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008197 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8198 final int NA = procs.size();
8199 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008200 ProcessRecord r = procs.valueAt(ia);
8201 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8202 continue;
8203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008204 if (!needSep) {
8205 pw.println(" All known processes:");
8206 needSep = true;
8207 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008208 pw.print(r.persistent ? " *PERS*" : " *APP*");
8209 pw.print(" UID "); pw.print(procs.keyAt(ia));
8210 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008211 r.dump(pw, " ");
8212 if (r.persistent) {
8213 numPers++;
8214 }
8215 }
8216 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008217 }
8218
8219 if (mLruProcesses.size() > 0) {
8220 if (needSep) pw.println(" ");
8221 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008222 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008223 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008224 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008225 needSep = true;
8226 }
8227
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008228 if (dumpAll) {
8229 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008230 boolean printed = false;
8231 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8232 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8233 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8234 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008235 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008236 if (!printed) {
8237 if (needSep) pw.println(" ");
8238 needSep = true;
8239 pw.println(" PID mappings:");
8240 printed = true;
8241 }
8242 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8243 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008244 }
8245 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008246 }
8247
8248 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008249 synchronized (mPidsSelfLocked) {
8250 boolean printed = false;
8251 for (int i=0; i<mForegroundProcesses.size(); i++) {
8252 ProcessRecord r = mPidsSelfLocked.get(
8253 mForegroundProcesses.valueAt(i).pid);
8254 if (dumpPackage != null && (r == null
8255 || !dumpPackage.equals(r.info.packageName))) {
8256 continue;
8257 }
8258 if (!printed) {
8259 if (needSep) pw.println(" ");
8260 needSep = true;
8261 pw.println(" Foreground Processes:");
8262 printed = true;
8263 }
8264 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8265 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008267 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008268 }
8269
8270 if (mPersistentStartingProcesses.size() > 0) {
8271 if (needSep) pw.println(" ");
8272 needSep = true;
8273 pw.println(" Persisent processes that are starting:");
8274 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008275 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008277
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008278 if (mRemovedProcesses.size() > 0) {
8279 if (needSep) pw.println(" ");
8280 needSep = true;
8281 pw.println(" Processes that are being removed:");
8282 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008283 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008284 }
8285
8286 if (mProcessesOnHold.size() > 0) {
8287 if (needSep) pw.println(" ");
8288 needSep = true;
8289 pw.println(" Processes that are on old until the system is ready:");
8290 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008291 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008293
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008294 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008295
8296 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008297 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008298 long now = SystemClock.uptimeMillis();
8299 for (Map.Entry<String, SparseArray<Long>> procs
8300 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008301 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008302 SparseArray<Long> uids = procs.getValue();
8303 final int N = uids.size();
8304 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008305 int puid = uids.keyAt(i);
8306 ProcessRecord r = mProcessNames.get(pname, puid);
8307 if (dumpPackage != null && (r == null
8308 || !dumpPackage.equals(r.info.packageName))) {
8309 continue;
8310 }
8311 if (!printed) {
8312 if (needSep) pw.println(" ");
8313 needSep = true;
8314 pw.println(" Time since processes crashed:");
8315 printed = true;
8316 }
8317 pw.print(" Process "); pw.print(pname);
8318 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008319 pw.print(": last crashed ");
8320 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008321 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008322 }
8323 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008325
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008326 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008327 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008328 for (Map.Entry<String, SparseArray<Long>> procs
8329 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008330 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008331 SparseArray<Long> uids = procs.getValue();
8332 final int N = uids.size();
8333 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008334 int puid = uids.keyAt(i);
8335 ProcessRecord r = mProcessNames.get(pname, puid);
8336 if (dumpPackage != null && (r == null
8337 || !dumpPackage.equals(r.info.packageName))) {
8338 continue;
8339 }
8340 if (!printed) {
8341 if (needSep) pw.println(" ");
8342 needSep = true;
8343 pw.println(" Bad processes:");
8344 }
8345 pw.print(" Bad process "); pw.print(pname);
8346 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008347 pw.print(": crashed at time ");
8348 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008349 }
8350 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008352
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008353 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008354 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008355 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008356 if (mHeavyWeightProcess != null) {
8357 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8358 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008359 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008360 if (dumpAll) {
8361 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008362 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008363 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008364 for (Map.Entry<String, Integer> entry
8365 : mCompatModePackages.getPackages().entrySet()) {
8366 String pkg = entry.getKey();
8367 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008368 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8369 continue;
8370 }
8371 if (!printed) {
8372 pw.println(" mScreenCompatPackages:");
8373 printed = true;
8374 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008375 pw.print(" "); pw.print(pkg); pw.print(": ");
8376 pw.print(mode); pw.println();
8377 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008378 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008379 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008380 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8381 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8382 || mOrigWaitForDebugger) {
8383 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8384 + " mDebugTransient=" + mDebugTransient
8385 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8386 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008387 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8388 || mProfileFd != null) {
8389 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8390 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8391 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8392 + mAutoStopProfiler);
8393 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008394 if (mAlwaysFinishActivities || mController != null) {
8395 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8396 + " mController=" + mController);
8397 }
8398 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008399 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008400 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008401 + " mProcessesReady=" + mProcessesReady
8402 + " mSystemReady=" + mSystemReady);
8403 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008404 + " mBooted=" + mBooted
8405 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008406 pw.print(" mLastPowerCheckRealtime=");
8407 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8408 pw.println("");
8409 pw.print(" mLastPowerCheckUptime=");
8410 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8411 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008412 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8413 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008414 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008415 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8416 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008417 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008418
8419 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008420 }
8421
Dianne Hackborn287952c2010-09-22 22:34:31 -07008422 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008423 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008424 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008425 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008426 long now = SystemClock.uptimeMillis();
8427 for (int i=0; i<mProcessesToGc.size(); i++) {
8428 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008429 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8430 continue;
8431 }
8432 if (!printed) {
8433 if (needSep) pw.println(" ");
8434 needSep = true;
8435 pw.println(" Processes that are waiting to GC:");
8436 printed = true;
8437 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008438 pw.print(" Process "); pw.println(proc);
8439 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8440 pw.print(", last gced=");
8441 pw.print(now-proc.lastRequestedGc);
8442 pw.print(" ms ago, last lowMem=");
8443 pw.print(now-proc.lastLowMemory);
8444 pw.println(" ms ago");
8445
8446 }
8447 }
8448 return needSep;
8449 }
8450
8451 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8452 int opti, boolean dumpAll) {
8453 boolean needSep = false;
8454
8455 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008456 if (needSep) pw.println(" ");
8457 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008458 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008459 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008460 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008461 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8462 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8463 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8464 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8465 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008466 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008467 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008468 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008469 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008470 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008471 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008472
8473 if (needSep) pw.println(" ");
8474 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008475 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008476 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008477 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008478 needSep = true;
8479 }
8480
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008481 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008482
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008483 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008484 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008485 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008486 if (mHeavyWeightProcess != null) {
8487 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8488 }
8489
8490 return true;
8491 }
8492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008493 /**
8494 * There are three ways to call this:
8495 * - no service specified: dump all the services
8496 * - a flattened component name that matched an existing service was specified as the
8497 * first arg: dump that one service
8498 * - the first arg isn't the flattened component name of an existing service:
8499 * dump all services whose component contains the first arg as a substring
8500 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008501 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8502 int opti, boolean dumpAll) {
8503 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008505 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008506 synchronized (this) {
8507 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008508 services.add(r1);
8509 }
8510 }
8511 } else {
8512 ComponentName componentName = name != null
8513 ? ComponentName.unflattenFromString(name) : null;
8514 int objectId = 0;
8515 if (componentName == null) {
8516 // Not a '/' separated full component name; maybe an object ID?
8517 try {
8518 objectId = Integer.parseInt(name, 16);
8519 name = null;
8520 componentName = null;
8521 } catch (RuntimeException e) {
8522 }
8523 }
8524
8525 synchronized (this) {
8526 for (ServiceRecord r1 : mServices.values()) {
8527 if (componentName != null) {
8528 if (r1.name.equals(componentName)) {
8529 services.add(r1);
8530 }
8531 } else if (name != null) {
8532 if (r1.name.flattenToString().contains(name)) {
8533 services.add(r1);
8534 }
8535 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008536 services.add(r1);
8537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008538 }
8539 }
8540 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008541
8542 if (services.size() <= 0) {
8543 return false;
8544 }
8545
8546 boolean needSep = false;
8547 for (int i=0; i<services.size(); i++) {
8548 if (needSep) {
8549 pw.println();
8550 }
8551 needSep = true;
8552 dumpService("", fd, pw, services.get(i), args, dumpAll);
8553 }
8554 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 }
8556
8557 /**
8558 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8559 * there is a thread associated with the service.
8560 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008561 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8562 final ServiceRecord r, String[] args, boolean dumpAll) {
8563 String innerPrefix = prefix + " ";
8564 synchronized (this) {
8565 pw.print(prefix); pw.print("SERVICE ");
8566 pw.print(r.shortName); pw.print(" ");
8567 pw.print(Integer.toHexString(System.identityHashCode(r)));
8568 pw.print(" pid=");
8569 if (r.app != null) pw.println(r.app.pid);
8570 else pw.println("(not running)");
8571 if (dumpAll) {
8572 r.dump(pw, innerPrefix);
8573 }
8574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008576 pw.print(prefix); pw.println(" Client:");
8577 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008578 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008579 TransferPipe tp = new TransferPipe();
8580 try {
8581 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8582 tp.setBufferPrefix(prefix + " ");
8583 tp.go(fd);
8584 } finally {
8585 tp.kill();
8586 }
8587 } catch (IOException e) {
8588 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008590 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008591 }
8592 }
8593 }
8594
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008595 static class ItemMatcher {
8596 ArrayList<ComponentName> components;
8597 ArrayList<String> strings;
8598 ArrayList<Integer> objects;
8599 boolean all;
8600
8601 ItemMatcher() {
8602 all = true;
8603 }
8604
8605 void build(String name) {
8606 ComponentName componentName = ComponentName.unflattenFromString(name);
8607 if (componentName != null) {
8608 if (components == null) {
8609 components = new ArrayList<ComponentName>();
8610 }
8611 components.add(componentName);
8612 all = false;
8613 } else {
8614 int objectId = 0;
8615 // Not a '/' separated full component name; maybe an object ID?
8616 try {
8617 objectId = Integer.parseInt(name, 16);
8618 if (objects == null) {
8619 objects = new ArrayList<Integer>();
8620 }
8621 objects.add(objectId);
8622 all = false;
8623 } catch (RuntimeException e) {
8624 // Not an integer; just do string match.
8625 if (strings == null) {
8626 strings = new ArrayList<String>();
8627 }
8628 strings.add(name);
8629 all = false;
8630 }
8631 }
8632 }
8633
8634 int build(String[] args, int opti) {
8635 for (; opti<args.length; opti++) {
8636 String name = args[opti];
8637 if ("--".equals(name)) {
8638 return opti+1;
8639 }
8640 build(name);
8641 }
8642 return opti;
8643 }
8644
8645 boolean match(Object object, ComponentName comp) {
8646 if (all) {
8647 return true;
8648 }
8649 if (components != null) {
8650 for (int i=0; i<components.size(); i++) {
8651 if (components.get(i).equals(comp)) {
8652 return true;
8653 }
8654 }
8655 }
8656 if (objects != null) {
8657 for (int i=0; i<objects.size(); i++) {
8658 if (System.identityHashCode(object) == objects.get(i)) {
8659 return true;
8660 }
8661 }
8662 }
8663 if (strings != null) {
8664 String flat = comp.flattenToString();
8665 for (int i=0; i<strings.size(); i++) {
8666 if (flat.contains(strings.get(i))) {
8667 return true;
8668 }
8669 }
8670 }
8671 return false;
8672 }
8673 }
8674
Dianne Hackborn625ac272010-09-17 18:29:22 -07008675 /**
8676 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008677 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008678 * - the cmd arg isn't the flattened component name of an existing activity:
8679 * dump all activity whose component contains the cmd as a substring
8680 * - A hex number of the ActivityRecord object instance.
8681 */
8682 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8683 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008684 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008685
8686 if ("all".equals(name)) {
8687 synchronized (this) {
8688 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008689 activities.add(r1);
8690 }
8691 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008692 } else if ("top".equals(name)) {
8693 synchronized (this) {
8694 final int N = mMainStack.mHistory.size();
8695 if (N > 0) {
8696 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8697 }
8698 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008699 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008700 ItemMatcher matcher = new ItemMatcher();
8701 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008702
8703 synchronized (this) {
8704 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008705 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008706 activities.add(r1);
8707 }
8708 }
8709 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008710 }
8711
8712 if (activities.size() <= 0) {
8713 return false;
8714 }
8715
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008716 String[] newArgs = new String[args.length - opti];
8717 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8718
Dianne Hackborn30d71892010-12-11 10:37:55 -08008719 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008720 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008721 for (int i=activities.size()-1; i>=0; i--) {
8722 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008723 if (needSep) {
8724 pw.println();
8725 }
8726 needSep = true;
8727 synchronized (this) {
8728 if (lastTask != r.task) {
8729 lastTask = r.task;
8730 pw.print("TASK "); pw.print(lastTask.affinity);
8731 pw.print(" id="); pw.println(lastTask.taskId);
8732 if (dumpAll) {
8733 lastTask.dump(pw, " ");
8734 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008735 }
8736 }
8737 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008738 }
8739 return true;
8740 }
8741
8742 /**
8743 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8744 * there is a thread associated with the activity.
8745 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008746 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008747 final ActivityRecord r, String[] args, boolean dumpAll) {
8748 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008749 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008750 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8751 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8752 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008753 if (r.app != null) pw.println(r.app.pid);
8754 else pw.println("(not running)");
8755 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008756 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008757 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008758 }
8759 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008760 // flush anything that is already in the PrintWriter since the thread is going
8761 // to write to the file descriptor directly
8762 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008763 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008764 TransferPipe tp = new TransferPipe();
8765 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008766 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8767 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 tp.go(fd);
8769 } finally {
8770 tp.kill();
8771 }
8772 } catch (IOException e) {
8773 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008774 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008775 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008776 }
8777 }
8778 }
8779
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008780 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008781 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008782 boolean needSep = false;
8783
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008784 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008785 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008786 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008787 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008788 Iterator it = mRegisteredReceivers.values().iterator();
8789 while (it.hasNext()) {
8790 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008791 if (dumpPackage != null && (r.app == null ||
8792 !dumpPackage.equals(r.app.info.packageName))) {
8793 continue;
8794 }
8795 if (!printed) {
8796 pw.println(" Registered Receivers:");
8797 needSep = true;
8798 printed = true;
8799 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008800 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008801 r.dump(pw, " ");
8802 }
8803 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008804
8805 if (mReceiverResolver.dump(pw, needSep ?
8806 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
8807 " ", dumpPackage, false)) {
8808 needSep = true;
8809 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008810 }
8811
8812 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8813 || mPendingBroadcast != null) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008814 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008815 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008816 BroadcastRecord br = mParallelBroadcasts.get(i);
8817 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8818 continue;
8819 }
8820 if (!printed) {
8821 if (needSep) {
8822 pw.println();
8823 }
8824 needSep = true;
8825 pw.println(" Active broadcasts:");
8826 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008827 pw.println(" Broadcast #" + i + ":");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008828 br.dump(pw, " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008829 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008830 printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008831 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008832 BroadcastRecord br = mOrderedBroadcasts.get(i);
8833 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8834 continue;
8835 }
8836 if (!printed) {
8837 if (needSep) {
8838 pw.println();
8839 }
8840 needSep = true;
8841 pw.println(" Active ordered broadcasts:");
8842 }
8843 pw.println(" Ordered Broadcast #" + i + ":");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008844 mOrderedBroadcasts.get(i).dump(pw, " ");
8845 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008846 if (dumpPackage == null || (mPendingBroadcast != null
8847 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
8848 if (needSep) {
8849 pw.println();
8850 }
8851 pw.println(" Pending broadcast:");
8852 if (mPendingBroadcast != null) {
8853 mPendingBroadcast.dump(pw, " ");
8854 } else {
8855 pw.println(" (null)");
8856 }
8857 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008858 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008860
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008861 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008862 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8863 BroadcastRecord r = mBroadcastHistory[i];
8864 if (r == null) {
8865 break;
8866 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008867 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
8868 continue;
8869 }
8870 if (!printed) {
8871 if (needSep) {
8872 pw.println();
8873 }
8874 needSep = true;
8875 pw.println(" Historical broadcasts:");
8876 printed = true;
8877 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008878 if (dumpAll) {
8879 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8880 r.dump(pw, " ");
8881 } else {
8882 if (i >= 50) {
8883 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008884 break;
8885 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008886 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008887 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008888 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008889 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008890
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008891 if (mStickyBroadcasts != null && dumpPackage == null) {
8892 if (needSep) {
8893 pw.println();
8894 }
8895 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008896 pw.println(" Sticky broadcasts:");
8897 StringBuilder sb = new StringBuilder(128);
8898 for (Map.Entry<String, ArrayList<Intent>> ent
8899 : mStickyBroadcasts.entrySet()) {
8900 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008901 if (dumpAll) {
8902 pw.println(":");
8903 ArrayList<Intent> intents = ent.getValue();
8904 final int N = intents.size();
8905 for (int i=0; i<N; i++) {
8906 sb.setLength(0);
8907 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008908 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008909 pw.println(sb.toString());
8910 Bundle bundle = intents.get(i).getExtras();
8911 if (bundle != null) {
8912 pw.print(" ");
8913 pw.println(bundle.toString());
8914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008915 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008916 } else {
8917 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008918 }
8919 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008920 needSep = true;
8921 }
8922
8923 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008924 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008925 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008926 pw.println(" mHandler:");
8927 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008928 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008929 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008930
8931 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008932 }
8933
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008934 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008935 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008936 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008938 ItemMatcher matcher = new ItemMatcher();
8939 matcher.build(args, opti);
8940
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008941 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8942 if (mServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008943 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008944 long nowReal = SystemClock.elapsedRealtime();
8945 Iterator<ServiceRecord> it = mServices.values().iterator();
8946 needSep = false;
8947 while (it.hasNext()) {
8948 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008949 if (!matcher.match(r, r.name)) {
8950 continue;
8951 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008952 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
8953 continue;
8954 }
8955 if (!printed) {
8956 pw.println(" Active services:");
8957 printed = true;
8958 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008959 if (needSep) {
8960 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008961 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008962 pw.print(" * "); pw.println(r);
8963 if (dumpAll) {
8964 r.dump(pw, " ");
8965 needSep = true;
8966 } else {
8967 pw.print(" app="); pw.println(r.app);
8968 pw.print(" created=");
8969 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8970 pw.print(" started="); pw.print(r.startRequested);
8971 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08008972 if (r.connections.size() > 0) {
8973 pw.println(" Connections:");
8974 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
8975 for (int i=0; i<clist.size(); i++) {
8976 ConnectionRecord conn = clist.get(i);
8977 pw.print(" ");
8978 pw.print(conn.binding.intent.intent.getIntent().toShortString(
8979 false, false, false));
8980 pw.print(" -> ");
8981 ProcessRecord proc = conn.binding.client;
8982 pw.println(proc != null ? proc.toShortString() : "null");
8983 }
8984 }
8985 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008986 }
8987 if (dumpClient && r.app != null && r.app.thread != null) {
8988 pw.println(" Client:");
8989 pw.flush();
8990 try {
8991 TransferPipe tp = new TransferPipe();
8992 try {
8993 r.app.thread.dumpService(
8994 tp.getWriteFd().getFileDescriptor(), r, args);
8995 tp.setBufferPrefix(" ");
8996 // Short timeout, since blocking here can
8997 // deadlock with the application.
8998 tp.go(fd, 2000);
8999 } finally {
9000 tp.kill();
9001 }
9002 } catch (IOException e) {
9003 pw.println(" Failure while dumping the service: " + e);
9004 } catch (RemoteException e) {
9005 pw.println(" Got a RemoteException while dumping the service");
9006 }
9007 needSep = true;
9008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009010 needSep = printed;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009012
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009013 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009014 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009015 for (int i=0; i<mPendingServices.size(); i++) {
9016 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009017 if (!matcher.match(r, r.name)) {
9018 continue;
9019 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009020 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9021 continue;
9022 }
9023 if (!printed) {
9024 if (needSep) pw.println(" ");
9025 needSep = true;
9026 pw.println(" Pending services:");
9027 printed = true;
9028 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009029 pw.print(" * Pending "); pw.println(r);
9030 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009031 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009032 needSep = true;
9033 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009034
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009035 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009036 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009037 for (int i=0; i<mRestartingServices.size(); i++) {
9038 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009039 if (!matcher.match(r, r.name)) {
9040 continue;
9041 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009042 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9043 continue;
9044 }
9045 if (!printed) {
9046 if (needSep) pw.println(" ");
9047 needSep = true;
9048 pw.println(" Restarting services:");
9049 printed = true;
9050 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009051 pw.print(" * Restarting "); pw.println(r);
9052 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009053 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009054 needSep = true;
9055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009056
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009057 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009058 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009059 for (int i=0; i<mStoppingServices.size(); i++) {
9060 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009061 if (!matcher.match(r, r.name)) {
9062 continue;
9063 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009064 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9065 continue;
9066 }
9067 if (!printed) {
9068 if (needSep) pw.println(" ");
9069 needSep = true;
9070 pw.println(" Stopping services:");
9071 printed = true;
9072 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009073 pw.print(" * Stopping "); pw.println(r);
9074 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009075 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009076 needSep = true;
9077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009078
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009079 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009080 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009081 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009082 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009083 = mServiceConnections.values().iterator();
9084 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009085 ArrayList<ConnectionRecord> r = it.next();
9086 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009087 ConnectionRecord cr = r.get(i);
9088 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9089 continue;
9090 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009091 if (dumpPackage != null && (cr.binding.client == null
9092 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9093 continue;
9094 }
9095 if (!printed) {
9096 if (needSep) pw.println(" ");
9097 needSep = true;
9098 pw.println(" Connection bindings to services:");
9099 printed = true;
9100 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009101 pw.print(" * "); pw.println(cr);
9102 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009104 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009105 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009106 }
9107 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009108
9109 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009110 }
9111
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009112 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009113 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009114 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009115
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009116 ItemMatcher matcher = new ItemMatcher();
9117 matcher.build(args, opti);
9118
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009119 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9120 if (mProvidersByClass.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009121 boolean printed = false;
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009122 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009123 = mProvidersByClass.entrySet().iterator();
9124 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009125 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009126 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009127 ComponentName comp = e.getKey();
9128 String cls = comp.getClassName();
9129 int end = cls.lastIndexOf('.');
9130 if (end > 0 && end < (cls.length()-2)) {
9131 cls = cls.substring(end+1);
9132 }
9133 if (!matcher.match(r, comp)) {
9134 continue;
9135 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009136 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9137 continue;
9138 }
9139 if (!printed) {
9140 if (needSep) pw.println(" ");
9141 needSep = true;
9142 pw.println(" Published content providers (by class):");
9143 printed = true;
9144 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009145 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009146 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009147 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009148 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009149 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009150 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009151 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009152 } else {
9153 pw.println();
9154 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009155 if (r.clients.size() > 0) {
9156 pw.println(" Clients:");
9157 for (ProcessRecord cproc : r.clients) {
9158 pw.print(" - "); pw.println(cproc);
9159 }
9160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009161 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009162 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009163 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009164
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009165 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009166 if (mProvidersByName.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009167 boolean printed = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009168 Iterator<Map.Entry<String, ContentProviderRecord>> it
9169 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009170 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009171 Map.Entry<String, ContentProviderRecord> e = it.next();
9172 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009173 if (!matcher.match(r, r.name)) {
9174 continue;
9175 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009176 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9177 continue;
9178 }
9179 if (!printed) {
9180 if (needSep) pw.println(" ");
9181 needSep = true;
9182 pw.println(" Authority to provider mappings:");
9183 printed = true;
9184 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009185 pw.print(" "); pw.print(e.getKey()); pw.println(":");
9186 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009187 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009189 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009190
9191 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009192 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009193 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009194 ContentProviderRecord r = mLaunchingProviders.get(i);
9195 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9196 continue;
9197 }
9198 if (!printed) {
9199 if (needSep) pw.println(" ");
9200 needSep = true;
9201 pw.println(" Launching content providers:");
9202 printed = true;
9203 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009204 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009205 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009206 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009207 }
9208
9209 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009210 if (needSep) pw.println();
9211 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009212 pw.println("Granted Uri Permissions:");
9213 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9214 int uid = mGrantedUriPermissions.keyAt(i);
9215 HashMap<Uri, UriPermission> perms
9216 = mGrantedUriPermissions.valueAt(i);
9217 pw.print(" * UID "); pw.print(uid);
9218 pw.println(" holds:");
9219 for (UriPermission perm : perms.values()) {
9220 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009221 if (dumpAll) {
9222 perm.dump(pw, " ");
9223 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009224 }
9225 }
9226 needSep = true;
9227 }
9228
9229 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009230 }
9231
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009232 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009233 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009234 boolean needSep = false;
9235
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009236 if (mIntentSenderRecords.size() > 0) {
9237 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009238 Iterator<WeakReference<PendingIntentRecord>> it
9239 = mIntentSenderRecords.values().iterator();
9240 while (it.hasNext()) {
9241 WeakReference<PendingIntentRecord> ref = it.next();
9242 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009243 if (dumpPackage != null && (rec == null
9244 || !dumpPackage.equals(rec.key.packageName))) {
9245 continue;
9246 }
9247 if (!printed) {
9248 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9249 printed = true;
9250 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009251 needSep = true;
9252 if (rec != null) {
9253 pw.print(" * "); pw.println(rec);
9254 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009256 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009257 } else {
9258 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009259 }
9260 }
9261 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009262
9263 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009264 }
9265
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009266 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009267 String prefix, String label, boolean complete, boolean brief, boolean client,
9268 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009269 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009270 boolean needNL = false;
9271 final String innerPrefix = prefix + " ";
9272 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009273 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009274 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009275 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9276 continue;
9277 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009278 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009279 if (needNL) {
9280 pw.println(" ");
9281 needNL = false;
9282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283 if (lastTask != r.task) {
9284 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009285 pw.print(prefix);
9286 pw.print(full ? "* " : " ");
9287 pw.println(lastTask);
9288 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009289 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009290 } else if (complete) {
9291 // Complete + brief == give a summary. Isn't that obvious?!?
9292 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009293 pw.print(prefix); pw.print(" ");
9294 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009295 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009298 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9299 pw.print(" #"); pw.print(i); pw.print(": ");
9300 pw.println(r);
9301 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009302 r.dump(pw, innerPrefix);
9303 } else if (complete) {
9304 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009305 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009306 if (r.app != null) {
9307 pw.print(innerPrefix); pw.println(r.app);
9308 }
9309 }
9310 if (client && r.app != null && r.app.thread != null) {
9311 // flush anything that is already in the PrintWriter since the thread is going
9312 // to write to the file descriptor directly
9313 pw.flush();
9314 try {
9315 TransferPipe tp = new TransferPipe();
9316 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009317 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9318 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009319 // Short timeout, since blocking here can
9320 // deadlock with the application.
9321 tp.go(fd, 2000);
9322 } finally {
9323 tp.kill();
9324 }
9325 } catch (IOException e) {
9326 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9327 } catch (RemoteException e) {
9328 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9329 }
9330 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009332 }
9333 }
9334
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009335 private static String buildOomTag(String prefix, String space, int val, int base) {
9336 if (val == base) {
9337 if (space == null) return prefix;
9338 return prefix + " ";
9339 }
9340 return prefix + "+" + Integer.toString(val-base);
9341 }
9342
9343 private static final int dumpProcessList(PrintWriter pw,
9344 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009345 String prefix, String normalLabel, String persistentLabel,
9346 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009348 final int N = list.size()-1;
9349 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009350 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009351 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9352 continue;
9353 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009354 pw.println(String.format("%s%s #%2d: %s",
9355 prefix, (r.persistent ? persistentLabel : normalLabel),
9356 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 if (r.persistent) {
9358 numPers++;
9359 }
9360 }
9361 return numPers;
9362 }
9363
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009364 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009365 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009366 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009367 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009368
Dianne Hackborn905577f2011-09-07 18:31:28 -07009369 ArrayList<Pair<ProcessRecord, Integer>> list
9370 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9371 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009372 ProcessRecord r = origList.get(i);
9373 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9374 continue;
9375 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009376 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9377 }
9378
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009379 if (list.size() <= 0) {
9380 return false;
9381 }
9382
Dianne Hackborn905577f2011-09-07 18:31:28 -07009383 Comparator<Pair<ProcessRecord, Integer>> comparator
9384 = new Comparator<Pair<ProcessRecord, Integer>>() {
9385 @Override
9386 public int compare(Pair<ProcessRecord, Integer> object1,
9387 Pair<ProcessRecord, Integer> object2) {
9388 if (object1.first.setAdj != object2.first.setAdj) {
9389 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9390 }
9391 if (object1.second.intValue() != object2.second.intValue()) {
9392 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9393 }
9394 return 0;
9395 }
9396 };
9397
9398 Collections.sort(list, comparator);
9399
Dianne Hackborn287952c2010-09-22 22:34:31 -07009400 final long curRealtime = SystemClock.elapsedRealtime();
9401 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9402 final long curUptime = SystemClock.uptimeMillis();
9403 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9404
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009405 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009406 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009407 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009408 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009409 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009410 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9411 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009412 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9413 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009414 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9415 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009416 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9417 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009418 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9419 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9420 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9421 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9422 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9423 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9424 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9425 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9426 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9427 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009428 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9429 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009430 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9431 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009432 } else {
9433 oomAdj = Integer.toString(r.setAdj);
9434 }
9435 String schedGroup;
9436 switch (r.setSchedGroup) {
9437 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9438 schedGroup = "B";
9439 break;
9440 case Process.THREAD_GROUP_DEFAULT:
9441 schedGroup = "F";
9442 break;
9443 default:
9444 schedGroup = Integer.toString(r.setSchedGroup);
9445 break;
9446 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009447 String foreground;
9448 if (r.foregroundActivities) {
9449 foreground = "A";
9450 } else if (r.foregroundServices) {
9451 foreground = "S";
9452 } else {
9453 foreground = " ";
9454 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009455 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009456 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009457 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9458 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009459 if (r.adjSource != null || r.adjTarget != null) {
9460 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009461 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009462 if (r.adjTarget instanceof ComponentName) {
9463 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9464 } else if (r.adjTarget != null) {
9465 pw.print(r.adjTarget.toString());
9466 } else {
9467 pw.print("{null}");
9468 }
9469 pw.print("<=");
9470 if (r.adjSource instanceof ProcessRecord) {
9471 pw.print("Proc{");
9472 pw.print(((ProcessRecord)r.adjSource).toShortString());
9473 pw.println("}");
9474 } else if (r.adjSource != null) {
9475 pw.println(r.adjSource.toString());
9476 } else {
9477 pw.println("{null}");
9478 }
9479 }
9480 if (inclDetails) {
9481 pw.print(prefix);
9482 pw.print(" ");
9483 pw.print("oom: max="); pw.print(r.maxAdj);
9484 pw.print(" hidden="); pw.print(r.hiddenAdj);
9485 pw.print(" curRaw="); pw.print(r.curRawAdj);
9486 pw.print(" setRaw="); pw.print(r.setRawAdj);
9487 pw.print(" cur="); pw.print(r.curAdj);
9488 pw.print(" set="); pw.println(r.setAdj);
9489 pw.print(prefix);
9490 pw.print(" ");
9491 pw.print("keeping="); pw.print(r.keeping);
9492 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009493 pw.print(" empty="); pw.print(r.empty);
9494 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009495
9496 if (!r.keeping) {
9497 if (r.lastWakeTime != 0) {
9498 long wtime;
9499 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9500 synchronized (stats) {
9501 wtime = stats.getProcessWakeTime(r.info.uid,
9502 r.pid, curRealtime);
9503 }
9504 long timeUsed = wtime - r.lastWakeTime;
9505 pw.print(prefix);
9506 pw.print(" ");
9507 pw.print("keep awake over ");
9508 TimeUtils.formatDuration(realtimeSince, pw);
9509 pw.print(" used ");
9510 TimeUtils.formatDuration(timeUsed, pw);
9511 pw.print(" (");
9512 pw.print((timeUsed*100)/realtimeSince);
9513 pw.println("%)");
9514 }
9515 if (r.lastCpuTime != 0) {
9516 long timeUsed = r.curCpuTime - r.lastCpuTime;
9517 pw.print(prefix);
9518 pw.print(" ");
9519 pw.print("run cpu over ");
9520 TimeUtils.formatDuration(uptimeSince, pw);
9521 pw.print(" used ");
9522 TimeUtils.formatDuration(timeUsed, pw);
9523 pw.print(" (");
9524 pw.print((timeUsed*100)/uptimeSince);
9525 pw.println("%)");
9526 }
9527 }
9528 }
9529 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009530 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009531 }
9532
Dianne Hackbornb437e092011-08-05 17:50:29 -07009533 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009534 ArrayList<ProcessRecord> procs;
9535 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009536 if (args != null && args.length > start
9537 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009538 procs = new ArrayList<ProcessRecord>();
9539 int pid = -1;
9540 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009541 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009542 } catch (NumberFormatException e) {
9543
9544 }
9545 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9546 ProcessRecord proc = mLruProcesses.get(i);
9547 if (proc.pid == pid) {
9548 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009549 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009550 procs.add(proc);
9551 }
9552 }
9553 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009554 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009555 return null;
9556 }
9557 } else {
9558 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9559 }
9560 }
9561 return procs;
9562 }
9563
9564 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9565 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009566 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009567 if (procs == null) {
9568 return;
9569 }
9570
9571 long uptime = SystemClock.uptimeMillis();
9572 long realtime = SystemClock.elapsedRealtime();
9573 pw.println("Applications Graphics Acceleration Info:");
9574 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9575
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009576 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9577 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009578 if (r.thread != null) {
9579 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9580 pw.flush();
9581 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009582 TransferPipe tp = new TransferPipe();
9583 try {
9584 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9585 tp.go(fd);
9586 } finally {
9587 tp.kill();
9588 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009589 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009590 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009591 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009592 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009593 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009594 pw.flush();
9595 }
9596 }
9597 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009598 }
9599
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009600 final static class MemItem {
9601 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009602 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009603 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009604 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009605 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009606
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009607 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009608 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009609 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009610 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009611 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009612 }
9613 }
9614
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009615 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009616 boolean sort) {
9617 if (sort) {
9618 Collections.sort(items, new Comparator<MemItem>() {
9619 @Override
9620 public int compare(MemItem lhs, MemItem rhs) {
9621 if (lhs.pss < rhs.pss) {
9622 return 1;
9623 } else if (lhs.pss > rhs.pss) {
9624 return -1;
9625 }
9626 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009627 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009628 });
9629 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009630
9631 for (int i=0; i<items.size(); i++) {
9632 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009633 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009634 if (mi.subitems != null) {
9635 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9636 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009637 }
9638 }
9639
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009640 // These are in KB.
9641 static final long[] DUMP_MEM_BUCKETS = new long[] {
9642 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9643 120*1024, 160*1024, 200*1024,
9644 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9645 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9646 };
9647
9648 static final void appendMemBucket(StringBuilder out, long memKB, String label) {
9649 int start = label.lastIndexOf('.');
9650 if (start >= 0) start++;
9651 else start = 0;
9652 int end = label.length();
9653 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9654 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9655 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9656 out.append(bucket);
9657 out.append("MB ");
9658 out.append(label, start, end);
9659 return;
9660 }
9661 }
9662 out.append(memKB/1024);
9663 out.append("MB ");
9664 out.append(label, start, end);
9665 }
9666
9667 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9668 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9669 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9670 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9671 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9672 };
9673 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9674 "System", "Persistent", "Foreground",
9675 "Visible", "Perceptible", "Heavy Weight",
9676 "Backup", "A Services", "Home", "Previous",
9677 "B Services", "Background"
9678 };
9679
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009680 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009681 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009682 PrintWriter categoryPw, StringBuilder outTag) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009683 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009684 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009685
9686 int opti = 0;
9687 while (opti < args.length) {
9688 String opt = args[opti];
9689 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9690 break;
9691 }
9692 opti++;
9693 if ("-a".equals(opt)) {
9694 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009695 } else if ("--oom".equals(opt)) {
9696 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009697 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009698 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009699 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009700 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009701 pw.println("If [process] is specified it can be the name or ");
9702 pw.println("pid of a specific process to dump.");
9703 return;
9704 } else {
9705 pw.println("Unknown argument: " + opt + "; use -h for help");
9706 }
9707 }
9708
9709 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009710 if (procs == null) {
9711 return;
9712 }
9713
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009714 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009715 long uptime = SystemClock.uptimeMillis();
9716 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009717
9718 if (procs.size() == 1 || isCheckinRequest) {
9719 dumpAll = true;
9720 }
9721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009722 if (isCheckinRequest) {
9723 // short checkin version
9724 pw.println(uptime + "," + realtime);
9725 pw.flush();
9726 } else {
9727 pw.println("Applications Memory Usage (kB):");
9728 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9729 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009730
Dianne Hackbornb437e092011-08-05 17:50:29 -07009731 String[] innerArgs = new String[args.length-opti];
9732 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9733
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009734 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9735 long nativePss=0, dalvikPss=0, otherPss=0;
9736 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9737
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009738 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9739 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9740 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009741
9742 long totalPss = 0;
9743
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009744 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9745 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009747 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9749 pw.flush();
9750 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009751 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009752 if (dumpAll) {
9753 try {
9754 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9755 } catch (RemoteException e) {
9756 if (!isCheckinRequest) {
9757 pw.println("Got RemoteException!");
9758 pw.flush();
9759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009760 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009761 } else {
9762 mi = new Debug.MemoryInfo();
9763 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009765
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009766 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009767 long myTotalPss = mi.getTotalPss();
9768 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009769 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009770 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009771 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009772
9773 nativePss += mi.nativePss;
9774 dalvikPss += mi.dalvikPss;
9775 otherPss += mi.otherPss;
9776 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9777 long mem = mi.getOtherPss(j);
9778 miscPss[j] += mem;
9779 otherPss -= mem;
9780 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009781
9782 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009783 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9784 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009785 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009786 if (oomProcs[oomIndex] == null) {
9787 oomProcs[oomIndex] = new ArrayList<MemItem>();
9788 }
9789 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009790 break;
9791 }
9792 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009794 }
9795 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009796
9797 if (!isCheckinRequest && procs.size() > 1) {
9798 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9799
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009800 catMems.add(new MemItem("Native", "Native", nativePss, -1));
9801 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9802 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009803 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009804 String label = Debug.MemoryInfo.getOtherLabel(j);
9805 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009806 }
9807
Dianne Hackbornb437e092011-08-05 17:50:29 -07009808 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9809 for (int j=0; j<oomPss.length; j++) {
9810 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009811 String label = DUMP_MEM_OOM_LABEL[j];
9812 MemItem item = new MemItem(label, label, oomPss[j],
9813 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009814 item.subitems = oomProcs[j];
9815 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009816 }
9817 }
9818
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009819 if (outTag != null) {
9820 appendMemBucket(outTag, totalPss, "total");
9821 for (int i=0; i<oomMems.size(); i++) {
9822 MemItem miCat = oomMems.get(i);
9823 if (miCat.subitems == null || miCat.subitems.size() < 1) {
9824 continue;
9825 }
9826 if (miCat.id < ProcessList.SERVICE_ADJ
9827 || miCat.id == ProcessList.HOME_APP_ADJ
9828 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
9829 outTag.append(" / ");
9830 for (int j=0; j<miCat.subitems.size(); j++) {
9831 MemItem mi = miCat.subitems.get(j);
9832 if (j > 0) {
9833 outTag.append(" ");
9834 }
9835 appendMemBucket(outTag, mi.pss, mi.shortLabel);
9836 }
9837 }
9838 }
9839 }
9840
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009841 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009842 pw.println();
9843 pw.println("Total PSS by process:");
9844 dumpMemItems(pw, " ", procMems, true);
9845 pw.println();
9846 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009847 pw.println("Total PSS by OOM adjustment:");
9848 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009849 if (!oomOnly) {
9850 PrintWriter out = categoryPw != null ? categoryPw : pw;
9851 out.println();
9852 out.println("Total PSS by category:");
9853 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009854 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009855 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009856 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 }
9859
9860 /**
9861 * Searches array of arguments for the specified string
9862 * @param args array of argument strings
9863 * @param value value to search for
9864 * @return true if the value is contained in the array
9865 */
9866 private static boolean scanArgs(String[] args, String value) {
9867 if (args != null) {
9868 for (String arg : args) {
9869 if (value.equals(arg)) {
9870 return true;
9871 }
9872 }
9873 }
9874 return false;
9875 }
9876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009877 private final void killServicesLocked(ProcessRecord app,
9878 boolean allowRestart) {
9879 // Report disconnected services.
9880 if (false) {
9881 // XXX we are letting the client link to the service for
9882 // death notifications.
9883 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009884 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009885 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009886 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009888 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009889 = r.connections.values().iterator();
9890 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009891 ArrayList<ConnectionRecord> cl = jt.next();
9892 for (int i=0; i<cl.size(); i++) {
9893 ConnectionRecord c = cl.get(i);
9894 if (c.binding.client != app) {
9895 try {
9896 //c.conn.connected(r.className, null);
9897 } catch (Exception e) {
9898 // todo: this should be asynchronous!
9899 Slog.w(TAG, "Exception thrown disconnected servce "
9900 + r.shortName
9901 + " from app " + app.processName, e);
9902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009903 }
9904 }
9905 }
9906 }
9907 }
9908 }
9909 }
9910
9911 // Clean up any connections this application has to other services.
9912 if (app.connections.size() > 0) {
9913 Iterator<ConnectionRecord> it = app.connections.iterator();
9914 while (it.hasNext()) {
9915 ConnectionRecord r = it.next();
9916 removeConnectionLocked(r, app, null);
9917 }
9918 }
9919 app.connections.clear();
9920
9921 if (app.services.size() != 0) {
9922 // Any services running in the application need to be placed
9923 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009924 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009926 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 synchronized (sr.stats.getBatteryStats()) {
9928 sr.stats.stopLaunchedLocked();
9929 }
9930 sr.app = null;
9931 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009932 if (mStoppingServices.remove(sr)) {
9933 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9934 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009935
9936 boolean hasClients = sr.bindings.size() > 0;
9937 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938 Iterator<IntentBindRecord> bindings
9939 = sr.bindings.values().iterator();
9940 while (bindings.hasNext()) {
9941 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009942 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009943 + ": shouldUnbind=" + b.hasBound);
9944 b.binder = null;
9945 b.requested = b.received = b.hasBound = false;
9946 }
9947 }
9948
Dianne Hackborn070783f2010-12-29 16:46:28 -08009949 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9950 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009951 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009953 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009954 sr.crashCount, sr.shortName, app.pid);
9955 bringDownServiceLocked(sr, true);
9956 } else if (!allowRestart) {
9957 bringDownServiceLocked(sr, true);
9958 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009959 boolean canceled = scheduleServiceRestartLocked(sr, true);
9960
9961 // Should the service remain running? Note that in the
9962 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009963 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009964 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9965 if (sr.pendingStarts.size() == 0) {
9966 sr.startRequested = false;
9967 if (!hasClients) {
9968 // Whoops, no reason to restart!
9969 bringDownServiceLocked(sr, true);
9970 }
9971 }
9972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009973 }
9974 }
9975
9976 if (!allowRestart) {
9977 app.services.clear();
9978 }
9979 }
9980
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009981 // Make sure we have no more records on the stopping list.
9982 int i = mStoppingServices.size();
9983 while (i > 0) {
9984 i--;
9985 ServiceRecord sr = mStoppingServices.get(i);
9986 if (sr.app == app) {
9987 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009988 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009989 }
9990 }
9991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 app.executingServices.clear();
9993 }
9994
9995 private final void removeDyingProviderLocked(ProcessRecord proc,
9996 ContentProviderRecord cpr) {
9997 synchronized (cpr) {
9998 cpr.launchingApp = null;
9999 cpr.notifyAll();
10000 }
10001
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010002 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 String names[] = cpr.info.authority.split(";");
10004 for (int j = 0; j < names.length; j++) {
10005 mProvidersByName.remove(names[j]);
10006 }
10007
10008 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10009 while (cit.hasNext()) {
10010 ProcessRecord capp = cit.next();
10011 if (!capp.persistent && capp.thread != null
10012 && capp.pid != 0
10013 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010014 Slog.i(TAG, "Kill " + capp.processName
10015 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010016 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010017 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010018 capp.processName, capp.setAdj, "dying provider "
10019 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010020 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010021 }
10022 }
10023
10024 mLaunchingProviders.remove(cpr);
10025 }
10026
10027 /**
10028 * Main code for cleaning up a process when it has gone away. This is
10029 * called both as a result of the process dying, or directly when stopping
10030 * a process when running in single process mode.
10031 */
10032 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010033 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010034 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010035 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010036 }
10037
Dianne Hackborn36124872009-10-08 16:22:03 -070010038 mProcessesToGc.remove(app);
10039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010040 // Dismiss any open dialogs.
10041 if (app.crashDialog != null) {
10042 app.crashDialog.dismiss();
10043 app.crashDialog = null;
10044 }
10045 if (app.anrDialog != null) {
10046 app.anrDialog.dismiss();
10047 app.anrDialog = null;
10048 }
10049 if (app.waitDialog != null) {
10050 app.waitDialog.dismiss();
10051 app.waitDialog = null;
10052 }
10053
10054 app.crashing = false;
10055 app.notResponding = false;
10056
10057 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010058 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010059 app.thread = null;
10060 app.forcingToForeground = null;
10061 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010062 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010063 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010064 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010066 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067
10068 boolean restart = false;
10069
10070 int NL = mLaunchingProviders.size();
10071
10072 // Remove published content providers.
10073 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010074 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010075 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010076 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010078 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079
10080 // See if someone is waiting for this provider... in which
10081 // case we don't remove it, but just let it restart.
10082 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010083 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 for (; i<NL; i++) {
10085 if (mLaunchingProviders.get(i) == cpr) {
10086 restart = true;
10087 break;
10088 }
10089 }
10090 } else {
10091 i = NL;
10092 }
10093
10094 if (i >= NL) {
10095 removeDyingProviderLocked(app, cpr);
10096 NL = mLaunchingProviders.size();
10097 }
10098 }
10099 app.pubProviders.clear();
10100 }
10101
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010102 // Take care of any launching providers waiting for this process.
10103 if (checkAppInLaunchingProvidersLocked(app, false)) {
10104 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 // Unregister from connected content providers.
10108 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070010109 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010110 while (it.hasNext()) {
10111 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10112 cpr.clients.remove(app);
10113 }
10114 app.conProviders.clear();
10115 }
10116
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010117 // At this point there may be remaining entries in mLaunchingProviders
10118 // where we were the only one waiting, so they are no longer of use.
10119 // Look for these and clean up if found.
10120 // XXX Commented out for now. Trying to figure out a way to reproduce
10121 // the actual situation to identify what is actually going on.
10122 if (false) {
10123 for (int i=0; i<NL; i++) {
10124 ContentProviderRecord cpr = (ContentProviderRecord)
10125 mLaunchingProviders.get(i);
10126 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10127 synchronized (cpr) {
10128 cpr.launchingApp = null;
10129 cpr.notifyAll();
10130 }
10131 }
10132 }
10133 }
10134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 skipCurrentReceiverLocked(app);
10136
10137 // Unregister any receivers.
10138 if (app.receivers.size() > 0) {
10139 Iterator<ReceiverList> it = app.receivers.iterator();
10140 while (it.hasNext()) {
10141 removeReceiverLocked(it.next());
10142 }
10143 app.receivers.clear();
10144 }
10145
Christopher Tate181fafa2009-05-14 11:12:14 -070010146 // If the app is undergoing backup, tell the backup manager about it
10147 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010148 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010149 try {
10150 IBackupManager bm = IBackupManager.Stub.asInterface(
10151 ServiceManager.getService(Context.BACKUP_SERVICE));
10152 bm.agentDisconnected(app.info.packageName);
10153 } catch (RemoteException e) {
10154 // can't happen; backup manager is local
10155 }
10156 }
10157
Jeff Sharkey287bd832011-05-28 19:36:26 -070010158 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010160 // If the caller is restarting this app, then leave it in its
10161 // current lists and let the caller take care of it.
10162 if (restarting) {
10163 return;
10164 }
10165
10166 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010167 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010168 "Removing non-persistent process during cleanup: " + app);
10169 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010170 if (mHeavyWeightProcess == app) {
10171 mHeavyWeightProcess = null;
10172 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010174 } else if (!app.removed) {
10175 // This app is persistent, so we need to keep its record around.
10176 // If it is not already on the pending app list, add it there
10177 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010178 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10179 mPersistentStartingProcesses.add(app);
10180 restart = true;
10181 }
10182 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010183 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10184 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 mProcessesOnHold.remove(app);
10186
The Android Open Source Project4df24232009-03-05 14:34:35 -080010187 if (app == mHomeProcess) {
10188 mHomeProcess = null;
10189 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010190 if (app == mPreviousProcess) {
10191 mPreviousProcess = null;
10192 }
10193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010194 if (restart) {
10195 // We have components that still need to be running in the
10196 // process, so re-launch it.
10197 mProcessNames.put(app.processName, app.info.uid, app);
10198 startProcessLocked(app, "restart", app.processName);
10199 } else if (app.pid > 0 && app.pid != MY_PID) {
10200 // Goodbye!
10201 synchronized (mPidsSelfLocked) {
10202 mPidsSelfLocked.remove(app.pid);
10203 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10204 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010205 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206 }
10207 }
10208
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010209 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10210 // Look through the content providers we are waiting to have launched,
10211 // and if any run in this process then either schedule a restart of
10212 // the process or kill the client waiting for it if this process has
10213 // gone bad.
10214 int NL = mLaunchingProviders.size();
10215 boolean restart = false;
10216 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010217 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010218 if (cpr.launchingApp == app) {
10219 if (!alwaysBad && !app.bad) {
10220 restart = true;
10221 } else {
10222 removeDyingProviderLocked(app, cpr);
10223 NL = mLaunchingProviders.size();
10224 }
10225 }
10226 }
10227 return restart;
10228 }
10229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010230 // =========================================================
10231 // SERVICES
10232 // =========================================================
10233
10234 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10235 ActivityManager.RunningServiceInfo info =
10236 new ActivityManager.RunningServiceInfo();
10237 info.service = r.name;
10238 if (r.app != null) {
10239 info.pid = r.app.pid;
10240 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010241 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 info.process = r.processName;
10243 info.foreground = r.isForeground;
10244 info.activeSince = r.createTime;
10245 info.started = r.startRequested;
10246 info.clientCount = r.connections.size();
10247 info.crashCount = r.crashCount;
10248 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010249 if (r.isForeground) {
10250 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10251 }
10252 if (r.startRequested) {
10253 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10254 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010255 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010256 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10257 }
10258 if (r.app != null && r.app.persistent) {
10259 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10260 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010261
10262 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10263 for (int i=0; i<connl.size(); i++) {
10264 ConnectionRecord conn = connl.get(i);
10265 if (conn.clientLabel != 0) {
10266 info.clientPackage = conn.binding.client.info.packageName;
10267 info.clientLabel = conn.clientLabel;
10268 return info;
10269 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010270 }
10271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010272 return info;
10273 }
10274
10275 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10276 int flags) {
10277 synchronized (this) {
10278 ArrayList<ActivityManager.RunningServiceInfo> res
10279 = new ArrayList<ActivityManager.RunningServiceInfo>();
10280
10281 if (mServices.size() > 0) {
10282 Iterator<ServiceRecord> it = mServices.values().iterator();
10283 while (it.hasNext() && res.size() < maxNum) {
10284 res.add(makeRunningServiceInfoLocked(it.next()));
10285 }
10286 }
10287
10288 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10289 ServiceRecord r = mRestartingServices.get(i);
10290 ActivityManager.RunningServiceInfo info =
10291 makeRunningServiceInfoLocked(r);
10292 info.restarting = r.nextRestartTime;
10293 res.add(info);
10294 }
10295
10296 return res;
10297 }
10298 }
10299
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010300 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10301 synchronized (this) {
10302 ServiceRecord r = mServices.get(name);
10303 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010304 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10305 for (int i=0; i<conn.size(); i++) {
10306 if (conn.get(i).clientIntent != null) {
10307 return conn.get(i).clientIntent;
10308 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010309 }
10310 }
10311 }
10312 }
10313 return null;
10314 }
10315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010316 private final ServiceRecord findServiceLocked(ComponentName name,
10317 IBinder token) {
10318 ServiceRecord r = mServices.get(name);
10319 return r == token ? r : null;
10320 }
10321
10322 private final class ServiceLookupResult {
10323 final ServiceRecord record;
10324 final String permission;
10325
10326 ServiceLookupResult(ServiceRecord _record, String _permission) {
10327 record = _record;
10328 permission = _permission;
10329 }
10330 };
10331
10332 private ServiceLookupResult findServiceLocked(Intent service,
10333 String resolvedType) {
10334 ServiceRecord r = null;
10335 if (service.getComponent() != null) {
10336 r = mServices.get(service.getComponent());
10337 }
10338 if (r == null) {
10339 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10340 r = mServicesByIntent.get(filter);
10341 }
10342
10343 if (r == null) {
10344 try {
10345 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010346 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010347 service, resolvedType, 0);
10348 ServiceInfo sInfo =
10349 rInfo != null ? rInfo.serviceInfo : null;
10350 if (sInfo == null) {
10351 return null;
10352 }
10353
10354 ComponentName name = new ComponentName(
10355 sInfo.applicationInfo.packageName, sInfo.name);
10356 r = mServices.get(name);
10357 } catch (RemoteException ex) {
10358 // pm is in same process, this will never happen.
10359 }
10360 }
10361 if (r != null) {
10362 int callingPid = Binder.getCallingPid();
10363 int callingUid = Binder.getCallingUid();
10364 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010365 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010366 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010367 if (!r.exported) {
10368 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10369 + " from pid=" + callingPid
10370 + ", uid=" + callingUid
10371 + " that is not exported from uid " + r.appInfo.uid);
10372 return new ServiceLookupResult(null, "not exported from uid "
10373 + r.appInfo.uid);
10374 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010375 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010376 + " from pid=" + callingPid
10377 + ", uid=" + callingUid
10378 + " requires " + r.permission);
10379 return new ServiceLookupResult(null, r.permission);
10380 }
10381 return new ServiceLookupResult(r, null);
10382 }
10383 return null;
10384 }
10385
10386 private class ServiceRestarter implements Runnable {
10387 private ServiceRecord mService;
10388
10389 void setService(ServiceRecord service) {
10390 mService = service;
10391 }
10392
10393 public void run() {
10394 synchronized(ActivityManagerService.this) {
10395 performServiceRestartLocked(mService);
10396 }
10397 }
10398 }
10399
10400 private ServiceLookupResult retrieveServiceLocked(Intent service,
10401 String resolvedType, int callingPid, int callingUid) {
10402 ServiceRecord r = null;
10403 if (service.getComponent() != null) {
10404 r = mServices.get(service.getComponent());
10405 }
10406 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10407 r = mServicesByIntent.get(filter);
10408 if (r == null) {
10409 try {
10410 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010411 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010412 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010413 ServiceInfo sInfo =
10414 rInfo != null ? rInfo.serviceInfo : null;
10415 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010416 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010417 ": not found");
10418 return null;
10419 }
10420
10421 ComponentName name = new ComponentName(
10422 sInfo.applicationInfo.packageName, sInfo.name);
10423 r = mServices.get(name);
10424 if (r == null) {
10425 filter = new Intent.FilterComparison(service.cloneFilter());
10426 ServiceRestarter res = new ServiceRestarter();
10427 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10428 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10429 synchronized (stats) {
10430 ss = stats.getServiceStatsLocked(
10431 sInfo.applicationInfo.uid, sInfo.packageName,
10432 sInfo.name);
10433 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010434 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010435 res.setService(r);
10436 mServices.put(name, r);
10437 mServicesByIntent.put(filter, r);
10438
10439 // Make sure this component isn't in the pending list.
10440 int N = mPendingServices.size();
10441 for (int i=0; i<N; i++) {
10442 ServiceRecord pr = mPendingServices.get(i);
10443 if (pr.name.equals(name)) {
10444 mPendingServices.remove(i);
10445 i--;
10446 N--;
10447 }
10448 }
10449 }
10450 } catch (RemoteException ex) {
10451 // pm is in same process, this will never happen.
10452 }
10453 }
10454 if (r != null) {
10455 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010456 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010458 if (!r.exported) {
10459 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10460 + " from pid=" + callingPid
10461 + ", uid=" + callingUid
10462 + " that is not exported from uid " + r.appInfo.uid);
10463 return new ServiceLookupResult(null, "not exported from uid "
10464 + r.appInfo.uid);
10465 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010466 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010467 + " from pid=" + callingPid
10468 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 + " requires " + r.permission);
10470 return new ServiceLookupResult(null, r.permission);
10471 }
10472 return new ServiceLookupResult(r, null);
10473 }
10474 return null;
10475 }
10476
Dianne Hackborn287952c2010-09-22 22:34:31 -070010477 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10478 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10479 + why + " of " + r + " in app " + r.app);
10480 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10481 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010482 long now = SystemClock.uptimeMillis();
10483 if (r.executeNesting == 0 && r.app != null) {
10484 if (r.app.executingServices.size() == 0) {
10485 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10486 msg.obj = r.app;
10487 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10488 }
10489 r.app.executingServices.add(r);
10490 }
10491 r.executeNesting++;
10492 r.executingStart = now;
10493 }
10494
10495 private final void sendServiceArgsLocked(ServiceRecord r,
10496 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010497 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010498 if (N == 0) {
10499 return;
10500 }
10501
Dianne Hackborn39792d22010-08-19 18:01:52 -070010502 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010503 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010504 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010505 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10506 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010507 if (si.intent == null && N > 1) {
10508 // If somehow we got a dummy null intent in the middle,
10509 // then skip it. DO NOT skip a null intent when it is
10510 // the only one in the list -- this is to support the
10511 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010512 continue;
10513 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010514 si.deliveredTime = SystemClock.uptimeMillis();
10515 r.deliveredStarts.add(si);
10516 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010517 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010518 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010519 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010520 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010521 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010522 if (!oomAdjusted) {
10523 oomAdjusted = true;
10524 updateOomAdjLocked(r.app);
10525 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010526 int flags = 0;
10527 if (si.deliveryCount > 0) {
10528 flags |= Service.START_FLAG_RETRY;
10529 }
10530 if (si.doneExecutingCount > 0) {
10531 flags |= Service.START_FLAG_REDELIVERY;
10532 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010533 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010534 } catch (RemoteException e) {
10535 // Remote process gone... we'll let the normal cleanup take
10536 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010537 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010538 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010539 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010540 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010541 break;
10542 }
10543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010544 }
10545
10546 private final boolean requestServiceBindingLocked(ServiceRecord r,
10547 IntentBindRecord i, boolean rebind) {
10548 if (r.app == null || r.app.thread == null) {
10549 // If service is not currently running, can't yet bind.
10550 return false;
10551 }
10552 if ((!i.requested || rebind) && i.apps.size() > 0) {
10553 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010554 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10556 if (!rebind) {
10557 i.requested = true;
10558 }
10559 i.hasBound = true;
10560 i.doRebind = false;
10561 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010562 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010563 return false;
10564 }
10565 }
10566 return true;
10567 }
10568
10569 private final void requestServiceBindingsLocked(ServiceRecord r) {
10570 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10571 while (bindings.hasNext()) {
10572 IntentBindRecord i = bindings.next();
10573 if (!requestServiceBindingLocked(r, i, false)) {
10574 break;
10575 }
10576 }
10577 }
10578
10579 private final void realStartServiceLocked(ServiceRecord r,
10580 ProcessRecord app) throws RemoteException {
10581 if (app.thread == null) {
10582 throw new RemoteException();
10583 }
10584
10585 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010586 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010587
10588 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010589 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010590 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010591
10592 boolean created = false;
10593 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010594 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010595 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010596 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010597 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010598 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010599 synchronized (r.stats.getBatteryStats()) {
10600 r.stats.startLaunchedLocked();
10601 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010602 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010603 app.thread.scheduleCreateService(r, r.serviceInfo,
10604 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010605 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010606 created = true;
10607 } finally {
10608 if (!created) {
10609 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010610 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010611 }
10612 }
10613
10614 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010615
10616 // If the service is in the started state, and there are no
10617 // pending arguments, then fake up one so its onStartCommand() will
10618 // be called.
10619 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010620 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10621 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010622 }
10623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010624 sendServiceArgsLocked(r, true);
10625 }
10626
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010627 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10628 boolean allowCancel) {
10629 boolean canceled = false;
10630
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010631 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010632 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010633 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010634
Dianne Hackborn070783f2010-12-29 16:46:28 -080010635 if ((r.serviceInfo.applicationInfo.flags
10636 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10637 minDuration /= 4;
10638 }
10639
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010640 // Any delivered but not yet finished starts should be put back
10641 // on the pending list.
10642 final int N = r.deliveredStarts.size();
10643 if (N > 0) {
10644 for (int i=N-1; i>=0; i--) {
10645 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010646 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010647 if (si.intent == null) {
10648 // We'll generate this again if needed.
10649 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10650 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10651 r.pendingStarts.add(0, si);
10652 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10653 dur *= 2;
10654 if (minDuration < dur) minDuration = dur;
10655 if (resetTime < dur) resetTime = dur;
10656 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010657 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010658 + r.name);
10659 canceled = true;
10660 }
10661 }
10662 r.deliveredStarts.clear();
10663 }
10664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010665 r.totalRestartCount++;
10666 if (r.restartDelay == 0) {
10667 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010668 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 } else {
10670 // If it has been a "reasonably long time" since the service
10671 // was started, then reset our restart duration back to
10672 // the beginning, so we don't infinitely increase the duration
10673 // on a service that just occasionally gets killed (which is
10674 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010675 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010677 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010678 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010679 if ((r.serviceInfo.applicationInfo.flags
10680 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10681 // Services in peristent processes will restart much more
10682 // quickly, since they are pretty important. (Think SystemUI).
10683 r.restartDelay += minDuration/2;
10684 } else {
10685 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10686 if (r.restartDelay < minDuration) {
10687 r.restartDelay = minDuration;
10688 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010690 }
10691 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010692
10693 r.nextRestartTime = now + r.restartDelay;
10694
10695 // Make sure that we don't end up restarting a bunch of services
10696 // all at the same time.
10697 boolean repeat;
10698 do {
10699 repeat = false;
10700 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10701 ServiceRecord r2 = mRestartingServices.get(i);
10702 if (r2 != r && r.nextRestartTime
10703 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10704 && r.nextRestartTime
10705 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10706 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10707 r.restartDelay = r.nextRestartTime - now;
10708 repeat = true;
10709 break;
10710 }
10711 }
10712 } while (repeat);
10713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010714 if (!mRestartingServices.contains(r)) {
10715 mRestartingServices.add(r);
10716 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010717
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010718 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010720 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010721 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010722 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010723 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010725 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 r.shortName, r.restartDelay);
10727
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010728 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010729 }
10730
10731 final void performServiceRestartLocked(ServiceRecord r) {
10732 if (!mRestartingServices.contains(r)) {
10733 return;
10734 }
10735 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10736 }
10737
10738 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10739 if (r.restartDelay == 0) {
10740 return false;
10741 }
10742 r.resetRestartCounter();
10743 mRestartingServices.remove(r);
10744 mHandler.removeCallbacks(r.restarter);
10745 return true;
10746 }
10747
10748 private final boolean bringUpServiceLocked(ServiceRecord r,
10749 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010750 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010751 //r.dump(" ");
10752
Dianne Hackborn36124872009-10-08 16:22:03 -070010753 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010754 sendServiceArgsLocked(r, false);
10755 return true;
10756 }
10757
10758 if (!whileRestarting && r.restartDelay > 0) {
10759 // If waiting for a restart, then do nothing.
10760 return true;
10761 }
10762
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010763 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010764
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010765 // We are now bringing the service up, so no longer in the
10766 // restarting state.
10767 mRestartingServices.remove(r);
10768
Dianne Hackborne7f97212011-02-24 14:40:20 -080010769 // Service is now being launched, its package can't be stopped.
10770 try {
10771 AppGlobals.getPackageManager().setPackageStoppedState(
10772 r.packageName, false);
10773 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010774 } catch (IllegalArgumentException e) {
10775 Slog.w(TAG, "Failed trying to unstop package "
10776 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010777 }
10778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 final String appName = r.processName;
10780 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10781 if (app != null && app.thread != null) {
10782 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010783 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010784 realStartServiceLocked(r, app);
10785 return true;
10786 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010787 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010788 }
10789
10790 // If a dead object exception was thrown -- fall through to
10791 // restart the application.
10792 }
10793
Dianne Hackborn36124872009-10-08 16:22:03 -070010794 // Not running -- get it started, and enqueue this service record
10795 // to be executed when the app comes up.
10796 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10797 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010798 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010799 + r.appInfo.packageName + "/"
10800 + r.appInfo.uid + " for service "
10801 + r.intent.getIntent() + ": process is bad");
10802 bringDownServiceLocked(r, true);
10803 return false;
10804 }
10805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010807 mPendingServices.add(r);
10808 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010810 return true;
10811 }
10812
10813 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010814 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010815 //r.dump(" ");
10816
10817 // Does it still need to run?
10818 if (!force && r.startRequested) {
10819 return;
10820 }
10821 if (r.connections.size() > 0) {
10822 if (!force) {
10823 // XXX should probably keep a count of the number of auto-create
10824 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010825 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010826 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010827 ArrayList<ConnectionRecord> cr = it.next();
10828 for (int i=0; i<cr.size(); i++) {
10829 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10830 return;
10831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010832 }
10833 }
10834 }
10835
10836 // Report to all of the connections that the service is no longer
10837 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010838 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010839 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010840 ArrayList<ConnectionRecord> c = it.next();
10841 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010842 ConnectionRecord cr = c.get(i);
10843 // There is still a connection to the service that is
10844 // being brought down. Mark it as dead.
10845 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010846 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010847 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010848 } catch (Exception e) {
10849 Slog.w(TAG, "Failure disconnecting service " + r.name +
10850 " to connection " + c.get(i).conn.asBinder() +
10851 " (in " + c.get(i).binding.client.processName + ")", e);
10852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010853 }
10854 }
10855 }
10856
10857 // Tell the service that it has been unbound.
10858 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10859 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10860 while (it.hasNext()) {
10861 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010862 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 + ": hasBound=" + ibr.hasBound);
10864 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10865 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010866 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010867 updateOomAdjLocked(r.app);
10868 ibr.hasBound = false;
10869 r.app.thread.scheduleUnbindService(r,
10870 ibr.intent.getIntent());
10871 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010872 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873 + r.shortName, e);
10874 serviceDoneExecutingLocked(r, true);
10875 }
10876 }
10877 }
10878 }
10879
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010880 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010881 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010882 System.identityHashCode(r), r.shortName,
10883 (r.app != null) ? r.app.pid : -1);
10884
10885 mServices.remove(r.name);
10886 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010887 r.totalRestartCount = 0;
10888 unscheduleServiceRestartLocked(r);
10889
10890 // Also make sure it is not on the pending list.
10891 int N = mPendingServices.size();
10892 for (int i=0; i<N; i++) {
10893 if (mPendingServices.get(i) == r) {
10894 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010895 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896 i--;
10897 N--;
10898 }
10899 }
10900
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010901 r.cancelNotification();
10902 r.isForeground = false;
10903 r.foregroundId = 0;
10904 r.foregroundNoti = null;
10905
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010906 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010907 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010908 r.pendingStarts.clear();
10909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 if (r.app != null) {
10911 synchronized (r.stats.getBatteryStats()) {
10912 r.stats.stopLaunchedLocked();
10913 }
10914 r.app.services.remove(r);
10915 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010916 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010917 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918 mStoppingServices.add(r);
10919 updateOomAdjLocked(r.app);
10920 r.app.thread.scheduleStopService(r);
10921 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010922 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010923 + r.shortName, e);
10924 serviceDoneExecutingLocked(r, true);
10925 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010926 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010927 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010928 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010929 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010930 }
10931 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010932 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010933 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010934 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010935
10936 if (r.bindings.size() > 0) {
10937 r.bindings.clear();
10938 }
10939
10940 if (r.restarter instanceof ServiceRestarter) {
10941 ((ServiceRestarter)r.restarter).setService(null);
10942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010943 }
10944
10945 ComponentName startServiceLocked(IApplicationThread caller,
10946 Intent service, String resolvedType,
10947 int callingPid, int callingUid) {
10948 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010949 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010950 + " type=" + resolvedType + " args=" + service.getExtras());
10951
10952 if (caller != null) {
10953 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10954 if (callerApp == null) {
10955 throw new SecurityException(
10956 "Unable to find app for caller " + caller
10957 + " (pid=" + Binder.getCallingPid()
10958 + ") when starting service " + service);
10959 }
10960 }
10961
10962 ServiceLookupResult res =
10963 retrieveServiceLocked(service, resolvedType,
10964 callingPid, callingUid);
10965 if (res == null) {
10966 return null;
10967 }
10968 if (res.record == null) {
10969 return new ComponentName("!", res.permission != null
10970 ? res.permission : "private to package");
10971 }
10972 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010973 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10974 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010975 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010976 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010977 }
10978 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010979 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010980 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010981 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010982 r.lastActivity = SystemClock.uptimeMillis();
10983 synchronized (r.stats.getBatteryStats()) {
10984 r.stats.startRunningLocked();
10985 }
10986 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10987 return new ComponentName("!", "Service process is bad");
10988 }
10989 return r.name;
10990 }
10991 }
10992
10993 public ComponentName startService(IApplicationThread caller, Intent service,
10994 String resolvedType) {
10995 // Refuse possible leaked file descriptors
10996 if (service != null && service.hasFileDescriptors() == true) {
10997 throw new IllegalArgumentException("File descriptors passed in Intent");
10998 }
10999
11000 synchronized(this) {
11001 final int callingPid = Binder.getCallingPid();
11002 final int callingUid = Binder.getCallingUid();
11003 final long origId = Binder.clearCallingIdentity();
11004 ComponentName res = startServiceLocked(caller, service,
11005 resolvedType, callingPid, callingUid);
11006 Binder.restoreCallingIdentity(origId);
11007 return res;
11008 }
11009 }
11010
11011 ComponentName startServiceInPackage(int uid,
11012 Intent service, String resolvedType) {
11013 synchronized(this) {
11014 final long origId = Binder.clearCallingIdentity();
11015 ComponentName res = startServiceLocked(null, service,
11016 resolvedType, -1, uid);
11017 Binder.restoreCallingIdentity(origId);
11018 return res;
11019 }
11020 }
11021
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011022 private void stopServiceLocked(ServiceRecord service) {
11023 synchronized (service.stats.getBatteryStats()) {
11024 service.stats.stopRunningLocked();
11025 }
11026 service.startRequested = false;
11027 service.callStart = false;
11028 bringDownServiceLocked(service, false);
11029 }
11030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 public int stopService(IApplicationThread caller, Intent service,
11032 String resolvedType) {
11033 // Refuse possible leaked file descriptors
11034 if (service != null && service.hasFileDescriptors() == true) {
11035 throw new IllegalArgumentException("File descriptors passed in Intent");
11036 }
11037
11038 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011039 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011040 + " type=" + resolvedType);
11041
11042 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11043 if (caller != null && callerApp == null) {
11044 throw new SecurityException(
11045 "Unable to find app for caller " + caller
11046 + " (pid=" + Binder.getCallingPid()
11047 + ") when stopping service " + service);
11048 }
11049
11050 // If this service is active, make sure it is stopped.
11051 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11052 if (r != null) {
11053 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011054 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011055 try {
11056 stopServiceLocked(r.record);
11057 } finally {
11058 Binder.restoreCallingIdentity(origId);
11059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011060 return 1;
11061 }
11062 return -1;
11063 }
11064 }
11065
11066 return 0;
11067 }
11068
11069 public IBinder peekService(Intent service, String resolvedType) {
11070 // Refuse possible leaked file descriptors
11071 if (service != null && service.hasFileDescriptors() == true) {
11072 throw new IllegalArgumentException("File descriptors passed in Intent");
11073 }
11074
11075 IBinder ret = null;
11076
11077 synchronized(this) {
11078 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11079
11080 if (r != null) {
11081 // r.record is null if findServiceLocked() failed the caller permission check
11082 if (r.record == null) {
11083 throw new SecurityException(
11084 "Permission Denial: Accessing service " + r.record.name
11085 + " from pid=" + Binder.getCallingPid()
11086 + ", uid=" + Binder.getCallingUid()
11087 + " requires " + r.permission);
11088 }
11089 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11090 if (ib != null) {
11091 ret = ib.binder;
11092 }
11093 }
11094 }
11095
11096 return ret;
11097 }
11098
11099 public boolean stopServiceToken(ComponentName className, IBinder token,
11100 int startId) {
11101 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011102 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011103 + " " + token + " startId=" + startId);
11104 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011105 if (r != null) {
11106 if (startId >= 0) {
11107 // Asked to only stop if done with all work. Note that
11108 // to avoid leaks, we will take this as dropping all
11109 // start items up to and including this one.
11110 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11111 if (si != null) {
11112 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011113 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11114 cur.removeUriPermissionsLocked();
11115 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011116 break;
11117 }
11118 }
11119 }
11120
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011121 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011122 return false;
11123 }
11124
11125 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011126 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011127 + " is last, but have " + r.deliveredStarts.size()
11128 + " remaining args");
11129 }
11130 }
11131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 synchronized (r.stats.getBatteryStats()) {
11133 r.stats.stopRunningLocked();
11134 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011135 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 }
11137 final long origId = Binder.clearCallingIdentity();
11138 bringDownServiceLocked(r, false);
11139 Binder.restoreCallingIdentity(origId);
11140 return true;
11141 }
11142 }
11143 return false;
11144 }
11145
11146 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011147 int id, Notification notification, boolean removeNotification) {
11148 final long origId = Binder.clearCallingIdentity();
11149 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011150 synchronized(this) {
11151 ServiceRecord r = findServiceLocked(className, token);
11152 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011153 if (id != 0) {
11154 if (notification == null) {
11155 throw new IllegalArgumentException("null notification");
11156 }
11157 if (r.foregroundId != id) {
11158 r.cancelNotification();
11159 r.foregroundId = id;
11160 }
11161 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11162 r.foregroundNoti = notification;
11163 r.isForeground = true;
11164 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 if (r.app != null) {
11166 updateServiceForegroundLocked(r.app, true);
11167 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011168 } else {
11169 if (r.isForeground) {
11170 r.isForeground = false;
11171 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011172 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011173 updateServiceForegroundLocked(r.app, true);
11174 }
11175 }
11176 if (removeNotification) {
11177 r.cancelNotification();
11178 r.foregroundId = 0;
11179 r.foregroundNoti = null;
11180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 }
11182 }
11183 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011184 } finally {
11185 Binder.restoreCallingIdentity(origId);
11186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011187 }
11188
11189 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11190 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011191 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011192 if (sr.isForeground) {
11193 anyForeground = true;
11194 break;
11195 }
11196 }
11197 if (anyForeground != proc.foregroundServices) {
11198 proc.foregroundServices = anyForeground;
11199 if (oomAdj) {
11200 updateOomAdjLocked();
11201 }
11202 }
11203 }
11204
11205 public int bindService(IApplicationThread caller, IBinder token,
11206 Intent service, String resolvedType,
11207 IServiceConnection connection, int flags) {
11208 // Refuse possible leaked file descriptors
11209 if (service != null && service.hasFileDescriptors() == true) {
11210 throw new IllegalArgumentException("File descriptors passed in Intent");
11211 }
11212
11213 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011214 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011215 + " type=" + resolvedType + " conn=" + connection.asBinder()
11216 + " flags=0x" + Integer.toHexString(flags));
11217 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11218 if (callerApp == null) {
11219 throw new SecurityException(
11220 "Unable to find app for caller " + caller
11221 + " (pid=" + Binder.getCallingPid()
11222 + ") when binding service " + service);
11223 }
11224
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011225 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011226 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011227 activity = mMainStack.isInStackLocked(token);
11228 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011229 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011230 return 0;
11231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011232 }
11233
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011234 int clientLabel = 0;
11235 PendingIntent clientIntent = null;
11236
11237 if (callerApp.info.uid == Process.SYSTEM_UID) {
11238 // Hacky kind of thing -- allow system stuff to tell us
11239 // what they are, so we can report this elsewhere for
11240 // others to know why certain services are running.
11241 try {
11242 clientIntent = (PendingIntent)service.getParcelableExtra(
11243 Intent.EXTRA_CLIENT_INTENT);
11244 } catch (RuntimeException e) {
11245 }
11246 if (clientIntent != null) {
11247 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11248 if (clientLabel != 0) {
11249 // There are no useful extras in the intent, trash them.
11250 // System code calling with this stuff just needs to know
11251 // this will happen.
11252 service = service.cloneFilter();
11253 }
11254 }
11255 }
11256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011257 ServiceLookupResult res =
11258 retrieveServiceLocked(service, resolvedType,
11259 Binder.getCallingPid(), Binder.getCallingUid());
11260 if (res == null) {
11261 return 0;
11262 }
11263 if (res.record == null) {
11264 return -1;
11265 }
11266 ServiceRecord s = res.record;
11267
11268 final long origId = Binder.clearCallingIdentity();
11269
11270 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011271 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011272 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011273 }
11274
11275 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11276 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011277 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011278
11279 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011280 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11281 if (clist == null) {
11282 clist = new ArrayList<ConnectionRecord>();
11283 s.connections.put(binder, clist);
11284 }
11285 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011286 b.connections.add(c);
11287 if (activity != null) {
11288 if (activity.connections == null) {
11289 activity.connections = new HashSet<ConnectionRecord>();
11290 }
11291 activity.connections.add(c);
11292 }
11293 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011294 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11295 b.client.hasAboveClient = true;
11296 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011297 clist = mServiceConnections.get(binder);
11298 if (clist == null) {
11299 clist = new ArrayList<ConnectionRecord>();
11300 mServiceConnections.put(binder, clist);
11301 }
11302 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011303
11304 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11305 s.lastActivity = SystemClock.uptimeMillis();
11306 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11307 return 0;
11308 }
11309 }
11310
11311 if (s.app != null) {
11312 // This could have made the service more important.
11313 updateOomAdjLocked(s.app);
11314 }
11315
Joe Onorato8a9b2202010-02-26 18:56:32 -080011316 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011317 + ": received=" + b.intent.received
11318 + " apps=" + b.intent.apps.size()
11319 + " doRebind=" + b.intent.doRebind);
11320
11321 if (s.app != null && b.intent.received) {
11322 // Service is already running, so we can immediately
11323 // publish the connection.
11324 try {
11325 c.conn.connected(s.name, b.intent.binder);
11326 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011327 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011328 + " to connection " + c.conn.asBinder()
11329 + " (in " + c.binding.client.processName + ")", e);
11330 }
11331
11332 // If this is the first app connected back to this binding,
11333 // and the service had previously asked to be told when
11334 // rebound, then do so.
11335 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11336 requestServiceBindingLocked(s, b.intent, true);
11337 }
11338 } else if (!b.intent.requested) {
11339 requestServiceBindingLocked(s, b.intent, false);
11340 }
11341
11342 Binder.restoreCallingIdentity(origId);
11343 }
11344
11345 return 1;
11346 }
11347
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011348 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011349 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011350 IBinder binder = c.conn.asBinder();
11351 AppBindRecord b = c.binding;
11352 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011353 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11354 if (clist != null) {
11355 clist.remove(c);
11356 if (clist.size() == 0) {
11357 s.connections.remove(binder);
11358 }
11359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 b.connections.remove(c);
11361 if (c.activity != null && c.activity != skipAct) {
11362 if (c.activity.connections != null) {
11363 c.activity.connections.remove(c);
11364 }
11365 }
11366 if (b.client != skipApp) {
11367 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011368 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11369 b.client.updateHasAboveClientLocked();
11370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011372 clist = mServiceConnections.get(binder);
11373 if (clist != null) {
11374 clist.remove(c);
11375 if (clist.size() == 0) {
11376 mServiceConnections.remove(binder);
11377 }
11378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011379
11380 if (b.connections.size() == 0) {
11381 b.intent.apps.remove(b.client);
11382 }
11383
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011384 if (!c.serviceDead) {
11385 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11386 + ": shouldUnbind=" + b.intent.hasBound);
11387 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11388 && b.intent.hasBound) {
11389 try {
11390 bumpServiceExecutingLocked(s, "unbind");
11391 updateOomAdjLocked(s.app);
11392 b.intent.hasBound = false;
11393 // Assume the client doesn't want to know about a rebind;
11394 // we will deal with that later if it asks for one.
11395 b.intent.doRebind = false;
11396 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11397 } catch (Exception e) {
11398 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11399 serviceDoneExecutingLocked(s, true);
11400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011401 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011402
11403 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11404 bringDownServiceLocked(s, false);
11405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011406 }
11407 }
11408
11409 public boolean unbindService(IServiceConnection connection) {
11410 synchronized (this) {
11411 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011412 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011413 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11414 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011415 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 + connection.asBinder());
11417 return false;
11418 }
11419
11420 final long origId = Binder.clearCallingIdentity();
11421
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011422 while (clist.size() > 0) {
11423 ConnectionRecord r = clist.get(0);
11424 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011426 if (r.binding.service.app != null) {
11427 // This could have made the service less important.
11428 updateOomAdjLocked(r.binding.service.app);
11429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011430 }
11431
11432 Binder.restoreCallingIdentity(origId);
11433 }
11434
11435 return true;
11436 }
11437
11438 public void publishService(IBinder token, Intent intent, IBinder service) {
11439 // Refuse possible leaked file descriptors
11440 if (intent != null && intent.hasFileDescriptors() == true) {
11441 throw new IllegalArgumentException("File descriptors passed in Intent");
11442 }
11443
11444 synchronized(this) {
11445 if (!(token instanceof ServiceRecord)) {
11446 throw new IllegalArgumentException("Invalid service token");
11447 }
11448 ServiceRecord r = (ServiceRecord)token;
11449
11450 final long origId = Binder.clearCallingIdentity();
11451
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011452 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 + " " + intent + ": " + service);
11454 if (r != null) {
11455 Intent.FilterComparison filter
11456 = new Intent.FilterComparison(intent);
11457 IntentBindRecord b = r.bindings.get(filter);
11458 if (b != null && !b.received) {
11459 b.binder = service;
11460 b.requested = true;
11461 b.received = true;
11462 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011463 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011464 = r.connections.values().iterator();
11465 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011466 ArrayList<ConnectionRecord> clist = it.next();
11467 for (int i=0; i<clist.size(); i++) {
11468 ConnectionRecord c = clist.get(i);
11469 if (!filter.equals(c.binding.intent.intent)) {
11470 if (DEBUG_SERVICE) Slog.v(
11471 TAG, "Not publishing to: " + c);
11472 if (DEBUG_SERVICE) Slog.v(
11473 TAG, "Bound intent: " + c.binding.intent.intent);
11474 if (DEBUG_SERVICE) Slog.v(
11475 TAG, "Published intent: " + intent);
11476 continue;
11477 }
11478 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11479 try {
11480 c.conn.connected(r.name, service);
11481 } catch (Exception e) {
11482 Slog.w(TAG, "Failure sending service " + r.name +
11483 " to connection " + c.conn.asBinder() +
11484 " (in " + c.binding.client.processName + ")", e);
11485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011486 }
11487 }
11488 }
11489 }
11490
11491 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11492
11493 Binder.restoreCallingIdentity(origId);
11494 }
11495 }
11496 }
11497
11498 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11499 // Refuse possible leaked file descriptors
11500 if (intent != null && intent.hasFileDescriptors() == true) {
11501 throw new IllegalArgumentException("File descriptors passed in Intent");
11502 }
11503
11504 synchronized(this) {
11505 if (!(token instanceof ServiceRecord)) {
11506 throw new IllegalArgumentException("Invalid service token");
11507 }
11508 ServiceRecord r = (ServiceRecord)token;
11509
11510 final long origId = Binder.clearCallingIdentity();
11511
11512 if (r != null) {
11513 Intent.FilterComparison filter
11514 = new Intent.FilterComparison(intent);
11515 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011516 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011517 + " at " + b + ": apps="
11518 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011519
11520 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011521 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011522 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011523 // Applications have already bound since the last
11524 // unbind, so just rebind right here.
11525 requestServiceBindingLocked(r, b, true);
11526 } else {
11527 // Note to tell the service the next time there is
11528 // a new client.
11529 b.doRebind = true;
11530 }
11531 }
11532
Per Edelberg78f9fff2010-08-30 20:01:35 +020011533 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011534
11535 Binder.restoreCallingIdentity(origId);
11536 }
11537 }
11538 }
11539
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011540 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011541 synchronized(this) {
11542 if (!(token instanceof ServiceRecord)) {
11543 throw new IllegalArgumentException("Invalid service token");
11544 }
11545 ServiceRecord r = (ServiceRecord)token;
11546 boolean inStopping = mStoppingServices.contains(token);
11547 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011548 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011549 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 + " with incorrect token: given " + token
11551 + ", expected " + r);
11552 return;
11553 }
11554
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011555 if (type == 1) {
11556 // This is a call from a service start... take care of
11557 // book-keeping.
11558 r.callStart = true;
11559 switch (res) {
11560 case Service.START_STICKY_COMPATIBILITY:
11561 case Service.START_STICKY: {
11562 // We are done with the associated start arguments.
11563 r.findDeliveredStart(startId, true);
11564 // Don't stop if killed.
11565 r.stopIfKilled = false;
11566 break;
11567 }
11568 case Service.START_NOT_STICKY: {
11569 // We are done with the associated start arguments.
11570 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011571 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011572 // There is no more work, and this service
11573 // doesn't want to hang around if killed.
11574 r.stopIfKilled = true;
11575 }
11576 break;
11577 }
11578 case Service.START_REDELIVER_INTENT: {
11579 // We'll keep this item until they explicitly
11580 // call stop for it, but keep track of the fact
11581 // that it was delivered.
11582 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11583 if (si != null) {
11584 si.deliveryCount = 0;
11585 si.doneExecutingCount++;
11586 // Don't stop if killed.
11587 r.stopIfKilled = true;
11588 }
11589 break;
11590 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011591 case Service.START_TASK_REMOVED_COMPLETE: {
11592 // Special processing for onTaskRemoved(). Don't
11593 // impact normal onStartCommand() processing.
11594 r.findDeliveredStart(startId, true);
11595 break;
11596 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011597 default:
11598 throw new IllegalArgumentException(
11599 "Unknown service start result: " + res);
11600 }
11601 if (res == Service.START_STICKY_COMPATIBILITY) {
11602 r.callStart = false;
11603 }
11604 }
11605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011606 final long origId = Binder.clearCallingIdentity();
11607 serviceDoneExecutingLocked(r, inStopping);
11608 Binder.restoreCallingIdentity(origId);
11609 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011610 Slog.w(TAG, "Done executing unknown service from pid "
11611 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011612 }
11613 }
11614 }
11615
11616 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011617 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11618 + ": nesting=" + r.executeNesting
11619 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011620 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011621 r.executeNesting--;
11622 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011623 if (DEBUG_SERVICE) Slog.v(TAG,
11624 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011625 r.app.executingServices.remove(r);
11626 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011627 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11628 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11630 }
11631 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011632 if (DEBUG_SERVICE) Slog.v(TAG,
11633 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011634 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011635 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011636 }
11637 updateOomAdjLocked(r.app);
11638 }
11639 }
11640
11641 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011642 String anrMessage = null;
11643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011644 synchronized(this) {
11645 if (proc.executingServices.size() == 0 || proc.thread == null) {
11646 return;
11647 }
11648 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11649 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11650 ServiceRecord timeout = null;
11651 long nextTime = 0;
11652 while (it.hasNext()) {
11653 ServiceRecord sr = it.next();
11654 if (sr.executingStart < maxTime) {
11655 timeout = sr;
11656 break;
11657 }
11658 if (sr.executingStart > nextTime) {
11659 nextTime = sr.executingStart;
11660 }
11661 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011662 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011663 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011664 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011665 } else {
11666 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11667 msg.obj = proc;
11668 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11669 }
11670 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011671
11672 if (anrMessage != null) {
11673 appNotResponding(proc, null, null, anrMessage);
11674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011675 }
11676
11677 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011678 // BACKUP AND RESTORE
11679 // =========================================================
11680
11681 // Cause the target app to be launched if necessary and its backup agent
11682 // instantiated. The backup agent will invoke backupAgentCreated() on the
11683 // activity manager to announce its creation.
11684 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011685 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011686 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11687
11688 synchronized(this) {
11689 // !!! TODO: currently no check here that we're already bound
11690 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11691 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11692 synchronized (stats) {
11693 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11694 }
11695
Dianne Hackborne7f97212011-02-24 14:40:20 -080011696 // Backup agent is now in use, its package can't be stopped.
11697 try {
11698 AppGlobals.getPackageManager().setPackageStoppedState(
11699 app.packageName, false);
11700 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011701 } catch (IllegalArgumentException e) {
11702 Slog.w(TAG, "Failed trying to unstop package "
11703 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011704 }
11705
Christopher Tate181fafa2009-05-14 11:12:14 -070011706 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011707 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11708 ? new ComponentName(app.packageName, app.backupAgentName)
11709 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011710 // startProcessLocked() returns existing proc's record if it's already running
11711 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011712 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011713 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011714 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011715 return false;
11716 }
11717
11718 r.app = proc;
11719 mBackupTarget = r;
11720 mBackupAppName = app.packageName;
11721
Christopher Tate6fa95972009-06-05 18:43:55 -070011722 // Try not to kill the process during backup
11723 updateOomAdjLocked(proc);
11724
Christopher Tate181fafa2009-05-14 11:12:14 -070011725 // If the process is already attached, schedule the creation of the backup agent now.
11726 // If it is not yet live, this will be done when it attaches to the framework.
11727 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011728 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011729 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011730 proc.thread.scheduleCreateBackupAgent(app,
11731 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011732 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011733 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011734 }
11735 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011736 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011737 }
11738 // Invariants: at this point, the target app process exists and the application
11739 // is either already running or in the process of coming up. mBackupTarget and
11740 // mBackupAppName describe the app, so that when it binds back to the AM we
11741 // know that it's scheduled for a backup-agent operation.
11742 }
11743
11744 return true;
11745 }
11746
11747 // A backup agent has just come up
11748 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011749 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011750 + " = " + agent);
11751
11752 synchronized(this) {
11753 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011754 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011755 return;
11756 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011757 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011758
Dianne Hackborn06740692010-09-22 22:46:21 -070011759 long oldIdent = Binder.clearCallingIdentity();
11760 try {
11761 IBackupManager bm = IBackupManager.Stub.asInterface(
11762 ServiceManager.getService(Context.BACKUP_SERVICE));
11763 bm.agentConnected(agentPackageName, agent);
11764 } catch (RemoteException e) {
11765 // can't happen; the backup manager service is local
11766 } catch (Exception e) {
11767 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11768 e.printStackTrace();
11769 } finally {
11770 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011771 }
11772 }
11773
11774 // done with this agent
11775 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011776 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011777 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011778 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011779 return;
11780 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011781
11782 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011783 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011784 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011785 return;
11786 }
11787
Christopher Tate181fafa2009-05-14 11:12:14 -070011788 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011789 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011790 return;
11791 }
11792
Christopher Tate6fa95972009-06-05 18:43:55 -070011793 ProcessRecord proc = mBackupTarget.app;
11794 mBackupTarget = null;
11795 mBackupAppName = null;
11796
11797 // Not backing this app up any more; reset its OOM adjustment
11798 updateOomAdjLocked(proc);
11799
Christopher Tatec7b31e32009-06-10 15:49:30 -070011800 // If the app crashed during backup, 'thread' will be null here
11801 if (proc.thread != null) {
11802 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011803 proc.thread.scheduleDestroyBackupAgent(appInfo,
11804 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011805 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011806 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011807 e.printStackTrace();
11808 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011809 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011810 }
11811 }
11812 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011813 // BROADCASTS
11814 // =========================================================
11815
Josh Bartel7f208742010-02-25 11:01:44 -060011816 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011817 List cur) {
11818 final ContentResolver resolver = mContext.getContentResolver();
11819 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11820 if (list == null) {
11821 return cur;
11822 }
11823 int N = list.size();
11824 for (int i=0; i<N; i++) {
11825 Intent intent = list.get(i);
11826 if (filter.match(resolver, intent, true, TAG) >= 0) {
11827 if (cur == null) {
11828 cur = new ArrayList<Intent>();
11829 }
11830 cur.add(intent);
11831 }
11832 }
11833 return cur;
11834 }
11835
11836 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011837 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 + mBroadcastsScheduled);
11839
11840 if (mBroadcastsScheduled) {
11841 return;
11842 }
11843 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11844 mBroadcastsScheduled = true;
11845 }
11846
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011847 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011848 IIntentReceiver receiver, IntentFilter filter, String permission) {
11849 synchronized(this) {
11850 ProcessRecord callerApp = null;
11851 if (caller != null) {
11852 callerApp = getRecordForAppLocked(caller);
11853 if (callerApp == null) {
11854 throw new SecurityException(
11855 "Unable to find app for caller " + caller
11856 + " (pid=" + Binder.getCallingPid()
11857 + ") when registering receiver " + receiver);
11858 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011859 if (callerApp.info.uid != Process.SYSTEM_UID &&
11860 !callerApp.pkgList.contains(callerPackage)) {
11861 throw new SecurityException("Given caller package " + callerPackage
11862 + " is not running in process " + callerApp);
11863 }
11864 } else {
11865 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011866 }
11867
11868 List allSticky = null;
11869
11870 // Look for any matching sticky broadcasts...
11871 Iterator actions = filter.actionsIterator();
11872 if (actions != null) {
11873 while (actions.hasNext()) {
11874 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011875 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011876 }
11877 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011878 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011879 }
11880
11881 // The first sticky in the list is returned directly back to
11882 // the client.
11883 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11884
Joe Onorato8a9b2202010-02-26 18:56:32 -080011885 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 + ": " + sticky);
11887
11888 if (receiver == null) {
11889 return sticky;
11890 }
11891
11892 ReceiverList rl
11893 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11894 if (rl == null) {
11895 rl = new ReceiverList(this, callerApp,
11896 Binder.getCallingPid(),
11897 Binder.getCallingUid(), receiver);
11898 if (rl.app != null) {
11899 rl.app.receivers.add(rl);
11900 } else {
11901 try {
11902 receiver.asBinder().linkToDeath(rl, 0);
11903 } catch (RemoteException e) {
11904 return sticky;
11905 }
11906 rl.linkedToDeath = true;
11907 }
11908 mRegisteredReceivers.put(receiver.asBinder(), rl);
11909 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011910 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 rl.add(bf);
11912 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011913 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 }
11915 mReceiverResolver.addFilter(bf);
11916
11917 // Enqueue broadcasts for all existing stickies that match
11918 // this filter.
11919 if (allSticky != null) {
11920 ArrayList receivers = new ArrayList();
11921 receivers.add(bf);
11922
11923 int N = allSticky.size();
11924 for (int i=0; i<N; i++) {
11925 Intent intent = (Intent)allSticky.get(i);
11926 BroadcastRecord r = new BroadcastRecord(intent, null,
11927 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011928 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011929 if (mParallelBroadcasts.size() == 0) {
11930 scheduleBroadcastsLocked();
11931 }
11932 mParallelBroadcasts.add(r);
11933 }
11934 }
11935
11936 return sticky;
11937 }
11938 }
11939
11940 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011941 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942
11943 boolean doNext = false;
11944
11945 synchronized(this) {
11946 ReceiverList rl
11947 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11948 if (rl != null) {
11949 if (rl.curBroadcast != null) {
11950 BroadcastRecord r = rl.curBroadcast;
11951 doNext = finishReceiverLocked(
11952 receiver.asBinder(), r.resultCode, r.resultData,
11953 r.resultExtras, r.resultAbort, true);
11954 }
11955
11956 if (rl.app != null) {
11957 rl.app.receivers.remove(rl);
11958 }
11959 removeReceiverLocked(rl);
11960 if (rl.linkedToDeath) {
11961 rl.linkedToDeath = false;
11962 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11963 }
11964 }
11965 }
11966
11967 if (!doNext) {
11968 return;
11969 }
11970
11971 final long origId = Binder.clearCallingIdentity();
11972 processNextBroadcast(false);
11973 trimApplications();
11974 Binder.restoreCallingIdentity(origId);
11975 }
11976
11977 void removeReceiverLocked(ReceiverList rl) {
11978 mRegisteredReceivers.remove(rl.receiver.asBinder());
11979 int N = rl.size();
11980 for (int i=0; i<N; i++) {
11981 mReceiverResolver.removeFilter(rl.get(i));
11982 }
11983 }
11984
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011985 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11986 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11987 ProcessRecord r = mLruProcesses.get(i);
11988 if (r.thread != null) {
11989 try {
11990 r.thread.dispatchPackageBroadcast(cmd, packages);
11991 } catch (RemoteException ex) {
11992 }
11993 }
11994 }
11995 }
11996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011997 private final int broadcastIntentLocked(ProcessRecord callerApp,
11998 String callerPackage, Intent intent, String resolvedType,
11999 IIntentReceiver resultTo, int resultCode, String resultData,
12000 Bundle map, String requiredPermission,
12001 boolean ordered, boolean sticky, int callingPid, int callingUid) {
12002 intent = new Intent(intent);
12003
Dianne Hackborne7f97212011-02-24 14:40:20 -080012004 // By default broadcasts do not go to stopped apps.
12005 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12006
Joe Onorato8a9b2202010-02-26 18:56:32 -080012007 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12009 + " ordered=" + ordered);
12010 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012011 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012012 }
12013
12014 // Handle special intents: if this broadcast is from the package
12015 // manager about a package being removed, we need to remove all of
12016 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012017 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012018 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012019 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12020 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012021 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012022 || uidRemoved) {
12023 if (checkComponentPermission(
12024 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012025 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 == PackageManager.PERMISSION_GRANTED) {
12027 if (uidRemoved) {
12028 final Bundle intentExtras = intent.getExtras();
12029 final int uid = intentExtras != null
12030 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12031 if (uid >= 0) {
12032 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12033 synchronized (bs) {
12034 bs.removeUidStatsLocked(uid);
12035 }
12036 }
12037 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012038 // If resources are unvailble just force stop all
12039 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012040 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012041 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12042 if (list != null && (list.length > 0)) {
12043 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070012044 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012045 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012046 sendPackageBroadcastLocked(
12047 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012048 }
12049 } else {
12050 Uri data = intent.getData();
12051 String ssp;
12052 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12053 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12054 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070012055 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012056 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012057 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012058 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12059 new String[] {ssp});
12060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 }
12062 }
12063 }
12064 } else {
12065 String msg = "Permission Denial: " + intent.getAction()
12066 + " broadcast from " + callerPackage + " (pid=" + callingPid
12067 + ", uid=" + callingUid + ")"
12068 + " requires "
12069 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012070 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 throw new SecurityException(msg);
12072 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012073
12074 // Special case for adding a package: by default turn on compatibility
12075 // mode.
12076 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012077 Uri data = intent.getData();
12078 String ssp;
12079 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12080 mCompatModePackages.handlePackageAddedLocked(ssp,
12081 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012083 }
12084
12085 /*
12086 * If this is the time zone changed action, queue up a message that will reset the timezone
12087 * of all currently running processes. This message will get queued up before the broadcast
12088 * happens.
12089 */
12090 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12091 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12092 }
12093
Robert Greenwalt03595d02010-11-02 14:08:23 -070012094 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12095 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12096 }
12097
Robert Greenwalt434203a2010-10-11 16:00:27 -070012098 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12099 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12100 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12101 }
12102
Dianne Hackborn854060af2009-07-09 18:14:31 -070012103 /*
12104 * Prevent non-system code (defined here to be non-persistent
12105 * processes) from sending protected broadcasts.
12106 */
12107 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12108 || callingUid == Process.SHELL_UID || callingUid == 0) {
12109 // Always okay.
12110 } else if (callerApp == null || !callerApp.persistent) {
12111 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012112 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012113 intent.getAction())) {
12114 String msg = "Permission Denial: not allowed to send broadcast "
12115 + intent.getAction() + " from pid="
12116 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012117 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012118 throw new SecurityException(msg);
12119 }
12120 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012121 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012122 return BROADCAST_SUCCESS;
12123 }
12124 }
12125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012126 // Add to the sticky list if requested.
12127 if (sticky) {
12128 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12129 callingPid, callingUid)
12130 != PackageManager.PERMISSION_GRANTED) {
12131 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12132 + callingPid + ", uid=" + callingUid
12133 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012134 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012135 throw new SecurityException(msg);
12136 }
12137 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012138 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 + " and enforce permission " + requiredPermission);
12140 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12141 }
12142 if (intent.getComponent() != null) {
12143 throw new SecurityException(
12144 "Sticky broadcasts can't target a specific component");
12145 }
12146 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12147 if (list == null) {
12148 list = new ArrayList<Intent>();
12149 mStickyBroadcasts.put(intent.getAction(), list);
12150 }
12151 int N = list.size();
12152 int i;
12153 for (i=0; i<N; i++) {
12154 if (intent.filterEquals(list.get(i))) {
12155 // This sticky already exists, replace it.
12156 list.set(i, new Intent(intent));
12157 break;
12158 }
12159 }
12160 if (i >= N) {
12161 list.add(new Intent(intent));
12162 }
12163 }
12164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165 // Figure out who all will receive this broadcast.
12166 List receivers = null;
12167 List<BroadcastFilter> registeredReceivers = null;
12168 try {
12169 if (intent.getComponent() != null) {
12170 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012171 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070012172 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012173 if (ai != null) {
12174 receivers = new ArrayList();
12175 ResolveInfo ri = new ResolveInfo();
12176 ri.activityInfo = ai;
12177 receivers.add(ri);
12178 }
12179 } else {
12180 // Need to resolve the intent to interested receivers...
12181 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12182 == 0) {
12183 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012184 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012185 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012186 }
Mihai Preda074edef2009-05-18 17:13:31 +020012187 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 }
12189 } catch (RemoteException ex) {
12190 // pm is in same process, this will never happen.
12191 }
12192
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012193 final boolean replacePending =
12194 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12195
Joe Onorato8a9b2202010-02-26 18:56:32 -080012196 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012197 + " replacePending=" + replacePending);
12198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12200 if (!ordered && NR > 0) {
12201 // If we are not serializing this broadcast, then send the
12202 // registered receivers separately so they don't wait for the
12203 // components to be launched.
12204 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12205 callerPackage, callingPid, callingUid, requiredPermission,
12206 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012207 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012208 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012209 TAG, "Enqueueing parallel broadcast " + r
12210 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012211 boolean replaced = false;
12212 if (replacePending) {
12213 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12214 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012215 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012216 "***** DROPPING PARALLEL: " + intent);
12217 mParallelBroadcasts.set(i, r);
12218 replaced = true;
12219 break;
12220 }
12221 }
12222 }
12223 if (!replaced) {
12224 mParallelBroadcasts.add(r);
12225 scheduleBroadcastsLocked();
12226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012227 registeredReceivers = null;
12228 NR = 0;
12229 }
12230
12231 // Merge into one list.
12232 int ir = 0;
12233 if (receivers != null) {
12234 // A special case for PACKAGE_ADDED: do not allow the package
12235 // being added to see this broadcast. This prevents them from
12236 // using this as a back door to get run as soon as they are
12237 // installed. Maybe in the future we want to have a special install
12238 // broadcast or such for apps, but we'd like to deliberately make
12239 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012240 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012241 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12242 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12243 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012244 Uri data = intent.getData();
12245 if (data != null) {
12246 String pkgName = data.getSchemeSpecificPart();
12247 if (pkgName != null) {
12248 skipPackages = new String[] { pkgName };
12249 }
12250 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012251 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012252 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012253 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012254 if (skipPackages != null && (skipPackages.length > 0)) {
12255 for (String skipPackage : skipPackages) {
12256 if (skipPackage != null) {
12257 int NT = receivers.size();
12258 for (int it=0; it<NT; it++) {
12259 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12260 if (curt.activityInfo.packageName.equals(skipPackage)) {
12261 receivers.remove(it);
12262 it--;
12263 NT--;
12264 }
12265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012266 }
12267 }
12268 }
12269
12270 int NT = receivers != null ? receivers.size() : 0;
12271 int it = 0;
12272 ResolveInfo curt = null;
12273 BroadcastFilter curr = null;
12274 while (it < NT && ir < NR) {
12275 if (curt == null) {
12276 curt = (ResolveInfo)receivers.get(it);
12277 }
12278 if (curr == null) {
12279 curr = registeredReceivers.get(ir);
12280 }
12281 if (curr.getPriority() >= curt.priority) {
12282 // Insert this broadcast record into the final list.
12283 receivers.add(it, curr);
12284 ir++;
12285 curr = null;
12286 it++;
12287 NT++;
12288 } else {
12289 // Skip to the next ResolveInfo in the final list.
12290 it++;
12291 curt = null;
12292 }
12293 }
12294 }
12295 while (ir < NR) {
12296 if (receivers == null) {
12297 receivers = new ArrayList();
12298 }
12299 receivers.add(registeredReceivers.get(ir));
12300 ir++;
12301 }
12302
12303 if ((receivers != null && receivers.size() > 0)
12304 || resultTo != null) {
12305 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12306 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012307 receivers, resultTo, resultCode, resultData, map, ordered,
12308 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012309 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 TAG, "Enqueueing ordered broadcast " + r
12311 + ": prev had " + mOrderedBroadcasts.size());
12312 if (DEBUG_BROADCAST) {
12313 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012314 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012315 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012316 boolean replaced = false;
12317 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012318 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012319 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012320 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012321 "***** DROPPING ORDERED: " + intent);
12322 mOrderedBroadcasts.set(i, r);
12323 replaced = true;
12324 break;
12325 }
12326 }
12327 }
12328 if (!replaced) {
12329 mOrderedBroadcasts.add(r);
12330 scheduleBroadcastsLocked();
12331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 }
12333
12334 return BROADCAST_SUCCESS;
12335 }
12336
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012337 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 // Refuse possible leaked file descriptors
12339 if (intent != null && intent.hasFileDescriptors() == true) {
12340 throw new IllegalArgumentException("File descriptors passed in Intent");
12341 }
12342
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012343 int flags = intent.getFlags();
12344
12345 if (!mProcessesReady) {
12346 // if the caller really truly claims to know what they're doing, go
12347 // ahead and allow the broadcast without launching any receivers
12348 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12349 intent = new Intent(intent);
12350 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12351 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12352 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12353 + " before boot completion");
12354 throw new IllegalStateException("Cannot broadcast before boot completed");
12355 }
12356 }
12357
12358 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12359 throw new IllegalArgumentException(
12360 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12361 }
12362
12363 return intent;
12364 }
12365
12366 public final int broadcastIntent(IApplicationThread caller,
12367 Intent intent, String resolvedType, IIntentReceiver resultTo,
12368 int resultCode, String resultData, Bundle map,
12369 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012370 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012371 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012373 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12374 final int callingPid = Binder.getCallingPid();
12375 final int callingUid = Binder.getCallingUid();
12376 final long origId = Binder.clearCallingIdentity();
12377 int res = broadcastIntentLocked(callerApp,
12378 callerApp != null ? callerApp.info.packageName : null,
12379 intent, resolvedType, resultTo,
12380 resultCode, resultData, map, requiredPermission, serialized,
12381 sticky, callingPid, callingUid);
12382 Binder.restoreCallingIdentity(origId);
12383 return res;
12384 }
12385 }
12386
12387 int broadcastIntentInPackage(String packageName, int uid,
12388 Intent intent, String resolvedType, IIntentReceiver resultTo,
12389 int resultCode, String resultData, Bundle map,
12390 String requiredPermission, boolean serialized, boolean sticky) {
12391 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012392 intent = verifyBroadcastLocked(intent);
12393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012394 final long origId = Binder.clearCallingIdentity();
12395 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12396 resultTo, resultCode, resultData, map, requiredPermission,
12397 serialized, sticky, -1, uid);
12398 Binder.restoreCallingIdentity(origId);
12399 return res;
12400 }
12401 }
12402
12403 public final void unbroadcastIntent(IApplicationThread caller,
12404 Intent intent) {
12405 // Refuse possible leaked file descriptors
12406 if (intent != null && intent.hasFileDescriptors() == true) {
12407 throw new IllegalArgumentException("File descriptors passed in Intent");
12408 }
12409
12410 synchronized(this) {
12411 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12412 != PackageManager.PERMISSION_GRANTED) {
12413 String msg = "Permission Denial: unbroadcastIntent() from pid="
12414 + Binder.getCallingPid()
12415 + ", uid=" + Binder.getCallingUid()
12416 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012417 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 throw new SecurityException(msg);
12419 }
12420 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12421 if (list != null) {
12422 int N = list.size();
12423 int i;
12424 for (i=0; i<N; i++) {
12425 if (intent.filterEquals(list.get(i))) {
12426 list.remove(i);
12427 break;
12428 }
12429 }
12430 }
12431 }
12432 }
12433
12434 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12435 String resultData, Bundle resultExtras, boolean resultAbort,
12436 boolean explicit) {
12437 if (mOrderedBroadcasts.size() == 0) {
12438 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012439 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 }
12441 return false;
12442 }
12443 BroadcastRecord r = mOrderedBroadcasts.get(0);
12444 if (r.receiver == null) {
12445 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012446 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012447 }
12448 return false;
12449 }
12450 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012451 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012452 return false;
12453 }
12454 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012455 r.state = BroadcastRecord.IDLE;
12456 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012457 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012458 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 }
12460 }
12461 r.receiver = null;
12462 r.intent.setComponent(null);
12463 if (r.curApp != null) {
12464 r.curApp.curReceiver = null;
12465 }
12466 if (r.curFilter != null) {
12467 r.curFilter.receiverList.curBroadcast = null;
12468 }
12469 r.curFilter = null;
12470 r.curApp = null;
12471 r.curComponent = null;
12472 r.curReceiver = null;
12473 mPendingBroadcast = null;
12474
12475 r.resultCode = resultCode;
12476 r.resultData = resultData;
12477 r.resultExtras = resultExtras;
12478 r.resultAbort = resultAbort;
12479
12480 // We will process the next receiver right now if this is finishing
12481 // an app receiver (which is always asynchronous) or after we have
12482 // come back from calling a receiver.
12483 return state == BroadcastRecord.APP_RECEIVE
12484 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12485 }
12486
12487 public void finishReceiver(IBinder who, int resultCode, String resultData,
12488 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012489 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012490
12491 // Refuse possible leaked file descriptors
12492 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12493 throw new IllegalArgumentException("File descriptors passed in Bundle");
12494 }
12495
12496 boolean doNext;
12497
12498 final long origId = Binder.clearCallingIdentity();
12499
12500 synchronized(this) {
12501 doNext = finishReceiverLocked(
12502 who, resultCode, resultData, resultExtras, resultAbort, true);
12503 }
12504
12505 if (doNext) {
12506 processNextBroadcast(false);
12507 }
12508 trimApplications();
12509
12510 Binder.restoreCallingIdentity(origId);
12511 }
12512
Jeff Brown4d94a762010-09-23 11:33:28 -070012513 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012514 if (r.nextReceiver > 0) {
12515 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12516 if (curReceiver instanceof BroadcastFilter) {
12517 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012518 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012519 System.identityHashCode(r),
12520 r.intent.getAction(),
12521 r.nextReceiver - 1,
12522 System.identityHashCode(bf));
12523 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012524 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012525 System.identityHashCode(r),
12526 r.intent.getAction(),
12527 r.nextReceiver - 1,
12528 ((ResolveInfo)curReceiver).toString());
12529 }
12530 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012531 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012532 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012533 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012534 System.identityHashCode(r),
12535 r.intent.getAction(),
12536 r.nextReceiver,
12537 "NONE");
12538 }
12539 }
12540
Jeff Brown4d94a762010-09-23 11:33:28 -070012541 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12542 if (! mPendingBroadcastTimeoutMessage) {
12543 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12544 mHandler.sendMessageAtTime(msg, timeoutTime);
12545 mPendingBroadcastTimeoutMessage = true;
12546 }
12547 }
12548
12549 private final void cancelBroadcastTimeoutLocked() {
12550 if (mPendingBroadcastTimeoutMessage) {
12551 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12552 mPendingBroadcastTimeoutMessage = false;
12553 }
12554 }
12555
12556 private final void broadcastTimeoutLocked(boolean fromMsg) {
12557 if (fromMsg) {
12558 mPendingBroadcastTimeoutMessage = false;
12559 }
12560
12561 if (mOrderedBroadcasts.size() == 0) {
12562 return;
12563 }
12564
12565 long now = SystemClock.uptimeMillis();
12566 BroadcastRecord r = mOrderedBroadcasts.get(0);
12567 if (fromMsg) {
12568 if (mDidDexOpt) {
12569 // Delay timeouts until dexopt finishes.
12570 mDidDexOpt = false;
12571 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12572 setBroadcastTimeoutLocked(timeoutTime);
12573 return;
12574 }
12575 if (! mProcessesReady) {
12576 // Only process broadcast timeouts if the system is ready. That way
12577 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12578 // to do heavy lifting for system up.
12579 return;
12580 }
12581
12582 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12583 if (timeoutTime > now) {
12584 // We can observe premature timeouts because we do not cancel and reset the
12585 // broadcast timeout message after each receiver finishes. Instead, we set up
12586 // an initial timeout then kick it down the road a little further as needed
12587 // when it expires.
12588 if (DEBUG_BROADCAST) Slog.v(TAG,
12589 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12590 + timeoutTime);
12591 setBroadcastTimeoutLocked(timeoutTime);
12592 return;
12593 }
12594 }
12595
12596 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12597 + ", started " + (now - r.receiverTime) + "ms ago");
12598 r.receiverTime = now;
12599 r.anrCount++;
12600
12601 // Current receiver has passed its expiration date.
12602 if (r.nextReceiver <= 0) {
12603 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12604 return;
12605 }
12606
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012607 ProcessRecord app = null;
12608 String anrMessage = null;
12609
Jeff Brown4d94a762010-09-23 11:33:28 -070012610 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12611 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12612 logBroadcastReceiverDiscardLocked(r);
12613 if (curReceiver instanceof BroadcastFilter) {
12614 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12615 if (bf.receiverList.pid != 0
12616 && bf.receiverList.pid != MY_PID) {
12617 synchronized (this.mPidsSelfLocked) {
12618 app = this.mPidsSelfLocked.get(
12619 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012621 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012622 } else {
12623 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012624 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012625
Jeff Brown4d94a762010-09-23 11:33:28 -070012626 if (app != null) {
12627 anrMessage = "Broadcast of " + r.intent.toString();
12628 }
12629
12630 if (mPendingBroadcast == r) {
12631 mPendingBroadcast = null;
12632 }
12633
12634 // Move on to the next receiver.
12635 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12636 r.resultExtras, r.resultAbort, true);
12637 scheduleBroadcastsLocked();
12638
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012639 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012640 // Post the ANR to the handler since we do not want to process ANRs while
12641 // potentially holding our lock.
12642 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012644 }
12645
12646 private final void processCurBroadcastLocked(BroadcastRecord r,
12647 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012648 if (DEBUG_BROADCAST) Slog.v(TAG,
12649 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012650 if (app.thread == null) {
12651 throw new RemoteException();
12652 }
12653 r.receiver = app.thread.asBinder();
12654 r.curApp = app;
12655 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012656 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012657
12658 // Tell the application to launch this receiver.
12659 r.intent.setComponent(r.curComponent);
12660
12661 boolean started = false;
12662 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012663 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012664 "Delivering to component " + r.curComponent
12665 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012666 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012667 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012668 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012669 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012670 if (DEBUG_BROADCAST) Slog.v(TAG,
12671 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012672 started = true;
12673 } finally {
12674 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012675 if (DEBUG_BROADCAST) Slog.v(TAG,
12676 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012677 r.receiver = null;
12678 r.curApp = null;
12679 app.curReceiver = null;
12680 }
12681 }
12682
12683 }
12684
Jeff Brown4d94a762010-09-23 11:33:28 -070012685 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012686 Intent intent, int resultCode, String data, Bundle extras,
12687 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012688 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012689 if (app != null && app.thread != null) {
12690 // If we have an app thread, do the call through that so it is
12691 // correctly ordered with other one-way calls.
12692 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012693 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012695 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012696 }
12697 }
12698
Jeff Brown4d94a762010-09-23 11:33:28 -070012699 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 BroadcastFilter filter, boolean ordered) {
12701 boolean skip = false;
12702 if (filter.requiredPermission != null) {
12703 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012704 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012705 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012706 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012707 + r.intent.toString()
12708 + " from " + r.callerPackage + " (pid="
12709 + r.callingPid + ", uid=" + r.callingUid + ")"
12710 + " requires " + filter.requiredPermission
12711 + " due to registered receiver " + filter);
12712 skip = true;
12713 }
12714 }
12715 if (r.requiredPermission != null) {
12716 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012717 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012718 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012719 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012720 + r.intent.toString()
12721 + " to " + filter.receiverList.app
12722 + " (pid=" + filter.receiverList.pid
12723 + ", uid=" + filter.receiverList.uid + ")"
12724 + " requires " + r.requiredPermission
12725 + " due to sender " + r.callerPackage
12726 + " (uid " + r.callingUid + ")");
12727 skip = true;
12728 }
12729 }
12730
12731 if (!skip) {
12732 // If this is not being sent as an ordered broadcast, then we
12733 // don't want to touch the fields that keep track of the current
12734 // state of ordered broadcasts.
12735 if (ordered) {
12736 r.receiver = filter.receiverList.receiver.asBinder();
12737 r.curFilter = filter;
12738 filter.receiverList.curBroadcast = r;
12739 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012740 if (filter.receiverList.app != null) {
12741 // Bump hosting application to no longer be in background
12742 // scheduling class. Note that we can't do that if there
12743 // isn't an app... but we can only be in that case for
12744 // things that directly call the IActivityManager API, which
12745 // are already core system stuff so don't matter for this.
12746 r.curApp = filter.receiverList.app;
12747 filter.receiverList.app.curReceiver = r;
12748 updateOomAdjLocked();
12749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012750 }
12751 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012752 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012754 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012755 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012756 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012757 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012759 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012760 if (ordered) {
12761 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12762 }
12763 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012764 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012765 if (ordered) {
12766 r.receiver = null;
12767 r.curFilter = null;
12768 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012769 if (filter.receiverList.app != null) {
12770 filter.receiverList.app.curReceiver = null;
12771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012772 }
12773 }
12774 }
12775 }
12776
Dianne Hackborn12527f92009-11-11 17:39:50 -080012777 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12778 if (r.callingUid < 0) {
12779 // This was from a registerReceiver() call; ignore it.
12780 return;
12781 }
12782 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12783 MAX_BROADCAST_HISTORY-1);
12784 r.finishTime = SystemClock.uptimeMillis();
12785 mBroadcastHistory[0] = r;
12786 }
12787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012788 private final void processNextBroadcast(boolean fromMsg) {
12789 synchronized(this) {
12790 BroadcastRecord r;
12791
Joe Onorato8a9b2202010-02-26 18:56:32 -080012792 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012793 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012794 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012795
12796 updateCpuStats();
12797
12798 if (fromMsg) {
12799 mBroadcastsScheduled = false;
12800 }
12801
12802 // First, deliver any non-serialized broadcasts right away.
12803 while (mParallelBroadcasts.size() > 0) {
12804 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012805 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012806 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012807 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012808 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012809 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012810 for (int i=0; i<N; i++) {
12811 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012812 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012813 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012814 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012815 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012816 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012817 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012818 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012819 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012820 }
12821
12822 // Now take care of the next serialized one...
12823
12824 // If we are waiting for a process to come up to handle the next
12825 // broadcast, then do nothing at this point. Just in case, we
12826 // check that the process we're waiting for still exists.
12827 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012828 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012829 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012830 + mPendingBroadcast.curApp);
12831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832
12833 boolean isDead;
12834 synchronized (mPidsSelfLocked) {
12835 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12836 }
12837 if (!isDead) {
12838 // It's still alive, so keep waiting
12839 return;
12840 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012841 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012842 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012843 mPendingBroadcast.state = BroadcastRecord.IDLE;
12844 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845 mPendingBroadcast = null;
12846 }
12847 }
12848
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012849 boolean looped = false;
12850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012851 do {
12852 if (mOrderedBroadcasts.size() == 0) {
12853 // No more broadcasts pending, so all done!
12854 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012855 if (looped) {
12856 // If we had finished the last ordered broadcast, then
12857 // make sure all processes have correct oom and sched
12858 // adjustments.
12859 updateOomAdjLocked();
12860 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012861 return;
12862 }
12863 r = mOrderedBroadcasts.get(0);
12864 boolean forceReceive = false;
12865
12866 // Ensure that even if something goes awry with the timeout
12867 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012868 // and continue to make progress.
12869 //
12870 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012871 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012872 // one time heavy lifting after system upgrades and can take
12873 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012874 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012875 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012876 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012877 if ((numReceivers > 0) &&
12878 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012879 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012880 + " now=" + now
12881 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012882 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012883 + " intent=" + r.intent
12884 + " numReceivers=" + numReceivers
12885 + " nextReceiver=" + r.nextReceiver
12886 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012887 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012888 forceReceive = true;
12889 r.state = BroadcastRecord.IDLE;
12890 }
12891 }
12892
12893 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012894 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012895 "processNextBroadcast() called when not idle (state="
12896 + r.state + ")");
12897 return;
12898 }
12899
12900 if (r.receivers == null || r.nextReceiver >= numReceivers
12901 || r.resultAbort || forceReceive) {
12902 // No more receivers for this broadcast! Send the final
12903 // result if requested...
12904 if (r.resultTo != null) {
12905 try {
12906 if (DEBUG_BROADCAST) {
12907 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012908 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012909 + " seq=" + seq + " app=" + r.callerApp);
12910 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012911 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012912 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012913 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012914 // Set this to null so that the reference
12915 // (local and remote) isnt kept in the mBroadcastHistory.
12916 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012917 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012918 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012919 }
12920 }
12921
Joe Onorato8a9b2202010-02-26 18:56:32 -080012922 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012923 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012924
Joe Onorato8a9b2202010-02-26 18:56:32 -080012925 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012926 + r);
12927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012928 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012929 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012930 mOrderedBroadcasts.remove(0);
12931 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012932 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012933 continue;
12934 }
12935 } while (r == null);
12936
12937 // Get the next receiver...
12938 int recIdx = r.nextReceiver++;
12939
12940 // Keep track of when this receiver started, and make sure there
12941 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012942 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012944 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012945 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012946 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012947 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012948 }
12949 if (! mPendingBroadcastTimeoutMessage) {
12950 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012951 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012952 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12953 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012954 }
12955
12956 Object nextReceiver = r.receivers.get(recIdx);
12957 if (nextReceiver instanceof BroadcastFilter) {
12958 // Simple case: this is a registered receiver who gets
12959 // a direct call.
12960 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012961 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012962 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012964 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012965 if (r.receiver == null || !r.ordered) {
12966 // The receiver has already finished, so schedule to
12967 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012968 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12969 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012970 r.state = BroadcastRecord.IDLE;
12971 scheduleBroadcastsLocked();
12972 }
12973 return;
12974 }
12975
12976 // Hard case: need to instantiate the receiver, possibly
12977 // starting its application process to host it.
12978
12979 ResolveInfo info =
12980 (ResolveInfo)nextReceiver;
12981
12982 boolean skip = false;
12983 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012984 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12985 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012986 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012987 if (!info.activityInfo.exported) {
12988 Slog.w(TAG, "Permission Denial: broadcasting "
12989 + r.intent.toString()
12990 + " from " + r.callerPackage + " (pid=" + r.callingPid
12991 + ", uid=" + r.callingUid + ")"
12992 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12993 + " due to receiver " + info.activityInfo.packageName
12994 + "/" + info.activityInfo.name);
12995 } else {
12996 Slog.w(TAG, "Permission Denial: broadcasting "
12997 + r.intent.toString()
12998 + " from " + r.callerPackage + " (pid=" + r.callingPid
12999 + ", uid=" + r.callingUid + ")"
13000 + " requires " + info.activityInfo.permission
13001 + " due to receiver " + info.activityInfo.packageName
13002 + "/" + info.activityInfo.name);
13003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 skip = true;
13005 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013006 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007 r.requiredPermission != null) {
13008 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013009 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013010 checkPermission(r.requiredPermission,
13011 info.activityInfo.applicationInfo.packageName);
13012 } catch (RemoteException e) {
13013 perm = PackageManager.PERMISSION_DENIED;
13014 }
13015 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013016 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017 + r.intent + " to "
13018 + info.activityInfo.applicationInfo.packageName
13019 + " requires " + r.requiredPermission
13020 + " due to sender " + r.callerPackage
13021 + " (uid " + r.callingUid + ")");
13022 skip = true;
13023 }
13024 }
13025 if (r.curApp != null && r.curApp.crashing) {
13026 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013027 if (DEBUG_BROADCAST) Slog.v(TAG,
13028 "Skipping deliver ordered " + r + " to " + r.curApp
13029 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013030 skip = true;
13031 }
13032
13033 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013034 if (DEBUG_BROADCAST) Slog.v(TAG,
13035 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013036 r.receiver = null;
13037 r.curFilter = null;
13038 r.state = BroadcastRecord.IDLE;
13039 scheduleBroadcastsLocked();
13040 return;
13041 }
13042
13043 r.state = BroadcastRecord.APP_RECEIVE;
13044 String targetProcess = info.activityInfo.processName;
13045 r.curComponent = new ComponentName(
13046 info.activityInfo.applicationInfo.packageName,
13047 info.activityInfo.name);
13048 r.curReceiver = info.activityInfo;
13049
Dianne Hackborne7f97212011-02-24 14:40:20 -080013050 // Broadcast is being executed, its package can't be stopped.
13051 try {
13052 AppGlobals.getPackageManager().setPackageStoppedState(
13053 r.curComponent.getPackageName(), false);
13054 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080013055 } catch (IllegalArgumentException e) {
13056 Slog.w(TAG, "Failed trying to unstop package "
13057 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080013058 }
13059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013060 // Is this receiver's application already running?
13061 ProcessRecord app = getProcessRecordLocked(targetProcess,
13062 info.activityInfo.applicationInfo.uid);
13063 if (app != null && app.thread != null) {
13064 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013065 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013066 processCurBroadcastLocked(r, app);
13067 return;
13068 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013069 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013070 + r.curComponent, e);
13071 }
13072
13073 // If a dead object exception was thrown -- fall through to
13074 // restart the application.
13075 }
13076
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013077 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013078 if (DEBUG_BROADCAST) Slog.v(TAG,
13079 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013080 if ((r.curApp=startProcessLocked(targetProcess,
13081 info.activityInfo.applicationInfo, true,
13082 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013083 "broadcast", r.curComponent,
13084 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13085 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013086 // Ah, this recipient is unavailable. Finish it if necessary,
13087 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013088 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013089 + info.activityInfo.applicationInfo.packageName + "/"
13090 + info.activityInfo.applicationInfo.uid + " for broadcast "
13091 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070013092 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013093 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13094 r.resultExtras, r.resultAbort, true);
13095 scheduleBroadcastsLocked();
13096 r.state = BroadcastRecord.IDLE;
13097 return;
13098 }
13099
13100 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013101 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013102 }
13103 }
13104
13105 // =========================================================
13106 // INSTRUMENTATION
13107 // =========================================================
13108
13109 public boolean startInstrumentation(ComponentName className,
13110 String profileFile, int flags, Bundle arguments,
13111 IInstrumentationWatcher watcher) {
13112 // Refuse possible leaked file descriptors
13113 if (arguments != null && arguments.hasFileDescriptors()) {
13114 throw new IllegalArgumentException("File descriptors passed in Bundle");
13115 }
13116
13117 synchronized(this) {
13118 InstrumentationInfo ii = null;
13119 ApplicationInfo ai = null;
13120 try {
13121 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013122 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013123 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013124 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013125 } catch (PackageManager.NameNotFoundException e) {
13126 }
13127 if (ii == null) {
13128 reportStartInstrumentationFailure(watcher, className,
13129 "Unable to find instrumentation info for: " + className);
13130 return false;
13131 }
13132 if (ai == null) {
13133 reportStartInstrumentationFailure(watcher, className,
13134 "Unable to find instrumentation target package: " + ii.targetPackage);
13135 return false;
13136 }
13137
13138 int match = mContext.getPackageManager().checkSignatures(
13139 ii.targetPackage, ii.packageName);
13140 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13141 String msg = "Permission Denial: starting instrumentation "
13142 + className + " from pid="
13143 + Binder.getCallingPid()
13144 + ", uid=" + Binder.getCallingPid()
13145 + " not allowed because package " + ii.packageName
13146 + " does not have a signature matching the target "
13147 + ii.targetPackage;
13148 reportStartInstrumentationFailure(watcher, className, msg);
13149 throw new SecurityException(msg);
13150 }
13151
13152 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013153 // Instrumentation can kill and relaunch even persistent processes
13154 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 ProcessRecord app = addAppLocked(ai);
13156 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013157 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013158 app.instrumentationProfileFile = profileFile;
13159 app.instrumentationArguments = arguments;
13160 app.instrumentationWatcher = watcher;
13161 app.instrumentationResultClass = className;
13162 Binder.restoreCallingIdentity(origId);
13163 }
13164
13165 return true;
13166 }
13167
13168 /**
13169 * Report errors that occur while attempting to start Instrumentation. Always writes the
13170 * error to the logs, but if somebody is watching, send the report there too. This enables
13171 * the "am" command to report errors with more information.
13172 *
13173 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13174 * @param cn The component name of the instrumentation.
13175 * @param report The error report.
13176 */
13177 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13178 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013179 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013180 try {
13181 if (watcher != null) {
13182 Bundle results = new Bundle();
13183 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13184 results.putString("Error", report);
13185 watcher.instrumentationStatus(cn, -1, results);
13186 }
13187 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013188 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013189 }
13190 }
13191
13192 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13193 if (app.instrumentationWatcher != null) {
13194 try {
13195 // NOTE: IInstrumentationWatcher *must* be oneway here
13196 app.instrumentationWatcher.instrumentationFinished(
13197 app.instrumentationClass,
13198 resultCode,
13199 results);
13200 } catch (RemoteException e) {
13201 }
13202 }
13203 app.instrumentationWatcher = null;
13204 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013205 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013206 app.instrumentationProfileFile = null;
13207 app.instrumentationArguments = null;
13208
Christopher Tate3dacd842011-08-19 14:56:15 -070013209 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013210 }
13211
13212 public void finishInstrumentation(IApplicationThread target,
13213 int resultCode, Bundle results) {
13214 // Refuse possible leaked file descriptors
13215 if (results != null && results.hasFileDescriptors()) {
13216 throw new IllegalArgumentException("File descriptors passed in Intent");
13217 }
13218
13219 synchronized(this) {
13220 ProcessRecord app = getRecordForAppLocked(target);
13221 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013222 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013223 return;
13224 }
13225 final long origId = Binder.clearCallingIdentity();
13226 finishInstrumentationLocked(app, resultCode, results);
13227 Binder.restoreCallingIdentity(origId);
13228 }
13229 }
13230
13231 // =========================================================
13232 // CONFIGURATION
13233 // =========================================================
13234
13235 public ConfigurationInfo getDeviceConfigurationInfo() {
13236 ConfigurationInfo config = new ConfigurationInfo();
13237 synchronized (this) {
13238 config.reqTouchScreen = mConfiguration.touchscreen;
13239 config.reqKeyboardType = mConfiguration.keyboard;
13240 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013241 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13242 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013243 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13244 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013245 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13246 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013247 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13248 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013249 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013250 }
13251 return config;
13252 }
13253
13254 public Configuration getConfiguration() {
13255 Configuration ci;
13256 synchronized(this) {
13257 ci = new Configuration(mConfiguration);
13258 }
13259 return ci;
13260 }
13261
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013262 public void updatePersistentConfiguration(Configuration values) {
13263 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13264 "updateConfiguration()");
13265 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13266 "updateConfiguration()");
13267 if (values == null) {
13268 throw new NullPointerException("Configuration must not be null");
13269 }
13270
13271 synchronized(this) {
13272 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013273 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013274 Binder.restoreCallingIdentity(origId);
13275 }
13276 }
13277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 public void updateConfiguration(Configuration values) {
13279 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13280 "updateConfiguration()");
13281
13282 synchronized(this) {
13283 if (values == null && mWindowManager != null) {
13284 // sentinel: fetch the current configuration from the window manager
13285 values = mWindowManager.computeNewConfiguration();
13286 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013287
13288 if (mWindowManager != null) {
13289 mProcessList.applyDisplaySize(mWindowManager);
13290 }
13291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013293 if (values != null) {
13294 Settings.System.clearConfiguration(values);
13295 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013296 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013297 Binder.restoreCallingIdentity(origId);
13298 }
13299 }
13300
13301 /**
13302 * Do either or both things: (1) change the current configuration, and (2)
13303 * make sure the given activity is running with the (now) current
13304 * configuration. Returns true if the activity has been left running, or
13305 * false if <var>starting</var> is being destroyed to match the new
13306 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013307 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013308 */
13309 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013310 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013311 int changes = 0;
13312
13313 boolean kept = true;
13314
13315 if (values != null) {
13316 Configuration newConfig = new Configuration(mConfiguration);
13317 changes = newConfig.updateFrom(values);
13318 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013319 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013320 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013321 }
13322
Doug Zongker2bec3d42009-12-04 12:52:44 -080013323 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013324
Dianne Hackborn813075a62011-11-14 17:45:19 -080013325 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013326 saveLocaleLocked(values.locale,
13327 !values.locale.equals(mConfiguration.locale),
13328 values.userSetLocale);
13329 }
13330
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013331 mConfigurationSeq++;
13332 if (mConfigurationSeq <= 0) {
13333 mConfigurationSeq = 1;
13334 }
13335 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013336 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013337 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013338
13339 final Configuration configCopy = new Configuration(mConfiguration);
13340
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013341 AttributeCache ac = AttributeCache.instance();
13342 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013343 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013345
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013346 // Make sure all resources in our process are updated
13347 // right now, so that anyone who is going to retrieve
13348 // resource values after we return will be sure to get
13349 // the new ones. This is especially important during
13350 // boot, where the first config change needs to guarantee
13351 // all resources have that config before following boot
13352 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013353 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013354
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013355 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013356 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013357 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013358 mHandler.sendMessage(msg);
13359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013360
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013361 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13362 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013363 try {
13364 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013365 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013366 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013367 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013368 }
13369 } catch (Exception e) {
13370 }
13371 }
13372 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013373 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13374 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013375 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13376 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013377 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13378 broadcastIntentLocked(null, null,
13379 new Intent(Intent.ACTION_LOCALE_CHANGED),
13380 null, null, 0, null, null,
13381 null, false, false, MY_PID, Process.SYSTEM_UID);
13382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013383 }
13384 }
13385
13386 if (changes != 0 && starting == null) {
13387 // If the configuration changed, and the caller is not already
13388 // in the process of starting an activity, then find the top
13389 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013390 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013391 }
13392
13393 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013394 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013395 // And we need to make sure at this point that all other activities
13396 // are made visible with the correct configuration.
13397 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013398 }
13399
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013400 if (values != null && mWindowManager != null) {
13401 mWindowManager.setNewConfiguration(mConfiguration);
13402 }
13403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013404 return kept;
13405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013406
13407 /**
13408 * Save the locale. You must be inside a synchronized (this) block.
13409 */
13410 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13411 if(isDiff) {
13412 SystemProperties.set("user.language", l.getLanguage());
13413 SystemProperties.set("user.region", l.getCountry());
13414 }
13415
13416 if(isPersist) {
13417 SystemProperties.set("persist.sys.language", l.getLanguage());
13418 SystemProperties.set("persist.sys.country", l.getCountry());
13419 SystemProperties.set("persist.sys.localevar", l.getVariant());
13420 }
13421 }
13422
13423 // =========================================================
13424 // LIFETIME MANAGEMENT
13425 // =========================================================
13426
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013427 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013428 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013429 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013430 // This adjustment has already been computed. If we are calling
13431 // from the top, we may have already computed our adjustment with
13432 // an earlier hidden adjustment that isn't really for us... if
13433 // so, use the new hidden adjustment.
13434 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013435 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013436 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013437 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013438 }
13439
13440 if (app.thread == null) {
13441 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013442 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013443 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013444 }
13445
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013446 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13447 app.adjSource = null;
13448 app.adjTarget = null;
13449 app.empty = false;
13450 app.hidden = false;
13451
13452 final int activitiesSize = app.activities.size();
13453
Dianne Hackborn7d608422011-08-07 16:24:18 -070013454 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013455 // The max adjustment doesn't allow this app to be anything
13456 // below foreground, so it is not worth doing work for it.
13457 app.adjType = "fixed";
13458 app.adjSeq = mAdjSeq;
13459 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013460 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013461 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013462 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013463 // System process can do UI, and when they do we want to have
13464 // them trim their memory after the user leaves the UI. To
13465 // facilitate this, here we need to determine whether or not it
13466 // is currently showing UI.
13467 app.systemNoUi = true;
13468 if (app == TOP_APP) {
13469 app.systemNoUi = false;
13470 } else if (activitiesSize > 0) {
13471 for (int j = 0; j < activitiesSize; j++) {
13472 final ActivityRecord r = app.activities.get(j);
13473 if (r.visible) {
13474 app.systemNoUi = false;
13475 break;
13476 }
13477 }
13478 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013479 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013480 }
13481
13482 final boolean hadForegroundActivities = app.foregroundActivities;
13483
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013484 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013485 app.keeping = false;
13486 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013487
The Android Open Source Project4df24232009-03-05 14:34:35 -080013488 // Determine the importance of the process, starting with most
13489 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013490 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013491 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013492 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013493 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013494 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013495 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013496 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013497 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013498 } else if (app.instrumentationClass != null) {
13499 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013500 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013501 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013502 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013503 } else if (app.curReceiver != null ||
13504 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13505 // An app that is currently receiving a broadcast also
13506 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013507 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013508 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013509 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013510 } else if (app.executingServices.size() > 0) {
13511 // An app that is currently executing a service callback also
13512 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013513 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013514 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013515 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013516 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013518 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013519 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013520 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013521 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013522 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013523 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013524 // A very not-needed process. If this is lower in the lru list,
13525 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013526 adj = hiddenAdj;
13527 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013528 app.hidden = true;
13529 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013530 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013532
13533 // Examine all activities if not already foreground.
13534 if (!app.foregroundActivities && activitiesSize > 0) {
13535 for (int j = 0; j < activitiesSize; j++) {
13536 final ActivityRecord r = app.activities.get(j);
13537 if (r.visible) {
13538 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013539 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13540 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013541 app.adjType = "visible";
13542 }
13543 schedGroup = Process.THREAD_GROUP_DEFAULT;
13544 app.hidden = false;
13545 app.foregroundActivities = true;
13546 break;
13547 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13548 || r.state == ActivityState.STOPPING) {
13549 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013550 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13551 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013552 app.adjType = "stopping";
13553 }
13554 app.foregroundActivities = true;
13555 }
13556 }
13557 }
13558
Dianne Hackborn7d608422011-08-07 16:24:18 -070013559 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013560 if (app.foregroundServices) {
13561 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013562 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013563 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013564 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013565 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013566 } else if (app.forcingToForeground != null) {
13567 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013568 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013569 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013570 app.adjType = "force-foreground";
13571 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013572 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013573 }
13574 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013575
Dianne Hackborn7d608422011-08-07 16:24:18 -070013576 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013577 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013578 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013579 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013580 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013581 app.adjType = "heavy";
13582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013583
Dianne Hackborn7d608422011-08-07 16:24:18 -070013584 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013585 // This process is hosting what we currently consider to be the
13586 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013587 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013588 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013589 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013590 app.adjType = "home";
13591 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013592
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013593 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13594 && app.activities.size() > 0) {
13595 // This was the previous process that showed UI to the user.
13596 // We want to try to keep it around more aggressively, to give
13597 // a good experience around switching between two apps.
13598 adj = ProcessList.PREVIOUS_APP_ADJ;
13599 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13600 app.hidden = false;
13601 app.adjType = "previous";
13602 }
13603
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013604 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13605 + " reason=" + app.adjType);
13606
The Android Open Source Project4df24232009-03-05 14:34:35 -080013607 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013608 // there are applications dependent on our services or providers, but
13609 // this gives us a baseline and makes sure we don't get into an
13610 // infinite recursion.
13611 app.adjSeq = mAdjSeq;
13612 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013613
Christopher Tate6fa95972009-06-05 18:43:55 -070013614 if (mBackupTarget != null && app == mBackupTarget.app) {
13615 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013616 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013617 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013618 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013619 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013620 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013621 }
13622 }
13623
Dianne Hackborn7d608422011-08-07 16:24:18 -070013624 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013625 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013626 final long now = SystemClock.uptimeMillis();
13627 // This process is more important if the top activity is
13628 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013629 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013630 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013631 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013632 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013633 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013634 // If this process has shown some UI, let it immediately
13635 // go to the LRU list because it may be pretty heavy with
13636 // UI stuff. We'll tag it with a label just to help
13637 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013638 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013639 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013640 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013641 } else {
13642 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13643 // This service has seen some activity within
13644 // recent memory, so we will keep its process ahead
13645 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013646 if (adj > ProcessList.SERVICE_ADJ) {
13647 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013648 app.adjType = "started-services";
13649 app.hidden = false;
13650 }
13651 }
13652 // If we have let the service slide into the background
13653 // state, still have some text describing what it is doing
13654 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013655 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013656 app.adjType = "started-bg-services";
13657 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013658 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013659 // Don't kill this process because it is doing work; it
13660 // has said it is doing work.
13661 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013662 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013663 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013664 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013665 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013666 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013667 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013668 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013669 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013670 // XXX should compute this based on the max of
13671 // all connected clients.
13672 ConnectionRecord cr = clist.get(i);
13673 if (cr.binding.client == app) {
13674 // Binding to ourself is not interesting.
13675 continue;
13676 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013677 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013678 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013679 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013680 int myHiddenAdj = hiddenAdj;
13681 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013682 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013683 myHiddenAdj = client.hiddenAdj;
13684 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013685 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013686 }
13687 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013688 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013689 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013690 String adjType = null;
13691 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13692 // Not doing bind OOM management, so treat
13693 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013694 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013695 // If this process has shown some UI, let it immediately
13696 // go to the LRU list because it may be pretty heavy with
13697 // UI stuff. We'll tag it with a label just to help
13698 // debug and understand what is going on.
13699 if (adj > clientAdj) {
13700 adjType = "bound-bg-ui-services";
13701 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013702 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013703 clientAdj = adj;
13704 } else {
13705 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13706 // This service has not seen activity within
13707 // recent memory, so allow it to drop to the
13708 // LRU list if there is no other reason to keep
13709 // it around. We'll also tag it with a label just
13710 // to help debug and undertand what is going on.
13711 if (adj > clientAdj) {
13712 adjType = "bound-bg-services";
13713 }
13714 clientAdj = adj;
13715 }
13716 }
13717 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013718 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013719 // If this process has recently shown UI, and
13720 // the process that is binding to it is less
13721 // important than being visible, then we don't
13722 // care about the binding as much as we care
13723 // about letting this process get into the LRU
13724 // list to be killed and restarted if needed for
13725 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013726 if (app.hasShownUi && app != mHomeProcess
13727 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013728 adjType = "bound-bg-ui-services";
13729 } else {
13730 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13731 |Context.BIND_IMPORTANT)) != 0) {
13732 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013733 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13734 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13735 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13736 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13737 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013738 adj = clientAdj;
13739 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013740 app.pendingUiClean = true;
13741 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13742 adj = ProcessList.VISIBLE_APP_ADJ;
13743 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013744 }
13745 if (!client.hidden) {
13746 app.hidden = false;
13747 }
13748 if (client.keeping) {
13749 app.keeping = true;
13750 }
13751 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013752 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013753 }
13754 if (adjType != null) {
13755 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013756 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13757 .REASON_SERVICE_IN_USE;
13758 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013759 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013760 app.adjTarget = s.name;
13761 }
13762 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13763 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13764 schedGroup = Process.THREAD_GROUP_DEFAULT;
13765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013766 }
13767 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013768 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13769 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013770 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013771 (a.visible || a.state == ActivityState.RESUMED
13772 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013773 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013774 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13775 schedGroup = Process.THREAD_GROUP_DEFAULT;
13776 }
13777 app.hidden = false;
13778 app.adjType = "service";
13779 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13780 .REASON_SERVICE_IN_USE;
13781 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013782 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013783 app.adjTarget = s.name;
13784 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013786 }
13787 }
13788 }
13789 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013790
Dianne Hackborn287952c2010-09-22 22:34:31 -070013791 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013792 // would like to avoid killing it unless it would prevent the current
13793 // application from running. By default we put the process in
13794 // with the rest of the background processes; as we scan through
13795 // its services we may bump it up from there.
13796 if (adj > hiddenAdj) {
13797 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013798 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013799 app.adjType = "bg-services";
13800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013801 }
13802
Dianne Hackborn7d608422011-08-07 16:24:18 -070013803 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013804 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013805 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013806 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013807 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013808 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013809 if (cpr.clients.size() != 0) {
13810 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013811 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013812 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013813 if (client == app) {
13814 // Being our own client is not interesting.
13815 continue;
13816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013817 int myHiddenAdj = hiddenAdj;
13818 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013819 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013820 myHiddenAdj = client.hiddenAdj;
13821 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013822 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013823 }
13824 }
13825 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013826 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013827 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013828 if (app.hasShownUi && app != mHomeProcess
13829 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013830 app.adjType = "bg-ui-provider";
13831 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013832 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13833 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013834 app.adjType = "provider";
13835 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013836 if (!client.hidden) {
13837 app.hidden = false;
13838 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013839 if (client.keeping) {
13840 app.keeping = true;
13841 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013842 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13843 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013844 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013845 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013846 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013847 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013848 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13849 schedGroup = Process.THREAD_GROUP_DEFAULT;
13850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013851 }
13852 }
13853 // If the provider has external (non-framework) process
13854 // dependencies, ensure that its adjustment is at least
13855 // FOREGROUND_APP_ADJ.
13856 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013857 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13858 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013859 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013860 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013861 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013862 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013863 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013864 }
13865 }
13866 }
13867 }
13868
13869 app.curRawAdj = adj;
13870
Joe Onorato8a9b2202010-02-26 18:56:32 -080013871 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013872 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13873 if (adj > app.maxAdj) {
13874 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013875 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013876 schedGroup = Process.THREAD_GROUP_DEFAULT;
13877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013878 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013879 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013880 app.keeping = true;
13881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013882
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013883 if (app.hasAboveClient) {
13884 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13885 // then we need to drop its adjustment to be lower than the service's
13886 // in order to honor the request. We want to drop it by one adjustment
13887 // level... but there is special meaning applied to various levels so
13888 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013889 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013890 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013891 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13892 adj = ProcessList.VISIBLE_APP_ADJ;
13893 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13894 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13895 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13896 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013897 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013898 adj++;
13899 }
13900 }
13901
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013902 if (adj == ProcessList.SERVICE_ADJ) {
13903 if (doingAll) {
13904 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13905 mNewNumServiceProcs++;
13906 }
13907 if (app.serviceb) {
13908 adj = ProcessList.SERVICE_B_ADJ;
13909 }
13910 } else {
13911 app.serviceb = false;
13912 }
13913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013914 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013915 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013916
13917 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013918 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13919 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013920 }
13921
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013922 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013923 }
13924
13925 /**
13926 * Ask a given process to GC right now.
13927 */
13928 final void performAppGcLocked(ProcessRecord app) {
13929 try {
13930 app.lastRequestedGc = SystemClock.uptimeMillis();
13931 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013932 if (app.reportLowMemory) {
13933 app.reportLowMemory = false;
13934 app.thread.scheduleLowMemory();
13935 } else {
13936 app.thread.processInBackground();
13937 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013938 }
13939 } catch (Exception e) {
13940 // whatever.
13941 }
13942 }
13943
13944 /**
13945 * Returns true if things are idle enough to perform GCs.
13946 */
Josh Bartel7f208742010-02-25 11:01:44 -060013947 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013948 return mParallelBroadcasts.size() == 0
13949 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013950 && (mSleeping || (mMainStack.mResumedActivity != null &&
13951 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013952 }
13953
13954 /**
13955 * Perform GCs on all processes that are waiting for it, but only
13956 * if things are idle.
13957 */
13958 final void performAppGcsLocked() {
13959 final int N = mProcessesToGc.size();
13960 if (N <= 0) {
13961 return;
13962 }
Josh Bartel7f208742010-02-25 11:01:44 -060013963 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013964 while (mProcessesToGc.size() > 0) {
13965 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013966 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013967 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13968 <= SystemClock.uptimeMillis()) {
13969 // To avoid spamming the system, we will GC processes one
13970 // at a time, waiting a few seconds between each.
13971 performAppGcLocked(proc);
13972 scheduleAppGcsLocked();
13973 return;
13974 } else {
13975 // It hasn't been long enough since we last GCed this
13976 // process... put it in the list to wait for its time.
13977 addProcessToGcListLocked(proc);
13978 break;
13979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013980 }
13981 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013982
13983 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013984 }
13985 }
13986
13987 /**
13988 * If all looks good, perform GCs on all processes waiting for them.
13989 */
13990 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013991 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013992 performAppGcsLocked();
13993 return;
13994 }
13995 // Still not idle, wait some more.
13996 scheduleAppGcsLocked();
13997 }
13998
13999 /**
14000 * Schedule the execution of all pending app GCs.
14001 */
14002 final void scheduleAppGcsLocked() {
14003 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014004
14005 if (mProcessesToGc.size() > 0) {
14006 // Schedule a GC for the time to the next process.
14007 ProcessRecord proc = mProcessesToGc.get(0);
14008 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14009
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014010 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014011 long now = SystemClock.uptimeMillis();
14012 if (when < (now+GC_TIMEOUT)) {
14013 when = now + GC_TIMEOUT;
14014 }
14015 mHandler.sendMessageAtTime(msg, when);
14016 }
14017 }
14018
14019 /**
14020 * Add a process to the array of processes waiting to be GCed. Keeps the
14021 * list in sorted order by the last GC time. The process can't already be
14022 * on the list.
14023 */
14024 final void addProcessToGcListLocked(ProcessRecord proc) {
14025 boolean added = false;
14026 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14027 if (mProcessesToGc.get(i).lastRequestedGc <
14028 proc.lastRequestedGc) {
14029 added = true;
14030 mProcessesToGc.add(i+1, proc);
14031 break;
14032 }
14033 }
14034 if (!added) {
14035 mProcessesToGc.add(0, proc);
14036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014037 }
14038
14039 /**
14040 * Set up to ask a process to GC itself. This will either do it
14041 * immediately, or put it on the list of processes to gc the next
14042 * time things are idle.
14043 */
14044 final void scheduleAppGcLocked(ProcessRecord app) {
14045 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014046 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014047 return;
14048 }
14049 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014050 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014051 scheduleAppGcsLocked();
14052 }
14053 }
14054
Dianne Hackborn287952c2010-09-22 22:34:31 -070014055 final void checkExcessivePowerUsageLocked(boolean doKills) {
14056 updateCpuStatsNow();
14057
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014058 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014059 boolean doWakeKills = doKills;
14060 boolean doCpuKills = doKills;
14061 if (mLastPowerCheckRealtime == 0) {
14062 doWakeKills = false;
14063 }
14064 if (mLastPowerCheckUptime == 0) {
14065 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014066 }
14067 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014068 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014069 }
14070 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014071 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14072 final long curUptime = SystemClock.uptimeMillis();
14073 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14074 mLastPowerCheckRealtime = curRealtime;
14075 mLastPowerCheckUptime = curUptime;
14076 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14077 doWakeKills = false;
14078 }
14079 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14080 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014081 }
14082 int i = mLruProcesses.size();
14083 while (i > 0) {
14084 i--;
14085 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014086 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014087 long wtime;
14088 synchronized (stats) {
14089 wtime = stats.getProcessWakeTime(app.info.uid,
14090 app.pid, curRealtime);
14091 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014092 long wtimeUsed = wtime - app.lastWakeTime;
14093 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14094 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014095 StringBuilder sb = new StringBuilder(128);
14096 sb.append("Wake for ");
14097 app.toShortString(sb);
14098 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014099 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014100 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014101 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014102 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014103 sb.append((wtimeUsed*100)/realtimeSince);
14104 sb.append("%)");
14105 Slog.i(TAG, sb.toString());
14106 sb.setLength(0);
14107 sb.append("CPU for ");
14108 app.toShortString(sb);
14109 sb.append(": over ");
14110 TimeUtils.formatDuration(uptimeSince, sb);
14111 sb.append(" used ");
14112 TimeUtils.formatDuration(cputimeUsed, sb);
14113 sb.append(" (");
14114 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014115 sb.append("%)");
14116 Slog.i(TAG, sb.toString());
14117 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014118 // If a process has held a wake lock for more
14119 // than 50% of the time during this period,
14120 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014121 if (doWakeKills && realtimeSince > 0
14122 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14123 synchronized (stats) {
14124 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14125 realtimeSince, wtimeUsed);
14126 }
14127 Slog.w(TAG, "Excessive wake lock in " + app.processName
14128 + " (pid " + app.pid + "): held " + wtimeUsed
14129 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014130 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14131 app.processName, app.setAdj, "excessive wake lock");
14132 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014133 } else if (doCpuKills && uptimeSince > 0
14134 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14135 synchronized (stats) {
14136 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14137 uptimeSince, cputimeUsed);
14138 }
14139 Slog.w(TAG, "Excessive CPU in " + app.processName
14140 + " (pid " + app.pid + "): used " + cputimeUsed
14141 + " during " + uptimeSince);
14142 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14143 app.processName, app.setAdj, "excessive cpu");
14144 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014145 } else {
14146 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014147 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014148 }
14149 }
14150 }
14151 }
14152
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014153 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014154 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014155 app.hiddenAdj = hiddenAdj;
14156
14157 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014158 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014159 }
14160
Dianne Hackborn287952c2010-09-22 22:34:31 -070014161 final boolean wasKeeping = app.keeping;
14162
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014163 boolean success = true;
14164
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014165 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014166
Jeff Brown10e89712011-07-08 18:52:57 -070014167 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014168 if (false) {
14169 // Removing for now. Forcing GCs is not so useful anymore
14170 // with Dalvik, and the new memory level hint facility is
14171 // better for what we need to do these days.
14172 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14173 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14174 // If this app is transitioning from foreground to
14175 // non-foreground, have it do a gc.
14176 scheduleAppGcLocked(app);
14177 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14178 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14179 // Likewise do a gc when an app is moving in to the
14180 // background (such as a service stopping).
14181 scheduleAppGcLocked(app);
14182 }
Jeff Brown10e89712011-07-08 18:52:57 -070014183 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014184
Jeff Brown10e89712011-07-08 18:52:57 -070014185 if (wasKeeping && !app.keeping) {
14186 // This app is no longer something we want to keep. Note
14187 // its current wake lock time to later know to kill it if
14188 // it is not behaving well.
14189 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14190 synchronized (stats) {
14191 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14192 app.pid, SystemClock.elapsedRealtime());
14193 }
14194 app.lastCpuTime = app.curCpuTime;
14195 }
14196
14197 app.setRawAdj = app.curRawAdj;
14198 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014199
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014200 if (app.curAdj != app.setAdj) {
14201 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014202 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14203 TAG, "Set " + app.pid + " " + app.processName +
14204 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014205 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014206 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014207 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014208 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014209 }
14210 }
14211 if (app.setSchedGroup != app.curSchedGroup) {
14212 app.setSchedGroup = app.curSchedGroup;
14213 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14214 "Setting process group of " + app.processName
14215 + " to " + app.curSchedGroup);
14216 if (app.waitingToKill != null &&
14217 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14218 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14219 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14220 app.processName, app.setAdj, app.waitingToKill);
14221 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014222 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014223 } else {
14224 if (true) {
14225 long oldId = Binder.clearCallingIdentity();
14226 try {
14227 Process.setProcessGroup(app.pid, app.curSchedGroup);
14228 } catch (Exception e) {
14229 Slog.w(TAG, "Failed setting process group of " + app.pid
14230 + " to " + app.curSchedGroup);
14231 e.printStackTrace();
14232 } finally {
14233 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014234 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014235 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014236 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014237 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014238 app.thread.setSchedulingGroup(app.curSchedGroup);
14239 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014240 }
14241 }
14242 }
14243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014244 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014245 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014246 }
14247
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014248 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014249 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014250 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014251 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014252 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014253 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014254 }
14255 }
14256 return resumedActivity;
14257 }
14258
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014259 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014260 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014261 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14262 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014263 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14264 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014265
14266 mAdjSeq++;
14267
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014268 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014269 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14270 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014271 if (nowHidden != wasHidden) {
14272 // Changed to/from hidden state, so apps after it in the LRU
14273 // list may also be changed.
14274 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014275 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014276 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014277 }
14278
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014279 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014280 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014281 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14282
14283 if (false) {
14284 RuntimeException e = new RuntimeException();
14285 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014286 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014287 }
14288
14289 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014290 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014291
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014292 // Let's determine how many processes we have running vs.
14293 // how many slots we have for background processes; we may want
14294 // to put multiple processes in a slot of there are enough of
14295 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014296 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014297 int factor = (mLruProcesses.size()-4)/numSlots;
14298 if (factor < 1) factor = 1;
14299 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014300 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014301
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014302 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014303 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014304 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014305 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014306 while (i > 0) {
14307 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014308 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014309 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014310 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14311 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014312 && app.curAdj == curHiddenAdj) {
14313 step++;
14314 if (step >= factor) {
14315 step = 0;
14316 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014317 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014318 }
14319 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014320 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014321 numHidden++;
14322 if (numHidden > mProcessLimit) {
14323 Slog.i(TAG, "No longer want " + app.processName
14324 + " (pid " + app.pid + "): hidden #" + numHidden);
14325 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14326 app.processName, app.setAdj, "too many background");
14327 app.killedBackground = true;
14328 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014329 }
14330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014331 }
14332 }
14333
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014334 mNumServiceProcs = mNewNumServiceProcs;
14335
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014336 // Now determine the memory trimming level of background processes.
14337 // Unfortunately we need to start at the back of the list to do this
14338 // properly. We only do this if the number of background apps we
14339 // are managing to keep around is less than half the maximum we desire;
14340 // if we are keeping a good number around, we'll let them use whatever
14341 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014342 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014343 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014344 factor = numHidden/3;
14345 int minFactor = 2;
14346 if (mHomeProcess != null) minFactor++;
14347 if (mPreviousProcess != null) minFactor++;
14348 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014349 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014350 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014351 for (i=0; i<N; i++) {
14352 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014353 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14354 && app.curAdj != ProcessList.SERVICE_B_ADJ
14355 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014356 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14357 try {
14358 app.thread.scheduleTrimMemory(curLevel);
14359 } catch (RemoteException e) {
14360 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014361 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014362 // For these apps we will also finish their activities
14363 // to help them free memory.
Dianne Hackborn28695e02011-11-02 21:59:51 -070014364 mMainStack.destroyActivitiesLocked(app, false, "trim");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014365 }
14366 }
14367 app.trimMemoryLevel = curLevel;
14368 step++;
14369 if (step >= factor) {
14370 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014371 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14372 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014373 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014374 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14375 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014376 break;
14377 }
14378 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014379 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014380 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014381 && app.thread != null) {
14382 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014383 app.thread.scheduleTrimMemory(
14384 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014385 } catch (RemoteException e) {
14386 }
14387 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014388 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014389 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014390 && app.pendingUiClean) {
14391 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14392 && app.thread != null) {
14393 try {
14394 app.thread.scheduleTrimMemory(
14395 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14396 } catch (RemoteException e) {
14397 }
14398 }
14399 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14400 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014401 } else {
14402 app.trimMemoryLevel = 0;
14403 }
14404 }
14405 } else {
14406 final int N = mLruProcesses.size();
14407 for (i=0; i<N; i++) {
14408 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014409 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014410 && app.pendingUiClean) {
14411 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14412 && app.thread != null) {
14413 try {
14414 app.thread.scheduleTrimMemory(
14415 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14416 } catch (RemoteException e) {
14417 }
14418 }
14419 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14420 app.pendingUiClean = false;
14421 } else {
14422 app.trimMemoryLevel = 0;
14423 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014424 }
14425 }
14426
14427 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014428 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014430 }
14431
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014432 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014433 synchronized (this) {
14434 int i;
14435
14436 // First remove any unused application processes whose package
14437 // has been removed.
14438 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14439 final ProcessRecord app = mRemovedProcesses.get(i);
14440 if (app.activities.size() == 0
14441 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014442 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014443 TAG, "Exiting empty application process "
14444 + app.processName + " ("
14445 + (app.thread != null ? app.thread.asBinder() : null)
14446 + ")\n");
14447 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014448 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14449 app.processName, app.setAdj, "empty");
14450 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014451 } else {
14452 try {
14453 app.thread.scheduleExit();
14454 } catch (Exception e) {
14455 // Ignore exceptions.
14456 }
14457 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014458 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014459 mRemovedProcesses.remove(i);
14460
14461 if (app.persistent) {
14462 if (app.persistent) {
14463 addAppLocked(app.info);
14464 }
14465 }
14466 }
14467 }
14468
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014469 // Now update the oom adj for all processes.
14470 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014471 }
14472 }
14473
14474 /** This method sends the specified signal to each of the persistent apps */
14475 public void signalPersistentProcesses(int sig) throws RemoteException {
14476 if (sig != Process.SIGNAL_USR1) {
14477 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14478 }
14479
14480 synchronized (this) {
14481 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14482 != PackageManager.PERMISSION_GRANTED) {
14483 throw new SecurityException("Requires permission "
14484 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14485 }
14486
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014487 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14488 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014489 if (r.thread != null && r.persistent) {
14490 Process.sendSignal(r.pid, sig);
14491 }
14492 }
14493 }
14494 }
14495
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014496 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14497 if (proc == null || proc == mProfileProc) {
14498 proc = mProfileProc;
14499 path = mProfileFile;
14500 profileType = mProfileType;
14501 clearProfilerLocked();
14502 }
14503 if (proc == null) {
14504 return;
14505 }
14506 try {
14507 proc.thread.profilerControl(false, path, null, profileType);
14508 } catch (RemoteException e) {
14509 throw new IllegalStateException("Process disappeared");
14510 }
14511 }
14512
14513 private void clearProfilerLocked() {
14514 if (mProfileFd != null) {
14515 try {
14516 mProfileFd.close();
14517 } catch (IOException e) {
14518 }
14519 }
14520 mProfileApp = null;
14521 mProfileProc = null;
14522 mProfileFile = null;
14523 mProfileType = 0;
14524 mAutoStopProfiler = false;
14525 }
14526
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014527 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014528 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014529
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014530 try {
14531 synchronized (this) {
14532 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14533 // its own permission.
14534 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14535 != PackageManager.PERMISSION_GRANTED) {
14536 throw new SecurityException("Requires permission "
14537 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014538 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014539
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014540 if (start && fd == null) {
14541 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014542 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014543
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014544 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014545 if (process != null) {
14546 try {
14547 int pid = Integer.parseInt(process);
14548 synchronized (mPidsSelfLocked) {
14549 proc = mPidsSelfLocked.get(pid);
14550 }
14551 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014552 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014553
14554 if (proc == null) {
14555 HashMap<String, SparseArray<ProcessRecord>> all
14556 = mProcessNames.getMap();
14557 SparseArray<ProcessRecord> procs = all.get(process);
14558 if (procs != null && procs.size() > 0) {
14559 proc = procs.valueAt(0);
14560 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014561 }
14562 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014563
14564 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014565 throw new IllegalArgumentException("Unknown process: " + process);
14566 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014567
14568 if (start) {
14569 stopProfilerLocked(null, null, 0);
14570 setProfileApp(proc.info, proc.processName, path, fd, false);
14571 mProfileProc = proc;
14572 mProfileType = profileType;
14573 try {
14574 fd = fd.dup();
14575 } catch (IOException e) {
14576 fd = null;
14577 }
14578 proc.thread.profilerControl(start, path, fd, profileType);
14579 fd = null;
14580 mProfileFd = null;
14581 } else {
14582 stopProfilerLocked(proc, path, profileType);
14583 if (fd != null) {
14584 try {
14585 fd.close();
14586 } catch (IOException e) {
14587 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014588 }
14589 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014590
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014591 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014592 }
14593 } catch (RemoteException e) {
14594 throw new IllegalStateException("Process disappeared");
14595 } finally {
14596 if (fd != null) {
14597 try {
14598 fd.close();
14599 } catch (IOException e) {
14600 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014601 }
14602 }
14603 }
Andy McFadden824c5102010-07-09 16:26:57 -070014604
14605 public boolean dumpHeap(String process, boolean managed,
14606 String path, ParcelFileDescriptor fd) throws RemoteException {
14607
14608 try {
14609 synchronized (this) {
14610 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14611 // its own permission (same as profileControl).
14612 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14613 != PackageManager.PERMISSION_GRANTED) {
14614 throw new SecurityException("Requires permission "
14615 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14616 }
14617
14618 if (fd == null) {
14619 throw new IllegalArgumentException("null fd");
14620 }
14621
14622 ProcessRecord proc = null;
14623 try {
14624 int pid = Integer.parseInt(process);
14625 synchronized (mPidsSelfLocked) {
14626 proc = mPidsSelfLocked.get(pid);
14627 }
14628 } catch (NumberFormatException e) {
14629 }
14630
14631 if (proc == null) {
14632 HashMap<String, SparseArray<ProcessRecord>> all
14633 = mProcessNames.getMap();
14634 SparseArray<ProcessRecord> procs = all.get(process);
14635 if (procs != null && procs.size() > 0) {
14636 proc = procs.valueAt(0);
14637 }
14638 }
14639
14640 if (proc == null || proc.thread == null) {
14641 throw new IllegalArgumentException("Unknown process: " + process);
14642 }
14643
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014644 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14645 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014646 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14647 throw new SecurityException("Process not debuggable: " + proc);
14648 }
14649 }
14650
14651 proc.thread.dumpHeap(managed, path, fd);
14652 fd = null;
14653 return true;
14654 }
14655 } catch (RemoteException e) {
14656 throw new IllegalStateException("Process disappeared");
14657 } finally {
14658 if (fd != null) {
14659 try {
14660 fd.close();
14661 } catch (IOException e) {
14662 }
14663 }
14664 }
14665 }
14666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014667 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14668 public void monitor() {
14669 synchronized (this) { }
14670 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014671
14672 public void onCoreSettingsChange(Bundle settings) {
14673 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14674 ProcessRecord processRecord = mLruProcesses.get(i);
14675 try {
14676 if (processRecord.thread != null) {
14677 processRecord.thread.setCoreSettings(settings);
14678 }
14679 } catch (RemoteException re) {
14680 /* ignore */
14681 }
14682 }
14683 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014684
14685 // Multi-user methods
14686
14687 public boolean switchUser(int userid) {
14688 // TODO
14689 return true;
14690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014691}