blob: 7232a9447f70a35dd926b1434cf8c0ee2be08e5e [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;
Dianne Hackborn661cd522011-08-22 00:26:20 -070094import android.os.HandlerThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import android.os.IBinder;
96import android.os.IPermissionController;
97import android.os.Looper;
98import android.os.Message;
99import android.os.Parcel;
100import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700102import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.os.RemoteException;
104import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700105import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.os.SystemClock;
107import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.util.EventLog;
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;
123import java.io.DataInputStream;
124import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.File;
126import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200130import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800131import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.PrintWriter;
133import java.lang.IllegalStateException;
134import java.lang.ref.WeakReference;
135import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700136import java.util.Collections;
137import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.util.HashMap;
139import java.util.HashSet;
140import java.util.Iterator;
141import java.util.List;
142import java.util.Locale;
143import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700144import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700145import java.util.concurrent.atomic.AtomicBoolean;
146import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148public final class ActivityManagerService extends ActivityManagerNative
149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "ActivityManager";
151 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400152 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_SWITCH = localLOGV || false;
154 static final boolean DEBUG_TASKS = localLOGV || false;
155 static final boolean DEBUG_PAUSE = localLOGV || false;
156 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
157 static final boolean DEBUG_TRANSITION = localLOGV || false;
158 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_VISBILITY = localLOGV || false;
163 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700164 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700167 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700168 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700169 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700170 static final boolean DEBUG_POWER = localLOGV || false;
171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean VALIDATE_TOKENS = false;
173 static final boolean SHOW_ACTIVITY_START_TIME = true;
174
175 // Control over CPU and battery monitoring.
176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
177 static final boolean MONITOR_CPU_USAGE = true;
178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
180 static final boolean MONITOR_THREAD_CPU_USAGE = false;
181
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 // Maximum number of recent tasks that we can remember.
188 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700189
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700190 // Amount of time after a call to stopAppSwitches() during which we will
191 // prevent further untrusted switches from happening.
192 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
194 // How long we wait for a launched process to attach to the activity manager
195 // before we decide it's never going to come up for real.
196 static final int PROC_START_TIMEOUT = 10*1000;
197
Jeff Brown3f9dd282011-07-08 20:02:19 -0700198 // How long we wait for a launched process to attach to the activity manager
199 // before we decide it's never going to come up for real, when the process was
200 // started with a wrapper for instrumentation (such as Valgrind) because it
201 // could take much longer than usual.
202 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 // How long to wait after going idle before forcing apps to GC.
205 static final int GC_TIMEOUT = 5*1000;
206
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700207 // The minimum amount of time between successive GC requests for a process.
208 static final int GC_MIN_INTERVAL = 60*1000;
209
Dianne Hackborn287952c2010-09-22 22:34:31 -0700210 // The rate at which we check for apps using excessive power -- 15 mins.
211 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
212
213 // The minimum sample duration we will allow before deciding we have
214 // enough data on wake locks to start killing things.
215 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
216
217 // The minimum sample duration we will allow before deciding we have
218 // enough data on CPU usage to start killing things.
219 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 // How long we allow a receiver to run before giving up on it.
222 static final int BROADCAST_TIMEOUT = 10*1000;
223
224 // How long we wait for a service to finish executing.
225 static final int SERVICE_TIMEOUT = 20*1000;
226
227 // How long a service needs to be running until restarting its process
228 // is no longer considered to be a relaunch of the service.
229 static final int SERVICE_RESTART_DURATION = 5*1000;
230
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700231 // How long a service needs to be running until it will start back at
232 // SERVICE_RESTART_DURATION after being killed.
233 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
234
235 // Multiplying factor to increase restart duration time by, for each time
236 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
237 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
238
239 // The minimum amount of time between restarting services that we allow.
240 // That is, when multiple services are restarting, we won't allow each
241 // to restart less than this amount of time from the last one.
242 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 // Maximum amount of time for there to be no activity on a service before
245 // we consider it non-essential and allow its process to go on the
246 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700247 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 // How long we wait until we timeout on key dispatching.
250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 // How long we wait until we timeout on key dispatching during instrumentation.
253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254
Dan Egnor42471dd2010-01-07 17:25:22 -0800255 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 static final String[] EMPTY_STRING_ARRAY = new String[0];
258
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700259 public ActivityStack mMainStack;
260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700262 * Description of a request to start a new activity, which has been held
263 * due to app switches being disabled.
264 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700265 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700266 ActivityRecord r;
267 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700268 Uri[] grantedUriPermissions;
269 int grantedMode;
270 boolean onlyIfNeeded;
271 }
272
273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274 = new ArrayList<PendingActivityLaunch>();
275
276 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 * List of all active broadcasts that are to be executed immediately
278 * (without waiting for another broadcast to finish). Currently this only
279 * contains broadcasts to registered receivers, to avoid spinning up
280 * a bunch of processes to execute IntentReceiver components.
281 */
282 final ArrayList<BroadcastRecord> mParallelBroadcasts
283 = new ArrayList<BroadcastRecord>();
284
285 /**
286 * List of all active broadcasts that are to be executed one at a time.
287 * The object at the top of the list is the currently activity broadcasts;
288 * those after it are waiting for the top to finish..
289 */
290 final ArrayList<BroadcastRecord> mOrderedBroadcasts
291 = new ArrayList<BroadcastRecord>();
292
293 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800294 * Historical data of past broadcasts, for debugging.
295 */
296 static final int MAX_BROADCAST_HISTORY = 100;
297 final BroadcastRecord[] mBroadcastHistory
298 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
299
300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * Set when we current have a BROADCAST_INTENT_MSG in flight.
302 */
303 boolean mBroadcastsScheduled = false;
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Activity we have told the window manager to have key focus.
307 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700308 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700309 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 * List of intents that were used to start the most recent tasks.
311 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700315 * Process management.
316 */
317 final ProcessList mProcessList = new ProcessList();
318
319 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 * All of the applications we currently have running organized by name.
321 * The keys are strings of the application package name (as
322 * returned by the package manager), and the keys are ApplicationRecord
323 * objects.
324 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
327 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700328 * The currently running heavy-weight process, if any.
329 */
330 ProcessRecord mHeavyWeightProcess = null;
331
332 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 * The last time that various processes have crashed.
334 */
335 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
336
337 /**
338 * Set of applications that we consider to be bad, and will reject
339 * incoming broadcasts from (which the user has no control over).
340 * Processes are added to this set when they have crashed twice within
341 * a minimum amount of time; they are removed from it when they are
342 * later restarted (hopefully due to some user action). The value is the
343 * time it was added to the list.
344 */
345 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
346
347 /**
348 * All of the processes we currently have running organized by pid.
349 * The keys are the pid running the application.
350 *
351 * <p>NOTE: This object is protected by its own lock, NOT the global
352 * activity manager lock!
353 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700354 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355
356 /**
357 * All of the processes that have been forced to be foreground. The key
358 * is the pid of the caller who requested it (we hold a death
359 * link on it).
360 */
361 abstract class ForegroundToken implements IBinder.DeathRecipient {
362 int pid;
363 IBinder token;
364 }
365 final SparseArray<ForegroundToken> mForegroundProcesses
366 = new SparseArray<ForegroundToken>();
367
368 /**
369 * List of records for processes that someone had tried to start before the
370 * system was ready. We don't start them at that point, but ensure they
371 * are started by the time booting is complete.
372 */
373 final ArrayList<ProcessRecord> mProcessesOnHold
374 = new ArrayList<ProcessRecord>();
375
376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 * List of persistent applications that are in the process
378 * of being started.
379 */
380 final ArrayList<ProcessRecord> mPersistentStartingProcesses
381 = new ArrayList<ProcessRecord>();
382
383 /**
384 * Processes that are being forcibly torn down.
385 */
386 final ArrayList<ProcessRecord> mRemovedProcesses
387 = new ArrayList<ProcessRecord>();
388
389 /**
390 * List of running applications, sorted by recent usage.
391 * The first entry in the list is the least recently used.
392 * It contains ApplicationRecord objects. This list does NOT include
393 * any persistent application records (since we never want to exit them).
394 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800395 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 = new ArrayList<ProcessRecord>();
397
398 /**
399 * List of processes that should gc as soon as things are idle.
400 */
401 final ArrayList<ProcessRecord> mProcessesToGc
402 = new ArrayList<ProcessRecord>();
403
404 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800405 * This is the process holding what we currently consider to be
406 * the "home" activity.
407 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700408 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800409
410 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400411 * Packages that the user has asked to have run in screen size
412 * compatibility mode instead of filling the screen.
413 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700414 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400415
416 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * Set of PendingResultRecord objects that are currently active.
418 */
419 final HashSet mPendingResultRecords = new HashSet();
420
421 /**
422 * Set of IntentSenderRecord objects that are currently active.
423 */
424 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
425 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
426
427 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800428 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700429 * already logged DropBox entries for. Guarded by itself. If
430 * something (rogue user app) forces this over
431 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
432 */
433 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
434 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
435
436 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700437 * Strict Mode background batched logging state.
438 *
439 * The string buffer is guarded by itself, and its lock is also
440 * used to determine if another batched write is already
441 * in-flight.
442 */
443 private final StringBuilder mStrictModeBuffer = new StringBuilder();
444
445 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700446 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
447 */
448 private boolean mPendingBroadcastTimeoutMessage;
449
450 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 * Intent broadcast that we have tried to start, but are
452 * waiting for its application's process to be created. We only
453 * need one (instead of a list) because we always process broadcasts
454 * one at a time, so no others can be started while waiting for this
455 * one.
456 */
457 BroadcastRecord mPendingBroadcast = null;
458
459 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700460 * The receiver index that is pending, to restart the broadcast if needed.
461 */
462 int mPendingBroadcastRecvIndex;
463
464 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 * Keeps track of all IIntentReceivers that have been registered for
466 * broadcasts. Hash keys are the receiver IBinder, hash value is
467 * a ReceiverList.
468 */
469 final HashMap mRegisteredReceivers = new HashMap();
470
471 /**
472 * Resolver for broadcast intents to registered receivers.
473 * Holds BroadcastFilter (subclass of IntentFilter).
474 */
475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
477 @Override
478 protected boolean allowFilterResult(
479 BroadcastFilter filter, List<BroadcastFilter> dest) {
480 IBinder target = filter.receiverList.receiver.asBinder();
481 for (int i=dest.size()-1; i>=0; i--) {
482 if (dest.get(i).receiverList.receiver.asBinder() == target) {
483 return false;
484 }
485 }
486 return true;
487 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700488
489 @Override
490 protected String packageForFilter(BroadcastFilter filter) {
491 return filter.packageName;
492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 };
494
495 /**
496 * State of all active sticky broadcasts. Keys are the action of the
497 * sticky Intent, values are an ArrayList of all broadcasted intents with
498 * that action (which should usually be one).
499 */
500 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
501 new HashMap<String, ArrayList<Intent>>();
502
503 /**
504 * All currently running services.
505 */
506 final HashMap<ComponentName, ServiceRecord> mServices =
507 new HashMap<ComponentName, ServiceRecord>();
508
509 /**
510 * All currently running services indexed by the Intent used to start them.
511 */
512 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
513 new HashMap<Intent.FilterComparison, ServiceRecord>();
514
515 /**
516 * All currently bound service connections. Keys are the IBinder of
517 * the client's IServiceConnection.
518 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700519 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
520 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521
522 /**
523 * List of services that we have been asked to start,
524 * but haven't yet been able to. It is used to hold start requests
525 * while waiting for their corresponding application thread to get
526 * going.
527 */
528 final ArrayList<ServiceRecord> mPendingServices
529 = new ArrayList<ServiceRecord>();
530
531 /**
532 * List of services that are scheduled to restart following a crash.
533 */
534 final ArrayList<ServiceRecord> mRestartingServices
535 = new ArrayList<ServiceRecord>();
536
537 /**
538 * List of services that are in the process of being stopped.
539 */
540 final ArrayList<ServiceRecord> mStoppingServices
541 = new ArrayList<ServiceRecord>();
542
543 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700544 * Backup/restore process management
545 */
546 String mBackupAppName = null;
547 BackupRecord mBackupTarget = null;
548
549 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * List of PendingThumbnailsRecord objects of clients who are still
551 * waiting to receive all of the thumbnails for a task.
552 */
553 final ArrayList mPendingThumbnails = new ArrayList();
554
555 /**
556 * List of HistoryRecord objects that have been finished and must
557 * still report back to a pending thumbnail receiver.
558 */
559 final ArrayList mCancelledThumbnails = new ArrayList();
560
561 /**
562 * All of the currently running global content providers. Keys are a
563 * string containing the provider name and values are a
564 * ContentProviderRecord object containing the data about it. Note
565 * that a single provider may be published under multiple names, so
566 * there may be multiple entries here for a single one in mProvidersByClass.
567 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700568 final HashMap<String, ContentProviderRecord> mProvidersByName
569 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570
571 /**
572 * All of the currently running global content providers. Keys are a
573 * string containing the provider's implementation class and values are a
574 * ContentProviderRecord object containing the data about it.
575 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700576 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
577 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * List of content providers who have clients waiting for them. The
581 * application is currently being launched and the provider will be
582 * removed from this list once it is published.
583 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700584 final ArrayList<ContentProviderRecord> mLaunchingProviders
585 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * Global set of specific Uri permissions that have been granted.
589 */
590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591 = new SparseArray<HashMap<Uri, UriPermission>>();
592
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800593 CoreSettingsObserver mCoreSettingsObserver;
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 /**
596 * Thread-local storage used to carry caller permissions over through
597 * indirect content-provider access.
598 * @see #ActivityManagerService.openContentUri()
599 */
600 private class Identity {
601 public int pid;
602 public int uid;
603
604 Identity(int _pid, int _uid) {
605 pid = _pid;
606 uid = _uid;
607 }
608 }
609 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
610
611 /**
612 * All information we have collected about the runtime performance of
613 * any user id that can impact battery performance.
614 */
615 final BatteryStatsService mBatteryStatsService;
616
617 /**
618 * information about component usage
619 */
620 final UsageStatsService mUsageStatsService;
621
622 /**
623 * Current configuration information. HistoryRecord objects are given
624 * a reference to this object to indicate which configuration they are
625 * currently running in, so this object must be kept immutable.
626 */
627 Configuration mConfiguration = new Configuration();
628
629 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800630 * Current sequencing integer of the configuration, for skipping old
631 * configurations.
632 */
633 int mConfigurationSeq = 0;
634
635 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700636 * Hardware-reported OpenGLES version.
637 */
638 final int GL_ES_VERSION;
639
640 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 * List of initialization arguments to pass to all processes when binding applications to them.
642 * For example, references to the commonly used services.
643 */
644 HashMap<String, IBinder> mAppBindArgs;
645
646 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700647 * Temporary to avoid allocations. Protected by main lock.
648 */
649 final StringBuilder mStringBuilder = new StringBuilder(256);
650
651 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 * Used to control how we initialize the service.
653 */
654 boolean mStartRunning = false;
655 ComponentName mTopComponent;
656 String mTopAction;
657 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700658 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 boolean mSystemReady = false;
660 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700661 boolean mWaitingUpdate = false;
662 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700663 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700664 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
666 Context mContext;
667
668 int mFactoryTest;
669
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700670 boolean mCheckedForSetup;
671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700673 * The time at which we will allow normal application switches again,
674 * after a call to {@link #stopAppSwitches()}.
675 */
676 long mAppSwitchesAllowedTime;
677
678 /**
679 * This is set to true after the first switch after mAppSwitchesAllowedTime
680 * is set; any switches after that will clear the time.
681 */
682 boolean mDidAppSwitch;
683
684 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700685 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700686 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700687 long mLastPowerCheckRealtime;
688
689 /**
690 * Last time (in uptime) at which we checked for power usage.
691 */
692 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700693
694 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 * Set while we are wanting to sleep, to prevent any
696 * activities from being started/resumed.
697 */
698 boolean mSleeping = false;
699
700 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700701 * Set if we are shutting down the system, similar to sleeping.
702 */
703 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * Task identifier that activities are currently being started
707 * in. Incremented each time a new task is created.
708 * todo: Replace this with a TokenSpace class that generates non-repeating
709 * integers that won't wrap.
710 */
711 int mCurTask = 1;
712
713 /**
714 * Current sequence id for oom_adj computation traversal.
715 */
716 int mAdjSeq = 0;
717
718 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700719 * Current sequence id for process LRU updating.
720 */
721 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
723 /**
724 * System monitoring: number of processes that died since the last
725 * N procs were started.
726 */
727 int[] mProcDeaths = new int[20];
728
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700729 /**
730 * This is set if we had to do a delayed dexopt of an app before launching
731 * it, to increasing the ANR timeouts in that case.
732 */
733 boolean mDidDexOpt;
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 String mDebugApp = null;
736 boolean mWaitForDebugger = false;
737 boolean mDebugTransient = false;
738 String mOrigDebugApp = null;
739 boolean mOrigWaitForDebugger = false;
740 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700741 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700742 String mProfileApp = null;
743 ProcessRecord mProfileProc = null;
744 String mProfileFile;
745 ParcelFileDescriptor mProfileFd;
746 int mProfileType = 0;
747 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700749 final RemoteCallbackList<IActivityWatcher> mWatchers
750 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700751
752 final RemoteCallbackList<IProcessObserver> mProcessObservers
753 = new RemoteCallbackList<IProcessObserver>();
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 /**
756 * Callback of last caller to {@link #requestPss}.
757 */
758 Runnable mRequestPssCallback;
759
760 /**
761 * Remaining processes for which we are waiting results from the last
762 * call to {@link #requestPss}.
763 */
764 final ArrayList<ProcessRecord> mRequestPssList
765 = new ArrayList<ProcessRecord>();
766
767 /**
768 * Runtime statistics collection thread. This object's lock is used to
769 * protect all related state.
770 */
771 final Thread mProcessStatsThread;
772
773 /**
774 * Used to collect process stats when showing not responding dialog.
775 * Protected by mProcessStatsThread.
776 */
777 final ProcessStats mProcessStats = new ProcessStats(
778 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700779 final AtomicLong mLastCpuTime = new AtomicLong(0);
780 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 long mLastWriteTime = 0;
783
784 /**
785 * Set to true after the system has finished booting.
786 */
787 boolean mBooted = false;
788
Dianne Hackborn7d608422011-08-07 16:24:18 -0700789 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700790 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 WindowManagerService mWindowManager;
793
794 static ActivityManagerService mSelf;
795 static ActivityThread mSystemThread;
796
797 private final class AppDeathRecipient implements IBinder.DeathRecipient {
798 final ProcessRecord mApp;
799 final int mPid;
800 final IApplicationThread mAppThread;
801
802 AppDeathRecipient(ProcessRecord app, int pid,
803 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800804 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 TAG, "New death recipient " + this
806 + " for thread " + thread.asBinder());
807 mApp = app;
808 mPid = pid;
809 mAppThread = thread;
810 }
811
812 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800813 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 TAG, "Death received in " + this
815 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 synchronized(ActivityManagerService.this) {
817 appDiedLocked(mApp, mPid, mAppThread);
818 }
819 }
820 }
821
822 static final int SHOW_ERROR_MSG = 1;
823 static final int SHOW_NOT_RESPONDING_MSG = 2;
824 static final int SHOW_FACTORY_ERROR_MSG = 3;
825 static final int UPDATE_CONFIGURATION_MSG = 4;
826 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827 static final int WAIT_FOR_DEBUGGER_MSG = 6;
828 static final int BROADCAST_INTENT_MSG = 7;
829 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static final int SERVICE_TIMEOUT_MSG = 12;
831 static final int UPDATE_TIME_ZONE = 13;
832 static final int SHOW_UID_ERROR_MSG = 14;
833 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700836 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800837 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700838 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700842 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700843 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700845 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
846 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847
848 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700849 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
851 final Handler mHandler = new Handler() {
852 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 //}
855
856 public void handleMessage(Message msg) {
857 switch (msg.what) {
858 case SHOW_ERROR_MSG: {
859 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 synchronized (ActivityManagerService.this) {
861 ProcessRecord proc = (ProcessRecord)data.get("app");
862 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800863 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 return;
865 }
866 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700867 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800868 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 d.show();
870 proc.crashDialog = d;
871 } else {
872 // The device is asleep, so just pretend that the user
873 // saw a crash dialog and hit "force quit".
874 res.set(0);
875 }
876 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700877
878 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 } break;
880 case SHOW_NOT_RESPONDING_MSG: {
881 synchronized (ActivityManagerService.this) {
882 HashMap data = (HashMap) msg.obj;
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800888
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700889 Intent intent = new Intent("android.intent.action.ANR");
890 if (!mProcessesReady) {
891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
892 }
893 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800894 null, null, 0, null, null, null,
895 false, false, MY_PID, Process.SYSTEM_UID);
896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700898 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 d.show();
900 proc.anrDialog = d;
901 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700902
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700903 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700905 case SHOW_STRICT_MODE_VIOLATION_MSG: {
906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907 synchronized (ActivityManagerService.this) {
908 ProcessRecord proc = (ProcessRecord) data.get("app");
909 if (proc == null) {
910 Slog.e(TAG, "App not found when showing strict mode dialog.");
911 break;
912 }
913 if (proc.crashDialog != null) {
914 Slog.e(TAG, "App already has strict mode dialog: " + proc);
915 return;
916 }
917 AppErrorResult res = (AppErrorResult) data.get("result");
918 if (!mSleeping && !mShuttingDown) {
919 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920 d.show();
921 proc.crashDialog = d;
922 } else {
923 // The device is asleep, so just pretend that the user
924 // saw a crash dialog and hit "force quit".
925 res.set(0);
926 }
927 }
928 ensureBootCompleted();
929 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 case SHOW_FACTORY_ERROR_MSG: {
931 Dialog d = new FactoryErrorDialog(
932 mContext, msg.getData().getCharSequence("msg"));
933 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700934 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 } break;
936 case UPDATE_CONFIGURATION_MSG: {
937 final ContentResolver resolver = mContext.getContentResolver();
938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939 } break;
940 case GC_BACKGROUND_PROCESSES_MSG: {
941 synchronized (ActivityManagerService.this) {
942 performAppGcsIfAppropriateLocked();
943 }
944 } break;
945 case WAIT_FOR_DEBUGGER_MSG: {
946 synchronized (ActivityManagerService.this) {
947 ProcessRecord app = (ProcessRecord)msg.obj;
948 if (msg.arg1 != 0) {
949 if (!app.waitedForDebugger) {
950 Dialog d = new AppWaitingForDebuggerDialog(
951 ActivityManagerService.this,
952 mContext, app);
953 app.waitDialog = d;
954 app.waitedForDebugger = true;
955 d.show();
956 }
957 } else {
958 if (app.waitDialog != null) {
959 app.waitDialog.dismiss();
960 app.waitDialog = null;
961 }
962 }
963 }
964 } break;
965 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800966 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 TAG, "Received BROADCAST_INTENT_MSG");
968 processNextBroadcast(true);
969 } break;
970 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700971 synchronized (ActivityManagerService.this) {
972 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700976 if (mDidDexOpt) {
977 mDidDexOpt = false;
978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979 nmsg.obj = msg.obj;
980 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
981 return;
982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 serviceTimeout((ProcessRecord)msg.obj);
984 } break;
985 case UPDATE_TIME_ZONE: {
986 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 if (r.thread != null) {
990 try {
991 r.thread.updateTimeZone();
992 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995 }
996 }
997 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700998 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700999 case CLEAR_DNS_CACHE: {
1000 synchronized (ActivityManagerService.this) {
1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002 ProcessRecord r = mLruProcesses.get(i);
1003 if (r.thread != null) {
1004 try {
1005 r.thread.clearDnsCache();
1006 } catch (RemoteException ex) {
1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008 }
1009 }
1010 }
1011 }
1012 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001013 case UPDATE_HTTP_PROXY: {
1014 ProxyProperties proxy = (ProxyProperties)msg.obj;
1015 String host = "";
1016 String port = "";
1017 String exclList = "";
1018 if (proxy != null) {
1019 host = proxy.getHost();
1020 port = Integer.toString(proxy.getPort());
1021 exclList = proxy.getExclusionList();
1022 }
1023 synchronized (ActivityManagerService.this) {
1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025 ProcessRecord r = mLruProcesses.get(i);
1026 if (r.thread != null) {
1027 try {
1028 r.thread.setHttpProxy(host, port, exclList);
1029 } catch (RemoteException ex) {
1030 Slog.w(TAG, "Failed to update http proxy for: " +
1031 r.info.processName);
1032 }
1033 }
1034 }
1035 }
1036 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 case SHOW_UID_ERROR_MSG: {
1038 // XXX This is a temporary dialog, no need to localize.
1039 AlertDialog d = new BaseErrorDialog(mContext);
1040 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1041 d.setCancelable(false);
1042 d.setTitle("System UIDs Inconsistent");
1043 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 +02001044 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1046 mUidAlert = d;
1047 d.show();
1048 } break;
1049 case IM_FEELING_LUCKY_MSG: {
1050 if (mUidAlert != null) {
1051 mUidAlert.dismiss();
1052 mUidAlert = null;
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001056 if (mDidDexOpt) {
1057 mDidDexOpt = false;
1058 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1059 nmsg.obj = msg.obj;
1060 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1061 return;
1062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 ProcessRecord app = (ProcessRecord)msg.obj;
1064 synchronized (ActivityManagerService.this) {
1065 processStartTimedOutLocked(app);
1066 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001067 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001068 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1069 synchronized (ActivityManagerService.this) {
1070 doPendingActivityLaunchesLocked(true);
1071 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001072 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001073 case KILL_APPLICATION_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 int uid = msg.arg1;
1076 boolean restart = (msg.arg2 == 1);
1077 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001078 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001079 }
1080 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001081 case FINALIZE_PENDING_INTENT_MSG: {
1082 ((PendingIntentRecord)msg.obj).completeFinalize();
1083 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001084 case POST_HEAVY_NOTIFICATION_MSG: {
1085 INotificationManager inm = NotificationManager.getService();
1086 if (inm == null) {
1087 return;
1088 }
1089
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001090 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001091 ProcessRecord process = root.app;
1092 if (process == null) {
1093 return;
1094 }
1095
1096 try {
1097 Context context = mContext.createPackageContext(process.info.packageName, 0);
1098 String text = mContext.getString(R.string.heavy_weight_notification,
1099 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1100 Notification notification = new Notification();
1101 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1102 notification.when = 0;
1103 notification.flags = Notification.FLAG_ONGOING_EVENT;
1104 notification.tickerText = text;
1105 notification.defaults = 0; // please be quiet
1106 notification.sound = null;
1107 notification.vibrate = null;
1108 notification.setLatestEventInfo(context, text,
1109 mContext.getText(R.string.heavy_weight_notification_detail),
1110 PendingIntent.getActivity(mContext, 0, root.intent,
1111 PendingIntent.FLAG_CANCEL_CURRENT));
1112
1113 try {
1114 int[] outId = new int[1];
1115 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1116 notification, outId);
1117 } catch (RuntimeException e) {
1118 Slog.w(ActivityManagerService.TAG,
1119 "Error showing notification for heavy-weight app", e);
1120 } catch (RemoteException e) {
1121 }
1122 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001123 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001124 }
1125 } break;
1126 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1127 INotificationManager inm = NotificationManager.getService();
1128 if (inm == null) {
1129 return;
1130 }
1131 try {
1132 inm.cancelNotification("android",
1133 R.string.heavy_weight_notification);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error canceling notification for service", e);
1137 } catch (RemoteException e) {
1138 }
1139 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001140 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1141 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001142 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001143 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001144 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1145 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001146 }
1147 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001148 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1149 synchronized (ActivityManagerService.this) {
1150 ActivityRecord ar = (ActivityRecord)msg.obj;
1151 if (mCompatModeDialog != null) {
1152 if (mCompatModeDialog.mAppInfo.packageName.equals(
1153 ar.info.applicationInfo.packageName)) {
1154 return;
1155 }
1156 mCompatModeDialog.dismiss();
1157 mCompatModeDialog = null;
1158 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001159 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001160 if (mCompatModePackages.getPackageAskCompatModeLocked(
1161 ar.packageName)) {
1162 int mode = mCompatModePackages.computeCompatModeLocked(
1163 ar.info.applicationInfo);
1164 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1165 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1166 mCompatModeDialog = new CompatModeDialog(
1167 ActivityManagerService.this, mContext,
1168 ar.info.applicationInfo);
1169 mCompatModeDialog.show();
1170 }
1171 }
1172 }
1173 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001174 break;
1175 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001176 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001177 final int pid = msg.arg1;
1178 final int uid = msg.arg2;
1179 final boolean foregroundActivities = (Boolean) msg.obj;
1180 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001181 break;
1182 }
1183 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001184 final int pid = msg.arg1;
1185 final int uid = msg.arg2;
1186 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001187 break;
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 }
1190 }
1191 };
1192
1193 public static void setSystemProcess() {
1194 try {
1195 ActivityManagerService m = mSelf;
1196
1197 ServiceManager.addService("activity", m);
1198 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001199 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 if (MONITOR_CPU_USAGE) {
1201 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 ServiceManager.addService("permission", new PermissionController(m));
1204
1205 ApplicationInfo info =
1206 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001207 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001208 mSystemThread.installSystemApplicationInfo(info);
1209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 synchronized (mSelf) {
1211 ProcessRecord app = mSelf.newProcessRecordLocked(
1212 mSystemThread.getApplicationThread(), info,
1213 info.processName);
1214 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001215 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001216 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1218 synchronized (mSelf.mPidsSelfLocked) {
1219 mSelf.mPidsSelfLocked.put(app.pid, app);
1220 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001221 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
1223 } catch (PackageManager.NameNotFoundException e) {
1224 throw new RuntimeException(
1225 "Unable to find android system package", e);
1226 }
1227 }
1228
1229 public void setWindowManager(WindowManagerService wm) {
1230 mWindowManager = wm;
1231 }
1232
1233 public static final Context main(int factoryTest) {
1234 AThread thr = new AThread();
1235 thr.start();
1236
1237 synchronized (thr) {
1238 while (thr.mService == null) {
1239 try {
1240 thr.wait();
1241 } catch (InterruptedException e) {
1242 }
1243 }
1244 }
1245
1246 ActivityManagerService m = thr.mService;
1247 mSelf = m;
1248 ActivityThread at = ActivityThread.systemMain();
1249 mSystemThread = at;
1250 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001251 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 m.mContext = context;
1253 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001254 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
1256 m.mBatteryStatsService.publish(context);
1257 m.mUsageStatsService.publish(context);
1258
1259 synchronized (thr) {
1260 thr.mReady = true;
1261 thr.notifyAll();
1262 }
1263
1264 m.startRunning(null, null, null, null);
1265
1266 return context;
1267 }
1268
1269 public static ActivityManagerService self() {
1270 return mSelf;
1271 }
1272
1273 static class AThread extends Thread {
1274 ActivityManagerService mService;
1275 boolean mReady = false;
1276
1277 public AThread() {
1278 super("ActivityManager");
1279 }
1280
1281 public void run() {
1282 Looper.prepare();
1283
1284 android.os.Process.setThreadPriority(
1285 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001286 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287
1288 ActivityManagerService m = new ActivityManagerService();
1289
1290 synchronized (this) {
1291 mService = m;
1292 notifyAll();
1293 }
1294
1295 synchronized (this) {
1296 while (!mReady) {
1297 try {
1298 wait();
1299 } catch (InterruptedException e) {
1300 }
1301 }
1302 }
1303
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001304 // For debug builds, log event loop stalls to dropbox for analysis.
1305 if (StrictMode.conditionallyEnableDebugLogging()) {
1306 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1307 }
1308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 Looper.loop();
1310 }
1311 }
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 static class MemBinder extends Binder {
1314 ActivityManagerService mActivityManagerService;
1315 MemBinder(ActivityManagerService activityManagerService) {
1316 mActivityManagerService = activityManagerService;
1317 }
1318
1319 @Override
1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001321 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 }
1323 }
1324
Chet Haase9c1e23b2011-03-24 10:51:31 -07001325 static class GraphicsBinder extends Binder {
1326 ActivityManagerService mActivityManagerService;
1327 GraphicsBinder(ActivityManagerService activityManagerService) {
1328 mActivityManagerService = activityManagerService;
1329 }
1330
1331 @Override
1332 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001333 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001334 }
1335 }
1336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 static class CpuBinder extends Binder {
1338 ActivityManagerService mActivityManagerService;
1339 CpuBinder(ActivityManagerService activityManagerService) {
1340 mActivityManagerService = activityManagerService;
1341 }
1342
1343 @Override
1344 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1345 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001346 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1347 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1348 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 }
1350 }
1351 }
1352
1353 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001354 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 File dataDir = Environment.getDataDirectory();
1357 File systemDir = new File(dataDir, "system");
1358 systemDir.mkdirs();
1359 mBatteryStatsService = new BatteryStatsService(new File(
1360 systemDir, "batterystats.bin").toString());
1361 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001362 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001363 mOnBattery = DEBUG_POWER ? true
1364 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001365 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001367 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001368 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369
Jack Palevichb90d28c2009-07-22 15:35:24 -07001370 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1371 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1372
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001373 mConfiguration.setToDefaults();
1374 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 mProcessStats.init();
1376
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001377 mCompatModePackages = new CompatModePackages(this, systemDir);
1378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 // Add ourself to the Watchdog monitors.
1380 Watchdog.getInstance().addMonitor(this);
1381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 mProcessStatsThread = new Thread("ProcessStats") {
1383 public void run() {
1384 while (true) {
1385 try {
1386 try {
1387 synchronized(this) {
1388 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001389 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 // + ", write delay=" + nextWriteDelay);
1393 if (nextWriteDelay < nextCpuDelay) {
1394 nextCpuDelay = nextWriteDelay;
1395 }
1396 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001397 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 this.wait(nextCpuDelay);
1399 }
1400 }
1401 } catch (InterruptedException e) {
1402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 updateCpuStatsNow();
1404 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001405 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
1407 }
1408 }
1409 };
1410 mProcessStatsThread.start();
1411 }
1412
1413 @Override
1414 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1415 throws RemoteException {
1416 try {
1417 return super.onTransact(code, data, reply, flags);
1418 } catch (RuntimeException e) {
1419 // The activity manager only throws security exceptions, so let's
1420 // log all others.
1421 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424 throw e;
1425 }
1426 }
1427
1428 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001429 final long now = SystemClock.uptimeMillis();
1430 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1431 return;
1432 }
1433 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1434 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 mProcessStatsThread.notify();
1436 }
1437 }
1438 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 void updateCpuStatsNow() {
1441 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001442 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 final long now = SystemClock.uptimeMillis();
1444 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001447 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1448 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 haveNewCpuStats = true;
1450 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001451 //Slog.i(TAG, mProcessStats.printCurrentState());
1452 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 // + mProcessStats.getTotalCpuPercent() + "%");
1454
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 if ("true".equals(SystemProperties.get("events.cpu"))) {
1457 int user = mProcessStats.getLastUserTime();
1458 int system = mProcessStats.getLastSystemTime();
1459 int iowait = mProcessStats.getLastIoWaitTime();
1460 int irq = mProcessStats.getLastIrqTime();
1461 int softIrq = mProcessStats.getLastSoftIrqTime();
1462 int idle = mProcessStats.getLastIdleTime();
1463
1464 int total = user + system + iowait + irq + softIrq + idle;
1465 if (total == 0) total = 1;
1466
Doug Zongker2bec3d42009-12-04 12:52:44 -08001467 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 ((user+system+iowait+irq+softIrq) * 100) / total,
1469 (user * 100) / total,
1470 (system * 100) / total,
1471 (iowait * 100) / total,
1472 (irq * 100) / total,
1473 (softIrq * 100) / total);
1474 }
1475 }
1476
Amith Yamasanie43530a2009-08-21 13:11:37 -07001477 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001478 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001479 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 synchronized(mPidsSelfLocked) {
1481 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001482 if (mOnBattery) {
1483 int perc = bstats.startAddingCpuLocked();
1484 int totalUTime = 0;
1485 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001486 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001488 ProcessStats.Stats st = mProcessStats.getStats(i);
1489 if (!st.working) {
1490 continue;
1491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001493 int otherUTime = (st.rel_utime*perc)/100;
1494 int otherSTime = (st.rel_stime*perc)/100;
1495 totalUTime += otherUTime;
1496 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 if (pr != null) {
1498 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001499 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1500 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001502 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 } else {
1504 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001505 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001506 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001507 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1508 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001509 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 }
1512 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001513 bstats.finishAddingCpuLocked(perc, totalUTime,
1514 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 }
1517 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1520 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001521 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 }
1523 }
1524 }
1525 }
1526
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001527 @Override
1528 public void batteryNeedsCpuUpdate() {
1529 updateCpuStatsNow();
1530 }
1531
1532 @Override
1533 public void batteryPowerChanged(boolean onBattery) {
1534 // When plugging in, update the CPU stats first before changing
1535 // the plug state.
1536 updateCpuStatsNow();
1537 synchronized (this) {
1538 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001539 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001540 }
1541 }
1542 }
1543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 /**
1545 * Initialize the application bind args. These are passed to each
1546 * process when the bindApplication() IPC is sent to the process. They're
1547 * lazily setup to make sure the services are running when they're asked for.
1548 */
1549 private HashMap<String, IBinder> getCommonServicesLocked() {
1550 if (mAppBindArgs == null) {
1551 mAppBindArgs = new HashMap<String, IBinder>();
1552
1553 // Setup the application init args
1554 mAppBindArgs.put("package", ServiceManager.getService("package"));
1555 mAppBindArgs.put("window", ServiceManager.getService("window"));
1556 mAppBindArgs.put(Context.ALARM_SERVICE,
1557 ServiceManager.getService(Context.ALARM_SERVICE));
1558 }
1559 return mAppBindArgs;
1560 }
1561
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001562 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if (mFocusedActivity != r) {
1564 mFocusedActivity = r;
1565 mWindowManager.setFocusedApp(r, true);
1566 }
1567 }
1568
Dianne Hackborn906497c2010-05-10 15:57:38 -07001569 private final void updateLruProcessInternalLocked(ProcessRecord app,
1570 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001572 int lrui = mLruProcesses.indexOf(app);
1573 if (lrui >= 0) mLruProcesses.remove(lrui);
1574
1575 int i = mLruProcesses.size()-1;
1576 int skipTop = 0;
1577
Dianne Hackborn906497c2010-05-10 15:57:38 -07001578 app.lruSeq = mLruSeq;
1579
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001580 // compute the new weight for this process.
1581 if (updateActivityTime) {
1582 app.lastActivityTime = SystemClock.uptimeMillis();
1583 }
1584 if (app.activities.size() > 0) {
1585 // If this process has activities, we more strongly want to keep
1586 // it around.
1587 app.lruWeight = app.lastActivityTime;
1588 } else if (app.pubProviders.size() > 0) {
1589 // If this process contains content providers, we want to keep
1590 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001591 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001592 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001593 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001594 } else {
1595 // If this process doesn't have activities, we less strongly
1596 // want to keep it around, and generally want to avoid getting
1597 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001598 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001599 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001600 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001601 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001603 while (i >= 0) {
1604 ProcessRecord p = mLruProcesses.get(i);
1605 // If this app shouldn't be in front of the first N background
1606 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001607 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001608 skipTop--;
1609 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001610 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001611 mLruProcesses.add(i+1, app);
1612 break;
1613 }
1614 i--;
1615 }
1616 if (i < 0) {
1617 mLruProcesses.add(0, app);
1618 }
1619
Dianne Hackborn906497c2010-05-10 15:57:38 -07001620 // If the app is currently using a content provider or service,
1621 // bump those processes as well.
1622 if (app.connections.size() > 0) {
1623 for (ConnectionRecord cr : app.connections) {
1624 if (cr.binding != null && cr.binding.service != null
1625 && cr.binding.service.app != null
1626 && cr.binding.service.app.lruSeq != mLruSeq) {
1627 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1628 updateActivityTime, i+1);
1629 }
1630 }
1631 }
1632 if (app.conProviders.size() > 0) {
1633 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1634 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1635 updateLruProcessInternalLocked(cpr.app, oomAdj,
1636 updateActivityTime, i+1);
1637 }
1638 }
1639 }
1640
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if (oomAdj) {
1643 updateOomAdjLocked();
1644 }
1645 }
1646
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001647 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001648 boolean oomAdj, boolean updateActivityTime) {
1649 mLruSeq++;
1650 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1651 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001652
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001653 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 String processName, int uid) {
1655 if (uid == Process.SYSTEM_UID) {
1656 // The system gets to run in any process. If there are multiple
1657 // processes with the same uid, just pick the first (this
1658 // should never happen).
1659 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1660 processName);
1661 return procs != null ? procs.valueAt(0) : null;
1662 }
1663 ProcessRecord proc = mProcessNames.get(processName, uid);
1664 return proc;
1665 }
1666
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001667 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001668 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001669 try {
1670 if (pm.performDexOpt(packageName)) {
1671 mDidDexOpt = true;
1672 }
1673 } catch (RemoteException e) {
1674 }
1675 }
1676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 int transit = mWindowManager.getPendingAppTransition();
1679 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1680 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1681 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1682 }
1683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001686 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1688 // We don't have to do anything more if:
1689 // (1) There is an existing application record; and
1690 // (2) The caller doesn't think it is dead, OR there is no thread
1691 // object attached to it so we know it couldn't have crashed; and
1692 // (3) There is a pid assigned to it, so it is either starting or
1693 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001694 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 + " app=" + app + " knownToBeDead=" + knownToBeDead
1696 + " thread=" + (app != null ? app.thread : null)
1697 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001698 if (app != null && app.pid > 0) {
1699 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001700 // We already have the app running, or are waiting for it to
1701 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001702 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001703 // If this is a new package in the process, add the package to the list
1704 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001705 return app;
1706 } else {
1707 // An application record is attached to a previous process,
1708 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001709 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001710 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 String hostingNameStr = hostingName != null
1715 ? hostingName.flattenToShortString() : null;
1716
1717 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1718 // If we are in the background, then check to see if this process
1719 // is bad. If so, we will just silently fail.
1720 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001721 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1722 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 return null;
1724 }
1725 } else {
1726 // When the user is explicitly starting a process, then clear its
1727 // crash count so that we won't make it bad until they see at
1728 // least one crash dialog again, and make the process good again
1729 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001730 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1731 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 mProcessCrashTimes.remove(info.processName, info.uid);
1733 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001734 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 info.processName);
1736 mBadProcesses.remove(info.processName, info.uid);
1737 if (app != null) {
1738 app.bad = false;
1739 }
1740 }
1741 }
1742
1743 if (app == null) {
1744 app = newProcessRecordLocked(null, info, processName);
1745 mProcessNames.put(processName, info.uid, app);
1746 } else {
1747 // If this is a new package in the process, add the package to the list
1748 app.addPackage(info.packageName);
1749 }
1750
1751 // If the system is not ready yet, then hold off on starting this
1752 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001753 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001754 && !isAllowedWhileBooting(info)
1755 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 if (!mProcessesOnHold.contains(app)) {
1757 mProcessesOnHold.add(app);
1758 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001759 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 return app;
1761 }
1762
1763 startProcessLocked(app, hostingType, hostingNameStr);
1764 return (app.pid != 0) ? app : null;
1765 }
1766
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001767 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1769 }
1770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 private final void startProcessLocked(ProcessRecord app,
1772 String hostingType, String hostingNameStr) {
1773 if (app.pid > 0 && app.pid != MY_PID) {
1774 synchronized (mPidsSelfLocked) {
1775 mPidsSelfLocked.remove(app.pid);
1776 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1777 }
1778 app.pid = 0;
1779 }
1780
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001781 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1782 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 mProcessesOnHold.remove(app);
1784
1785 updateCpuStats();
1786
1787 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1788 mProcDeaths[0] = 0;
1789
1790 try {
1791 int uid = app.info.uid;
1792 int[] gids = null;
1793 try {
1794 gids = mContext.getPackageManager().getPackageGids(
1795 app.info.packageName);
1796 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001797 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 }
1799 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1800 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1801 && mTopComponent != null
1802 && app.processName.equals(mTopComponent.getPackageName())) {
1803 uid = 0;
1804 }
1805 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1806 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1807 uid = 0;
1808 }
1809 }
1810 int debugFlags = 0;
1811 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1812 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001813 // Also turn on CheckJNI for debuggable apps. It's quite
1814 // awkward to turn on otherwise.
1815 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001817 // Run the app in safe mode if its manifest requests so or the
1818 // system is booted in safe mode.
1819 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1820 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001821 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1824 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1825 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001826 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1827 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 if ("1".equals(SystemProperties.get("debug.assert"))) {
1830 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1831 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001832
1833 // Start the process. It will either succeed and return a result containing
1834 // the PID of the new process, or else throw a RuntimeException.
1835 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001836 app.processName, uid, uid, gids, debugFlags,
1837 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1840 synchronized (bs) {
1841 if (bs.isOnBattery()) {
1842 app.batteryStats.incStartsLocked();
1843 }
1844 }
1845
Jeff Brown3f9dd282011-07-08 20:02:19 -07001846 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 app.processName, hostingType,
1848 hostingNameStr != null ? hostingNameStr : "");
1849
1850 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001851 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001854 StringBuilder buf = mStringBuilder;
1855 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 buf.append("Start proc ");
1857 buf.append(app.processName);
1858 buf.append(" for ");
1859 buf.append(hostingType);
1860 if (hostingNameStr != null) {
1861 buf.append(" ");
1862 buf.append(hostingNameStr);
1863 }
1864 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001865 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 buf.append(" uid=");
1867 buf.append(uid);
1868 buf.append(" gids={");
1869 if (gids != null) {
1870 for (int gi=0; gi<gids.length; gi++) {
1871 if (gi != 0) buf.append(", ");
1872 buf.append(gids[gi]);
1873
1874 }
1875 }
1876 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001877 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001878 app.pid = startResult.pid;
1879 app.usingWrapper = startResult.usingWrapper;
1880 app.removed = false;
1881 synchronized (mPidsSelfLocked) {
1882 this.mPidsSelfLocked.put(startResult.pid, app);
1883 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1884 msg.obj = app;
1885 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1886 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 }
1888 } catch (RuntimeException e) {
1889 // XXX do better error recovery.
1890 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001891 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 }
1893 }
1894
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001895 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 if (resumed) {
1897 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1898 } else {
1899 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1900 }
1901 }
1902
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001903 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001904 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1905 && mTopAction == null) {
1906 // We are running in factory test mode, but unable to find
1907 // the factory test app, so just sit around displaying the
1908 // error message and don't try to start anything.
1909 return false;
1910 }
1911 Intent intent = new Intent(
1912 mTopAction,
1913 mTopData != null ? Uri.parse(mTopData) : null);
1914 intent.setComponent(mTopComponent);
1915 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1916 intent.addCategory(Intent.CATEGORY_HOME);
1917 }
1918 ActivityInfo aInfo =
1919 intent.resolveActivityInfo(mContext.getPackageManager(),
1920 STOCK_PM_FLAGS);
1921 if (aInfo != null) {
1922 intent.setComponent(new ComponentName(
1923 aInfo.applicationInfo.packageName, aInfo.name));
1924 // Don't do this if the home app is currently being
1925 // instrumented.
1926 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1927 aInfo.applicationInfo.uid);
1928 if (app == null || app.instrumentationClass == null) {
1929 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001930 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001931 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001932 }
1933 }
1934
1935
1936 return true;
1937 }
1938
1939 /**
1940 * Starts the "new version setup screen" if appropriate.
1941 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001942 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001943 // Only do this once per boot.
1944 if (mCheckedForSetup) {
1945 return;
1946 }
1947
1948 // We will show this screen if the current one is a different
1949 // version than the last one shown, and we are not running in
1950 // low-level factory test mode.
1951 final ContentResolver resolver = mContext.getContentResolver();
1952 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1953 Settings.Secure.getInt(resolver,
1954 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1955 mCheckedForSetup = true;
1956
1957 // See if we should be showing the platform update setup UI.
1958 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1959 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1960 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1961
1962 // We don't allow third party apps to replace this.
1963 ResolveInfo ri = null;
1964 for (int i=0; ris != null && i<ris.size(); i++) {
1965 if ((ris.get(i).activityInfo.applicationInfo.flags
1966 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1967 ri = ris.get(i);
1968 break;
1969 }
1970 }
1971
1972 if (ri != null) {
1973 String vers = ri.activityInfo.metaData != null
1974 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1975 : null;
1976 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1977 vers = ri.activityInfo.applicationInfo.metaData.getString(
1978 Intent.METADATA_SETUP_VERSION);
1979 }
1980 String lastVers = Settings.Secure.getString(
1981 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1982 if (vers != null && !vers.equals(lastVers)) {
1983 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1984 intent.setComponent(new ComponentName(
1985 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001986 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001987 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001988 }
1989 }
1990 }
1991 }
1992
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001993 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001994 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001995 }
1996
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001997 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001998 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001999 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2000 }
2001 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002002
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002003 public void setFrontActivityScreenCompatMode(int mode) {
2004 synchronized (this) {
2005 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2006 }
2007 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002008
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002009 public int getPackageScreenCompatMode(String packageName) {
2010 synchronized (this) {
2011 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2012 }
2013 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002014
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002015 public void setPackageScreenCompatMode(String packageName, int mode) {
2016 synchronized (this) {
2017 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002018 }
2019 }
2020
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002021 public boolean getPackageAskScreenCompat(String packageName) {
2022 synchronized (this) {
2023 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2024 }
2025 }
2026
2027 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2028 synchronized (this) {
2029 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2030 }
2031 }
2032
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002033 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002034 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002035
2036 final int identHash = System.identityHashCode(r);
2037 updateUsageStats(r, true);
2038
2039 int i = mWatchers.beginBroadcast();
2040 while (i > 0) {
2041 i--;
2042 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2043 if (w != null) {
2044 try {
2045 w.activityResuming(identHash);
2046 } catch (RemoteException e) {
2047 }
2048 }
2049 }
2050 mWatchers.finishBroadcast();
2051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052
Jeff Sharkeya4620792011-05-20 15:29:23 -07002053 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2054 int i = mProcessObservers.beginBroadcast();
2055 while (i > 0) {
2056 i--;
2057 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2058 if (observer != null) {
2059 try {
2060 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2061 } catch (RemoteException e) {
2062 }
2063 }
2064 }
2065 mProcessObservers.finishBroadcast();
2066 }
2067
2068 private void dispatchProcessDied(int pid, int uid) {
2069 int i = mProcessObservers.beginBroadcast();
2070 while (i > 0) {
2071 i--;
2072 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2073 if (observer != null) {
2074 try {
2075 observer.onProcessDied(pid, uid);
2076 } catch (RemoteException e) {
2077 }
2078 }
2079 }
2080 mProcessObservers.finishBroadcast();
2081 }
2082
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002083 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002084 final int N = mPendingActivityLaunches.size();
2085 if (N <= 0) {
2086 return;
2087 }
2088 for (int i=0; i<N; i++) {
2089 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002090 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002091 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2092 doResume && i == (N-1));
2093 }
2094 mPendingActivityLaunches.clear();
2095 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002096
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002097 public final int startActivity(IApplicationThread caller,
2098 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2099 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002100 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2101 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002102 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002103 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002104 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2105 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002106 }
2107
2108 public final WaitResult startActivityAndWait(IApplicationThread caller,
2109 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2110 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002111 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2112 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002113 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002114 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002115 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002116 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2117 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002118 return res;
2119 }
2120
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002121 public final int startActivityWithConfig(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
2124 String resultWho, int requestCode, boolean onlyIfNeeded,
2125 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002126 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002127 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002128 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002129 }
2130
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002131 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002132 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002133 IBinder resultTo, String resultWho, int requestCode,
2134 int flagsMask, int flagsValues) {
2135 // Refuse possible leaked file descriptors
2136 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2137 throw new IllegalArgumentException("File descriptors passed in Intent");
2138 }
2139
2140 IIntentSender sender = intent.getTarget();
2141 if (!(sender instanceof PendingIntentRecord)) {
2142 throw new IllegalArgumentException("Bad PendingIntent object");
2143 }
2144
2145 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002146
2147 synchronized (this) {
2148 // If this is coming from the currently resumed activity, it is
2149 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002150 if (mMainStack.mResumedActivity != null
2151 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002152 Binder.getCallingUid()) {
2153 mAppSwitchesAllowedTime = 0;
2154 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002155 }
2156
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002157 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002158 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2159 }
2160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 public boolean startNextMatchingActivity(IBinder callingActivity,
2162 Intent intent) {
2163 // Refuse possible leaked file descriptors
2164 if (intent != null && intent.hasFileDescriptors() == true) {
2165 throw new IllegalArgumentException("File descriptors passed in Intent");
2166 }
2167
2168 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002169 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2170 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 return false;
2172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 if (r.app == null || r.app.thread == null) {
2174 // The caller is not running... d'oh!
2175 return false;
2176 }
2177 intent = new Intent(intent);
2178 // The caller is not allowed to change the data.
2179 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2180 // And we are resetting to find the next component...
2181 intent.setComponent(null);
2182
2183 ActivityInfo aInfo = null;
2184 try {
2185 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002186 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002188 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189
2190 // Look for the original activity in the list...
2191 final int N = resolves != null ? resolves.size() : 0;
2192 for (int i=0; i<N; i++) {
2193 ResolveInfo rInfo = resolves.get(i);
2194 if (rInfo.activityInfo.packageName.equals(r.packageName)
2195 && rInfo.activityInfo.name.equals(r.info.name)) {
2196 // We found the current one... the next matching is
2197 // after it.
2198 i++;
2199 if (i<N) {
2200 aInfo = resolves.get(i).activityInfo;
2201 }
2202 break;
2203 }
2204 }
2205 } catch (RemoteException e) {
2206 }
2207
2208 if (aInfo == null) {
2209 // Nobody who is next!
2210 return false;
2211 }
2212
2213 intent.setComponent(new ComponentName(
2214 aInfo.applicationInfo.packageName, aInfo.name));
2215 intent.setFlags(intent.getFlags()&~(
2216 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2217 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2218 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2219 Intent.FLAG_ACTIVITY_NEW_TASK));
2220
2221 // Okay now we need to start the new activity, replacing the
2222 // currently running activity. This is a little tricky because
2223 // we want to start the new one as if the current one is finished,
2224 // but not finish the current one first so that there is no flicker.
2225 // And thus...
2226 final boolean wasFinishing = r.finishing;
2227 r.finishing = true;
2228
2229 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002230 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 final String resultWho = r.resultWho;
2232 final int requestCode = r.requestCode;
2233 r.resultTo = null;
2234 if (resultTo != null) {
2235 resultTo.removeResultsLocked(r, resultWho, requestCode);
2236 }
2237
2238 final long origId = Binder.clearCallingIdentity();
2239 // XXX we are not dealing with propagating grantedUriPermissions...
2240 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002241 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002243 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 Binder.restoreCallingIdentity(origId);
2245
2246 r.finishing = wasFinishing;
2247 if (res != START_SUCCESS) {
2248 return false;
2249 }
2250 return true;
2251 }
2252 }
2253
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002254 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 Intent intent, String resolvedType, IBinder resultTo,
2256 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002257
2258 // This is so super not safe, that only the system (or okay root)
2259 // can do it.
2260 final int callingUid = Binder.getCallingUid();
2261 if (callingUid != 0 && callingUid != Process.myUid()) {
2262 throw new SecurityException(
2263 "startActivityInPackage only available to the system");
2264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002266 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002267 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2268 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002269 }
2270
2271 public final int startActivities(IApplicationThread caller,
2272 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2273 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2274 }
2275
2276 public final int startActivitiesInPackage(int uid,
2277 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2278
2279 // This is so super not safe, that only the system (or okay root)
2280 // can do it.
2281 final int callingUid = Binder.getCallingUid();
2282 if (callingUid != 0 && callingUid != Process.myUid()) {
2283 throw new SecurityException(
2284 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002287 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 }
2289
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002290 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002292 // Quick case: check if the top-most recent task is the same.
2293 if (N > 0 && mRecentTasks.get(0) == task) {
2294 return;
2295 }
2296 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 for (int i=0; i<N; i++) {
2298 TaskRecord tr = mRecentTasks.get(i);
2299 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2300 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2301 mRecentTasks.remove(i);
2302 i--;
2303 N--;
2304 if (task.intent == null) {
2305 // If the new recent task we are adding is not fully
2306 // specified, then replace it with the existing recent task.
2307 task = tr;
2308 }
2309 }
2310 }
2311 if (N >= MAX_RECENT_TASKS) {
2312 mRecentTasks.remove(N-1);
2313 }
2314 mRecentTasks.add(0, task);
2315 }
2316
2317 public void setRequestedOrientation(IBinder token,
2318 int requestedOrientation) {
2319 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002320 ActivityRecord r = mMainStack.isInStackLocked(token);
2321 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 return;
2323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 final long origId = Binder.clearCallingIdentity();
2325 mWindowManager.setAppOrientation(r, requestedOrientation);
2326 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 r.mayFreezeScreenLocked(r.app) ? r : null);
2329 if (config != null) {
2330 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002331 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002332 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 }
2334 }
2335 Binder.restoreCallingIdentity(origId);
2336 }
2337 }
2338
2339 public int getRequestedOrientation(IBinder token) {
2340 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002341 ActivityRecord r = mMainStack.isInStackLocked(token);
2342 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 return mWindowManager.getAppOrientation(r);
2346 }
2347 }
2348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 /**
2350 * This is the internal entry point for handling Activity.finish().
2351 *
2352 * @param token The Binder token referencing the Activity we want to finish.
2353 * @param resultCode Result code, if any, from this Activity.
2354 * @param resultData Result data (Intent), if any, from this Activity.
2355 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002356 * @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 -08002357 */
2358 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2359 // Refuse possible leaked file descriptors
2360 if (resultData != null && resultData.hasFileDescriptors() == true) {
2361 throw new IllegalArgumentException("File descriptors passed in Intent");
2362 }
2363
2364 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002365 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002367 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (next != null) {
2369 // ask watcher if this is allowed
2370 boolean resumeOK = true;
2371 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002372 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002374 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
2376
2377 if (!resumeOK) {
2378 return false;
2379 }
2380 }
2381 }
2382 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002383 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 resultData, "app-request");
2385 Binder.restoreCallingIdentity(origId);
2386 return res;
2387 }
2388 }
2389
Dianne Hackborn860755f2010-06-03 18:47:52 -07002390 public final void finishHeavyWeightApp() {
2391 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2392 != PackageManager.PERMISSION_GRANTED) {
2393 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2394 + Binder.getCallingPid()
2395 + ", uid=" + Binder.getCallingUid()
2396 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2397 Slog.w(TAG, msg);
2398 throw new SecurityException(msg);
2399 }
2400
2401 synchronized(this) {
2402 if (mHeavyWeightProcess == null) {
2403 return;
2404 }
2405
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002406 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002407 mHeavyWeightProcess.activities);
2408 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002409 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002410 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002411 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002412 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002413 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 null, "finish-heavy");
2415 }
2416 }
2417 }
2418
2419 mHeavyWeightProcess = null;
2420 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2421 }
2422 }
2423
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002424 public void crashApplication(int uid, int initialPid, String packageName,
2425 String message) {
2426 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2427 != PackageManager.PERMISSION_GRANTED) {
2428 String msg = "Permission Denial: crashApplication() from pid="
2429 + Binder.getCallingPid()
2430 + ", uid=" + Binder.getCallingUid()
2431 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2432 Slog.w(TAG, msg);
2433 throw new SecurityException(msg);
2434 }
2435
2436 synchronized(this) {
2437 ProcessRecord proc = null;
2438
2439 // Figure out which process to kill. We don't trust that initialPid
2440 // still has any relation to current pids, so must scan through the
2441 // list.
2442 synchronized (mPidsSelfLocked) {
2443 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2444 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2445 if (p.info.uid != uid) {
2446 continue;
2447 }
2448 if (p.pid == initialPid) {
2449 proc = p;
2450 break;
2451 }
2452 for (String str : p.pkgList) {
2453 if (str.equals(packageName)) {
2454 proc = p;
2455 }
2456 }
2457 }
2458 }
2459
2460 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002461 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002462 + " initialPid=" + initialPid
2463 + " packageName=" + packageName);
2464 return;
2465 }
2466
2467 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002468 if (proc.pid == Process.myPid()) {
2469 Log.w(TAG, "crashApplication: trying to crash self!");
2470 return;
2471 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002472 long ident = Binder.clearCallingIdentity();
2473 try {
2474 proc.thread.scheduleCrash(message);
2475 } catch (RemoteException e) {
2476 }
2477 Binder.restoreCallingIdentity(ident);
2478 }
2479 }
2480 }
2481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482 public final void finishSubActivity(IBinder token, String resultWho,
2483 int requestCode) {
2484 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002485 ActivityRecord self = mMainStack.isInStackLocked(token);
2486 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 return;
2488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489
2490 final long origId = Binder.clearCallingIdentity();
2491
2492 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2494 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 if (r.resultTo == self && r.requestCode == requestCode) {
2496 if ((r.resultWho == null && resultWho == null) ||
2497 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002498 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 Activity.RESULT_CANCELED, null, "request-sub");
2500 }
2501 }
2502 }
2503
2504 Binder.restoreCallingIdentity(origId);
2505 }
2506 }
2507
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002508 public boolean willActivityBeVisible(IBinder token) {
2509 synchronized(this) {
2510 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2512 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002513 if (r == token) {
2514 return true;
2515 }
2516 if (r.fullscreen && !r.finishing) {
2517 return false;
2518 }
2519 }
2520 return true;
2521 }
2522 }
2523
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002524 public void overridePendingTransition(IBinder token, String packageName,
2525 int enterAnim, int exitAnim) {
2526 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002527 ActivityRecord self = mMainStack.isInStackLocked(token);
2528 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002529 return;
2530 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002531
2532 final long origId = Binder.clearCallingIdentity();
2533
2534 if (self.state == ActivityState.RESUMED
2535 || self.state == ActivityState.PAUSING) {
2536 mWindowManager.overridePendingAppTransition(packageName,
2537 enterAnim, exitAnim);
2538 }
2539
2540 Binder.restoreCallingIdentity(origId);
2541 }
2542 }
2543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 * Main function for removing an existing process from the activity manager
2546 * as a result of that process going away. Clears out all connections
2547 * to the process.
2548 */
2549 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002550 boolean restarting, boolean allowRestart) {
2551 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002553 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 }
2555
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002556 if (mProfileProc == app) {
2557 clearProfilerLocked();
2558 }
2559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002561 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2562 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2563 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002565 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2566 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 }
2568
2569 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002570 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571
2572 boolean atTop = true;
2573 boolean hasVisibleActivities = false;
2574
2575 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002577 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 TAG, "Removing app " + app + " from history with " + i + " entries");
2579 while (i > 0) {
2580 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002581 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002582 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2584 if (r.app == app) {
2585 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002586 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 TAG, "Removing this entry! frozen=" + r.haveState
2588 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002589 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002590 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002591 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 mWindowManager.removeAppToken(r);
2593 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597
2598 } else {
2599 // We have the current state for this activity, so
2600 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Keeping entry, setting app to null");
2603 if (r.visible) {
2604 hasVisibleActivities = true;
2605 }
2606 r.app = null;
2607 r.nowVisible = false;
2608 if (!r.haveState) {
2609 r.icicle = null;
2610 }
2611 }
2612
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002613 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 }
2615 atTop = false;
2616 }
2617
2618 app.activities.clear();
2619
2620 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002621 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 + " running instrumentation " + app.instrumentationClass);
2623 Bundle info = new Bundle();
2624 info.putString("shortMsg", "Process crashed.");
2625 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2626 }
2627
2628 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 // If there was nothing to resume, and we are not already
2631 // restarting this process, but there is a visible activity that
2632 // is hosted by the process... then make sure all visible
2633 // activities are running, taking care of restarting this
2634 // process.
2635 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638 }
2639 }
2640 }
2641
2642 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2643 IBinder threadBinder = thread.asBinder();
2644
2645 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002646 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2647 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2649 return i;
2650 }
2651 }
2652 return -1;
2653 }
2654
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002655 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 IApplicationThread thread) {
2657 if (thread == null) {
2658 return null;
2659 }
2660
2661 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002662 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 }
2664
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002665 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 IApplicationThread thread) {
2667
2668 mProcDeaths[0]++;
2669
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002670 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2671 synchronized (stats) {
2672 stats.noteProcessDiedLocked(app.info.uid, pid);
2673 }
2674
Magnus Edlund7bb25812010-02-24 15:45:06 +01002675 // Clean up already done if the process has been re-started.
2676 if (app.pid == pid && app.thread != null &&
2677 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002678 if (!app.killedBackground) {
2679 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2680 + ") has died.");
2681 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002682 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002683 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684 TAG, "Dying app: " + app + ", pid: " + pid
2685 + ", thread: " + thread.asBinder());
2686 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002687 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688
2689 if (doLowMem) {
2690 // If there are no longer any background processes running,
2691 // and the app that died was not running instrumentation,
2692 // then tell everyone we are now low on memory.
2693 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002694 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2695 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002696 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 haveBg = true;
2698 break;
2699 }
2700 }
2701
2702 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002704 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002705 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2706 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002707 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002708 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2709 // The low memory report is overriding any current
2710 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002711 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002712 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002713 rec.lastRequestedGc = 0;
2714 } else {
2715 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002717 rec.reportLowMemory = true;
2718 rec.lastLowMemory = now;
2719 mProcessesToGc.remove(rec);
2720 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002723 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002726 } else if (app.pid != pid) {
2727 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002729 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002731 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002732 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 + thread.asBinder());
2734 }
2735 }
2736
Dan Egnor42471dd2010-01-07 17:25:22 -08002737 /**
2738 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002739 * @param clearTraces causes the dump file to be erased prior to the new
2740 * traces being written, if true; when false, the new traces will be
2741 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002742 * @param firstPids of dalvik VM processes to dump stack traces for first
2743 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002744 * @return file containing stack traces, or null if no dump file is configured
2745 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002746 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2747 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002748 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2749 if (tracesPath == null || tracesPath.length() == 0) {
2750 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002752
2753 File tracesFile = new File(tracesPath);
2754 try {
2755 File tracesDir = tracesFile.getParentFile();
2756 if (!tracesDir.exists()) tracesFile.mkdirs();
2757 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2758
Christopher Tate6ee412d2010-05-28 12:01:56 -07002759 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002760 tracesFile.createNewFile();
2761 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2762 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002764 return null;
2765 }
2766
2767 // Use a FileObserver to detect when traces finish writing.
2768 // The order of traces is considered important to maintain for legibility.
2769 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2770 public synchronized void onEvent(int event, String path) { notify(); }
2771 };
2772
2773 try {
2774 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002775
2776 // First collect all of the stacks of the most important pids.
2777 try {
2778 int num = firstPids.size();
2779 for (int i = 0; i < num; i++) {
2780 synchronized (observer) {
2781 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2782 observer.wait(200); // Wait for write-close, give up after 200msec
2783 }
2784 }
2785 } catch (InterruptedException e) {
2786 Log.wtf(TAG, e);
2787 }
2788
2789 // Next measure CPU usage.
2790 if (processStats != null) {
2791 processStats.init();
2792 System.gc();
2793 processStats.update();
2794 try {
2795 synchronized (processStats) {
2796 processStats.wait(500); // measure over 1/2 second.
2797 }
2798 } catch (InterruptedException e) {
2799 }
2800 processStats.update();
2801
2802 // We'll take the stack crawls of just the top apps using CPU.
2803 final int N = processStats.countWorkingStats();
2804 int numProcs = 0;
2805 for (int i=0; i<N && numProcs<5; i++) {
2806 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2807 if (lastPids.indexOfKey(stats.pid) >= 0) {
2808 numProcs++;
2809 try {
2810 synchronized (observer) {
2811 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2812 observer.wait(200); // Wait for write-close, give up after 200msec
2813 }
2814 } catch (InterruptedException e) {
2815 Log.wtf(TAG, e);
2816 }
2817
2818 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002819 }
2820 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002821
2822 return tracesFile;
2823
Dan Egnor42471dd2010-01-07 17:25:22 -08002824 } finally {
2825 observer.stopWatching();
2826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 }
2828
Jeff Brown4d94a762010-09-23 11:33:28 -07002829 private final class AppNotResponding implements Runnable {
2830 private final ProcessRecord mApp;
2831 private final String mAnnotation;
2832
2833 public AppNotResponding(ProcessRecord app, String annotation) {
2834 mApp = app;
2835 mAnnotation = annotation;
2836 }
2837
2838 @Override
2839 public void run() {
2840 appNotResponding(mApp, null, null, mAnnotation);
2841 }
2842 }
2843
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002844 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2845 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2847 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2848
Dianne Hackborn287952c2010-09-22 22:34:31 -07002849 if (mController != null) {
2850 try {
2851 // 0 == continue, -1 = kill process immediately
2852 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2853 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2854 } catch (RemoteException e) {
2855 mController = null;
2856 }
2857 }
2858
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002859 long anrTime = SystemClock.uptimeMillis();
2860 if (MONITOR_CPU_USAGE) {
2861 updateCpuStatsNow();
2862 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002863
2864 synchronized (this) {
2865 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2866 if (mShuttingDown) {
2867 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2868 return;
2869 } else if (app.notResponding) {
2870 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2871 return;
2872 } else if (app.crashing) {
2873 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2874 return;
2875 }
2876
2877 // In case we come through here for the same app before completing
2878 // this one, mark as anring now so we will bail out.
2879 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002880
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881 // Log the ANR to the event log.
2882 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2883 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002884
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002885 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002886 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 int parentPid = app.pid;
2889 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002890 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002891
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002892 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002893
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002894 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2895 ProcessRecord r = mLruProcesses.get(i);
2896 if (r != null && r.thread != null) {
2897 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002898 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2899 if (r.persistent) {
2900 firstPids.add(pid);
2901 } else {
2902 lastPids.put(pid, Boolean.TRUE);
2903 }
2904 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
2907 }
2908
Dan Egnor42471dd2010-01-07 17:25:22 -08002909 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002910 StringBuilder info = mStringBuilder;
2911 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002912 info.append("ANR in ").append(app.processName);
2913 if (activity != null && activity.shortComponentName != null) {
2914 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002915 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002916 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002918 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002920 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002921 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923
Dianne Hackborn287952c2010-09-22 22:34:31 -07002924 final ProcessStats processStats = new ProcessStats(true);
2925
2926 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2927
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 String cpuInfo = null;
2929 if (MONITOR_CPU_USAGE) {
2930 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002931 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002935 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 info.append(processStats.printCurrentState(anrTime));
2939
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002941 if (tracesFile == null) {
2942 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2943 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2944 }
2945
2946 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2947
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002948 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002950 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2951 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2954 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 }
2956 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002957 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 }
2959 }
2960
Dan Egnor42471dd2010-01-07 17:25:22 -08002961 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2962 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2963 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964
2965 synchronized (this) {
2966 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002967 Slog.w(TAG, "Killing " + app + ": background ANR");
2968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2969 app.processName, app.setAdj, "background ANR");
2970 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002971 return;
2972 }
2973
2974 // Set the app's notResponding state, and look up the errorReportReceiver
2975 makeAppNotRespondingLocked(app,
2976 activity != null ? activity.shortComponentName : null,
2977 annotation != null ? "ANR " + annotation : "ANR",
2978 info.toString());
2979
2980 // Bring up the infamous App Not Responding dialog
2981 Message msg = Message.obtain();
2982 HashMap map = new HashMap();
2983 msg.what = SHOW_NOT_RESPONDING_MSG;
2984 msg.obj = map;
2985 map.put("app", app);
2986 if (activity != null) {
2987 map.put("activity", activity);
2988 }
2989
2990 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002994 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2995 if (!mLaunchWarningShown) {
2996 mLaunchWarningShown = true;
2997 mHandler.post(new Runnable() {
2998 @Override
2999 public void run() {
3000 synchronized (ActivityManagerService.this) {
3001 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3002 d.show();
3003 mHandler.postDelayed(new Runnable() {
3004 @Override
3005 public void run() {
3006 synchronized (ActivityManagerService.this) {
3007 d.dismiss();
3008 mLaunchWarningShown = false;
3009 }
3010 }
3011 }, 4000);
3012 }
3013 }
3014 });
3015 }
3016 }
3017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 public boolean clearApplicationUserData(final String packageName,
3019 final IPackageDataObserver observer) {
3020 int uid = Binder.getCallingUid();
3021 int pid = Binder.getCallingPid();
3022 long callingId = Binder.clearCallingIdentity();
3023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003024 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 int pkgUid = -1;
3026 synchronized(this) {
3027 try {
3028 pkgUid = pm.getPackageUid(packageName);
3029 } catch (RemoteException e) {
3030 }
3031 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003032 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 return false;
3034 }
3035 if (uid == pkgUid || checkComponentPermission(
3036 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003037 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003039 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 } else {
3041 throw new SecurityException(pid+" does not have permission:"+
3042 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3043 "for process:"+packageName);
3044 }
3045 }
3046
3047 try {
3048 //clear application user data
3049 pm.clearApplicationUserData(packageName, observer);
3050 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3051 Uri.fromParts("package", packageName, null));
3052 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003053 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3054 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 } catch (RemoteException e) {
3056 }
3057 } finally {
3058 Binder.restoreCallingIdentity(callingId);
3059 }
3060 return true;
3061 }
3062
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 public void killBackgroundProcesses(final String packageName) {
3064 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3065 != PackageManager.PERMISSION_GRANTED &&
3066 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3067 != PackageManager.PERMISSION_GRANTED) {
3068 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 + Binder.getCallingPid()
3070 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003072 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 throw new SecurityException(msg);
3074 }
3075
3076 long callingId = Binder.clearCallingIdentity();
3077 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003078 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 int pkgUid = -1;
3080 synchronized(this) {
3081 try {
3082 pkgUid = pm.getPackageUid(packageName);
3083 } catch (RemoteException e) {
3084 }
3085 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 return;
3088 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003089 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003090 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003091 }
3092 } finally {
3093 Binder.restoreCallingIdentity(callingId);
3094 }
3095 }
3096
3097 public void forceStopPackage(final String packageName) {
3098 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3099 != PackageManager.PERMISSION_GRANTED) {
3100 String msg = "Permission Denial: forceStopPackage() from pid="
3101 + Binder.getCallingPid()
3102 + ", uid=" + Binder.getCallingUid()
3103 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003104 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003105 throw new SecurityException(msg);
3106 }
3107
3108 long callingId = Binder.clearCallingIdentity();
3109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003110 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003111 int pkgUid = -1;
3112 synchronized(this) {
3113 try {
3114 pkgUid = pm.getPackageUid(packageName);
3115 } catch (RemoteException e) {
3116 }
3117 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003118 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003119 return;
3120 }
3121 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003122 try {
3123 pm.setPackageStoppedState(packageName, true);
3124 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003125 } catch (IllegalArgumentException e) {
3126 Slog.w(TAG, "Failed trying to unstop package "
3127 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 }
3130 } finally {
3131 Binder.restoreCallingIdentity(callingId);
3132 }
3133 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003134
3135 /*
3136 * The pkg name and uid have to be specified.
3137 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3138 */
3139 public void killApplicationWithUid(String pkg, int uid) {
3140 if (pkg == null) {
3141 return;
3142 }
3143 // Make sure the uid is valid.
3144 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003146 return;
3147 }
3148 int callerUid = Binder.getCallingUid();
3149 // Only the system server can kill an application
3150 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003151 // Post an aysnc message to kill the application
3152 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3153 msg.arg1 = uid;
3154 msg.arg2 = 0;
3155 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003156 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003157 } else {
3158 throw new SecurityException(callerUid + " cannot kill pkg: " +
3159 pkg);
3160 }
3161 }
3162
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003163 public void closeSystemDialogs(String reason) {
3164 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003165 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003166 if (reason != null) {
3167 intent.putExtra("reason", reason);
3168 }
3169
3170 final int uid = Binder.getCallingUid();
3171 final long origId = Binder.clearCallingIdentity();
3172 synchronized (this) {
3173 int i = mWatchers.beginBroadcast();
3174 while (i > 0) {
3175 i--;
3176 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3177 if (w != null) {
3178 try {
3179 w.closingSystemDialogs(reason);
3180 } catch (RemoteException e) {
3181 }
3182 }
3183 }
3184 mWatchers.finishBroadcast();
3185
Dianne Hackbornffa42482009-09-23 22:20:11 -07003186 mWindowManager.closeSystemDialogs(reason);
3187
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003188 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3189 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003190 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003191 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003192 Activity.RESULT_CANCELED, null, "close-sys");
3193 }
3194 }
3195
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003196 broadcastIntentLocked(null, null, intent, null,
3197 null, 0, null, null, null, false, false, -1, uid);
3198 }
3199 Binder.restoreCallingIdentity(origId);
3200 }
3201
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003202 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003203 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003204 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3205 for (int i=pids.length-1; i>=0; i--) {
3206 infos[i] = new Debug.MemoryInfo();
3207 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003208 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003209 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003210 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003211
Dianne Hackbornb437e092011-08-05 17:50:29 -07003212 public long[] getProcessPss(int[] pids) throws RemoteException {
3213 long[] pss = new long[pids.length];
3214 for (int i=pids.length-1; i>=0; i--) {
3215 pss[i] = Debug.getPss(pids[i]);
3216 }
3217 return pss;
3218 }
3219
Christopher Tate5e1ab332009-09-01 20:32:49 -07003220 public void killApplicationProcess(String processName, int uid) {
3221 if (processName == null) {
3222 return;
3223 }
3224
3225 int callerUid = Binder.getCallingUid();
3226 // Only the system server can kill an application
3227 if (callerUid == Process.SYSTEM_UID) {
3228 synchronized (this) {
3229 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003230 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003231 try {
3232 app.thread.scheduleSuicide();
3233 } catch (RemoteException e) {
3234 // If the other end already died, then our work here is done.
3235 }
3236 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003237 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003238 + processName + " / " + uid);
3239 }
3240 }
3241 } else {
3242 throw new SecurityException(callerUid + " cannot kill app process: " +
3243 processName);
3244 }
3245 }
3246
Dianne Hackborn03abb812010-01-04 18:43:19 -08003247 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003248 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3250 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003251 if (!mProcessesReady) {
3252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 intent.putExtra(Intent.EXTRA_UID, uid);
3255 broadcastIntentLocked(null, null, intent,
3256 null, null, 0, null, null, null,
3257 false, false, MY_PID, Process.SYSTEM_UID);
3258 }
3259
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003260 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003261 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3262 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003263 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264
Dianne Hackborn03abb812010-01-04 18:43:19 -08003265 // Remove all processes this package may have touched: all with the
3266 // same UID (except for the system or root user), and all whose name
3267 // matches the package name.
3268 final String procNamePrefix = packageName + ":";
3269 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3270 final int NA = apps.size();
3271 for (int ia=0; ia<NA; ia++) {
3272 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003273 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003274 // we don't kill persistent processes
3275 continue;
3276 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003277 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003278 if (doit) {
3279 procs.add(app);
3280 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003281 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3282 || app.processName.equals(packageName)
3283 || app.processName.startsWith(procNamePrefix)) {
3284 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003285 if (!doit) {
3286 return true;
3287 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003288 app.removed = true;
3289 procs.add(app);
3290 }
3291 }
3292 }
3293 }
3294
3295 int N = procs.size();
3296 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003297 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003298 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003299 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003300 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003301
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003302 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003303 boolean callerWillRestart, boolean purgeCache, boolean doit,
3304 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003305 int i;
3306 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 if (uid < 0) {
3309 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003310 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 } catch (RemoteException e) {
3312 }
3313 }
3314
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003316 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3319 while (badApps.hasNext()) {
3320 SparseArray<Long> ba = badApps.next();
3321 if (ba.get(uid) != null) {
3322 badApps.remove();
3323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 }
3325 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326
3327 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003328 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003330 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3331 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003332 if (r.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003333 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003334 if (!doit) {
3335 return true;
3336 }
3337 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003338 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 if (r.app != null) {
3340 r.app.removed = true;
3341 }
3342 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003343 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 }
3345 }
3346
3347 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3348 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003349 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003350 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003351 if (!doit) {
3352 return true;
3353 }
3354 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003355 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 if (service.app != null) {
3357 service.app.removed = true;
3358 }
3359 service.app = null;
3360 services.add(service);
3361 }
3362 }
3363
3364 N = services.size();
3365 for (i=0; i<N; i++) {
3366 bringDownServiceLocked(services.get(i), true);
3367 }
3368
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003369 if (doit) {
3370 if (purgeCache) {
3371 AttributeCache ac = AttributeCache.instance();
3372 if (ac != null) {
3373 ac.removePackage(name);
3374 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003375 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003376 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003377 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003378
3379 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 }
3381
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003382 private final boolean removeProcessLocked(ProcessRecord app,
3383 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 final String name = app.processName;
3385 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003386 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 TAG, "Force removing process " + app + " (" + name
3388 + "/" + uid + ")");
3389
3390 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003391 if (mHeavyWeightProcess == app) {
3392 mHeavyWeightProcess = null;
3393 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003395 boolean needRestart = false;
3396 if (app.pid > 0 && app.pid != MY_PID) {
3397 int pid = app.pid;
3398 synchronized (mPidsSelfLocked) {
3399 mPidsSelfLocked.remove(pid);
3400 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3401 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003402 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003403 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 Process.killProcess(pid);
3405
3406 if (app.persistent) {
3407 if (!callerWillRestart) {
3408 addAppLocked(app.info);
3409 } else {
3410 needRestart = true;
3411 }
3412 }
3413 } else {
3414 mRemovedProcesses.add(app);
3415 }
3416
3417 return needRestart;
3418 }
3419
3420 private final void processStartTimedOutLocked(ProcessRecord app) {
3421 final int pid = app.pid;
3422 boolean gone = false;
3423 synchronized (mPidsSelfLocked) {
3424 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3425 if (knownApp != null && knownApp.thread == null) {
3426 mPidsSelfLocked.remove(pid);
3427 gone = true;
3428 }
3429 }
3430
3431 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003432 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003433 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003434 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003436 if (mHeavyWeightProcess == app) {
3437 mHeavyWeightProcess = null;
3438 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3439 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003440 // Take care of any launching providers waiting for this process.
3441 checkAppInLaunchingProvidersLocked(app, true);
3442 // Take care of any services that are waiting for the process.
3443 for (int i=0; i<mPendingServices.size(); i++) {
3444 ServiceRecord sr = mPendingServices.get(i);
3445 if (app.info.uid == sr.appInfo.uid
3446 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003447 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003448 mPendingServices.remove(i);
3449 i--;
3450 bringDownServiceLocked(sr, true);
3451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003453 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3454 app.processName, app.setAdj, "start timeout");
3455 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003456 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003457 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003458 try {
3459 IBackupManager bm = IBackupManager.Stub.asInterface(
3460 ServiceManager.getService(Context.BACKUP_SERVICE));
3461 bm.agentDisconnected(app.info.packageName);
3462 } catch (RemoteException e) {
3463 // Can't happen; the backup manager is local
3464 }
3465 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003466 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003467 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003468 mPendingBroadcast.state = BroadcastRecord.IDLE;
3469 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003470 mPendingBroadcast = null;
3471 scheduleBroadcastsLocked();
3472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003474 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 }
3476 }
3477
3478 private final boolean attachApplicationLocked(IApplicationThread thread,
3479 int pid) {
3480
3481 // Find the application record that is being attached... either via
3482 // the pid if we are running in multiple processes, or just pull the
3483 // next app record if we are emulating process with anonymous threads.
3484 ProcessRecord app;
3485 if (pid != MY_PID && pid >= 0) {
3486 synchronized (mPidsSelfLocked) {
3487 app = mPidsSelfLocked.get(pid);
3488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 } else {
3490 app = null;
3491 }
3492
3493 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003494 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003496 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003498 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003499 } else {
3500 try {
3501 thread.scheduleExit();
3502 } catch (Exception e) {
3503 // Ignore exceptions.
3504 }
3505 }
3506 return false;
3507 }
3508
3509 // If this application record is still attached to a previous
3510 // process, clean it up now.
3511 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003512 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 }
3514
3515 // Tell the process all about itself.
3516
Joe Onorato8a9b2202010-02-26 18:56:32 -08003517 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 TAG, "Binding process pid " + pid + " to record " + app);
3519
3520 String processName = app.processName;
3521 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003522 AppDeathRecipient adr = new AppDeathRecipient(
3523 app, pid, thread);
3524 thread.asBinder().linkToDeath(adr, 0);
3525 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 } catch (RemoteException e) {
3527 app.resetPackageList();
3528 startProcessLocked(app, "link fail", processName);
3529 return false;
3530 }
3531
Doug Zongker2bec3d42009-12-04 12:52:44 -08003532 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533
3534 app.thread = thread;
3535 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003536 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3537 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 app.forcingToForeground = null;
3539 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003540 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 app.debugging = false;
3542
3543 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3544
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003545 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003546 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003548 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003549 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003550 }
3551
Joe Onorato8a9b2202010-02-26 18:56:32 -08003552 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 TAG, "New app record " + app
3554 + " thread=" + thread.asBinder() + " pid=" + pid);
3555 try {
3556 int testMode = IApplicationThread.DEBUG_OFF;
3557 if (mDebugApp != null && mDebugApp.equals(processName)) {
3558 testMode = mWaitForDebugger
3559 ? IApplicationThread.DEBUG_WAIT
3560 : IApplicationThread.DEBUG_ON;
3561 app.debugging = true;
3562 if (mDebugTransient) {
3563 mDebugApp = mOrigDebugApp;
3564 mWaitForDebugger = mOrigWaitForDebugger;
3565 }
3566 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003567 String profileFile = app.instrumentationProfileFile;
3568 ParcelFileDescriptor profileFd = null;
3569 boolean profileAutoStop = false;
3570 if (mProfileApp != null && mProfileApp.equals(processName)) {
3571 mProfileProc = app;
3572 profileFile = mProfileFile;
3573 profileFd = mProfileFd;
3574 profileAutoStop = mAutoStopProfiler;
3575 }
3576
Christopher Tate181fafa2009-05-14 11:12:14 -07003577 // If the app is being launched for restore or full backup, set it up specially
3578 boolean isRestrictedBackupMode = false;
3579 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3580 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003581 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003582 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3583 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003584
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003585 ensurePackageDexOpt(app.instrumentationInfo != null
3586 ? app.instrumentationInfo.packageName
3587 : app.info.packageName);
3588 if (app.instrumentationClass != null) {
3589 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003590 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003591 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003592 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003593 ApplicationInfo appInfo = app.instrumentationInfo != null
3594 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003595 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003596 if (profileFd != null) {
3597 profileFd = profileFd.dup();
3598 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003599 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003600 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003602 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003603 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003604 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003605 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003606 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 } catch (Exception e) {
3608 // todo: Yikes! What should we do? For now we will try to
3609 // start another process, but that could easily get us in
3610 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003611 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612
3613 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003614 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 startProcessLocked(app, "bind fail", processName);
3616 return false;
3617 }
3618
3619 // Remove this record from the list of starting applications.
3620 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003621 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3622 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623 mProcessesOnHold.remove(app);
3624
3625 boolean badApp = false;
3626 boolean didSomething = false;
3627
3628 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003629 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003630 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003631 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3632 && processName.equals(hr.processName)) {
3633 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003634 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 didSomething = true;
3636 }
3637 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003638 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 + hr.intent.getComponent().flattenToShortString(), e);
3640 badApp = true;
3641 }
3642 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003643 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 }
3645 }
3646
3647 // Find any services that should be running in this process...
3648 if (!badApp && mPendingServices.size() > 0) {
3649 ServiceRecord sr = null;
3650 try {
3651 for (int i=0; i<mPendingServices.size(); i++) {
3652 sr = mPendingServices.get(i);
3653 if (app.info.uid != sr.appInfo.uid
3654 || !processName.equals(sr.processName)) {
3655 continue;
3656 }
3657
3658 mPendingServices.remove(i);
3659 i--;
3660 realStartServiceLocked(sr, app);
3661 didSomething = true;
3662 }
3663 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003664 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 + sr.shortName, e);
3666 badApp = true;
3667 }
3668 }
3669
3670 // Check if the next broadcast receiver is in this process...
3671 BroadcastRecord br = mPendingBroadcast;
3672 if (!badApp && br != null && br.curApp == app) {
3673 try {
3674 mPendingBroadcast = null;
3675 processCurBroadcastLocked(br, app);
3676 didSomething = true;
3677 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003678 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 + br.curComponent.flattenToShortString(), e);
3680 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003681 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3683 br.resultExtras, br.resultAbort, true);
3684 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003685 // We need to reset the state if we fails to start the receiver.
3686 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 }
3688 }
3689
Christopher Tate181fafa2009-05-14 11:12:14 -07003690 // Check whether the next backup agent is in this process...
3691 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003692 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003693 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003694 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003695 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3696 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3697 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003698 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003699 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003700 e.printStackTrace();
3701 }
3702 }
3703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 if (badApp) {
3705 // todo: Also need to kill application to deal with all
3706 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003707 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 return false;
3709 }
3710
3711 if (!didSomething) {
3712 updateOomAdjLocked();
3713 }
3714
3715 return true;
3716 }
3717
3718 public final void attachApplication(IApplicationThread thread) {
3719 synchronized (this) {
3720 int callingPid = Binder.getCallingPid();
3721 final long origId = Binder.clearCallingIdentity();
3722 attachApplicationLocked(thread, callingPid);
3723 Binder.restoreCallingIdentity(origId);
3724 }
3725 }
3726
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003727 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003729 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3730 if (stopProfiling) {
3731 synchronized (this) {
3732 if (mProfileProc == r.app) {
3733 if (mProfileFd != null) {
3734 try {
3735 mProfileFd.close();
3736 } catch (IOException e) {
3737 }
3738 clearProfilerLocked();
3739 }
3740 }
3741 }
3742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 Binder.restoreCallingIdentity(origId);
3744 }
3745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003747 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003748 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 mWindowManager.enableScreenAfterBoot();
3750 }
3751
Dianne Hackborn661cd522011-08-22 00:26:20 -07003752 public void showBootMessage(final CharSequence msg, final boolean always) {
3753 mWindowManager.showBootMessage(msg, always);
3754 }
3755
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003756 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003757 IntentFilter pkgFilter = new IntentFilter();
3758 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3759 pkgFilter.addDataScheme("package");
3760 mContext.registerReceiver(new BroadcastReceiver() {
3761 @Override
3762 public void onReceive(Context context, Intent intent) {
3763 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3764 if (pkgs != null) {
3765 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003766 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003767 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003768 setResultCode(Activity.RESULT_OK);
3769 return;
3770 }
3771 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003772 }
3773 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003774 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003775 }, pkgFilter);
3776
3777 synchronized (this) {
3778 // Ensure that any processes we had put on hold are now started
3779 // up.
3780 final int NP = mProcessesOnHold.size();
3781 if (NP > 0) {
3782 ArrayList<ProcessRecord> procs =
3783 new ArrayList<ProcessRecord>(mProcessesOnHold);
3784 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003785 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3786 + procs.get(ip));
3787 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003788 }
3789 }
3790
3791 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003792 // Start looking for apps that are abusing wake locks.
3793 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003794 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003795 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003796 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003797 broadcastIntentLocked(null, null,
3798 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3799 null, null, 0, null, null,
3800 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3801 false, false, MY_PID, Process.SYSTEM_UID);
3802 }
3803 }
3804 }
3805
3806 final void ensureBootCompleted() {
3807 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003808 boolean enableScreen;
3809 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003810 booting = mBooting;
3811 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003812 enableScreen = !mBooted;
3813 mBooted = true;
3814 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003815
3816 if (booting) {
3817 finishBooting();
3818 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003819
3820 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003821 enableScreenAfterBoot();
3822 }
3823 }
3824
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003825 public final void activityPaused(IBinder token) {
3826 final long origId = Binder.clearCallingIdentity();
3827 mMainStack.activityPaused(token, false);
3828 Binder.restoreCallingIdentity(origId);
3829 }
3830
3831 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3832 CharSequence description) {
3833 if (localLOGV) Slog.v(
3834 TAG, "Activity stopped: token=" + token);
3835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 // Refuse possible leaked file descriptors
3837 if (icicle != null && icicle.hasFileDescriptors()) {
3838 throw new IllegalArgumentException("File descriptors passed in Bundle");
3839 }
3840
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003841 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842
3843 final long origId = Binder.clearCallingIdentity();
3844
3845 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003846 r = mMainStack.isInStackLocked(token);
3847 if (r != null) {
3848 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 }
3850 }
3851
3852 if (r != null) {
3853 sendPendingThumbnail(r, null, null, null, false);
3854 }
3855
3856 trimApplications();
3857
3858 Binder.restoreCallingIdentity(origId);
3859 }
3860
3861 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003862 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003863 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 }
3865
3866 public String getCallingPackage(IBinder token) {
3867 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003868 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003869 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 }
3871 }
3872
3873 public ComponentName getCallingActivity(IBinder token) {
3874 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003875 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 return r != null ? r.intent.getComponent() : null;
3877 }
3878 }
3879
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003880 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003881 ActivityRecord r = mMainStack.isInStackLocked(token);
3882 if (r == null) {
3883 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003884 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003885 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 }
3887
3888 public ComponentName getActivityClassForToken(IBinder token) {
3889 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003890 ActivityRecord r = mMainStack.isInStackLocked(token);
3891 if (r == null) {
3892 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003893 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003894 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 }
3896 }
3897
3898 public String getPackageForToken(IBinder token) {
3899 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003900 ActivityRecord r = mMainStack.isInStackLocked(token);
3901 if (r == null) {
3902 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003904 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 }
3906 }
3907
3908 public IIntentSender getIntentSender(int type,
3909 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003910 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003912 if (intents != null) {
3913 if (intents.length < 1) {
3914 throw new IllegalArgumentException("Intents array length must be >= 1");
3915 }
3916 for (int i=0; i<intents.length; i++) {
3917 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003918 if (intent != null) {
3919 if (intent.hasFileDescriptors()) {
3920 throw new IllegalArgumentException("File descriptors passed in Intent");
3921 }
3922 if (type == INTENT_SENDER_BROADCAST &&
3923 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3924 throw new IllegalArgumentException(
3925 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3926 }
3927 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003928 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003929 }
3930 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003931 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003932 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003933 }
3934 }
3935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 synchronized(this) {
3937 int callingUid = Binder.getCallingUid();
3938 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003939 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003940 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 .getPackageUid(packageName);
3942 if (uid != Binder.getCallingUid()) {
3943 String msg = "Permission Denial: getIntentSender() from pid="
3944 + Binder.getCallingPid()
3945 + ", uid=" + Binder.getCallingUid()
3946 + ", (need uid=" + uid + ")"
3947 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003948 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 throw new SecurityException(msg);
3950 }
3951 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003952
3953 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003954 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 } catch (RemoteException e) {
3957 throw new SecurityException(e);
3958 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003959 }
3960 }
3961
3962 IIntentSender getIntentSenderLocked(int type,
3963 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003964 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003965 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003966 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003967 activity = mMainStack.isInStackLocked(token);
3968 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003969 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003971 if (activity.finishing) {
3972 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003974 }
3975
3976 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3977 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3978 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3979 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3980 |PendingIntent.FLAG_UPDATE_CURRENT);
3981
3982 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3983 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003984 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003985 WeakReference<PendingIntentRecord> ref;
3986 ref = mIntentSenderRecords.get(key);
3987 PendingIntentRecord rec = ref != null ? ref.get() : null;
3988 if (rec != null) {
3989 if (!cancelCurrent) {
3990 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003991 if (rec.key.requestIntent != null) {
3992 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3993 }
3994 if (intents != null) {
3995 intents[intents.length-1] = rec.key.requestIntent;
3996 rec.key.allIntents = intents;
3997 rec.key.allResolvedTypes = resolvedTypes;
3998 } else {
3999 rec.key.allIntents = null;
4000 rec.key.allResolvedTypes = null;
4001 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 return rec;
4004 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004005 rec.canceled = true;
4006 mIntentSenderRecords.remove(key);
4007 }
4008 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 return rec;
4010 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004011 rec = new PendingIntentRecord(this, key, callingUid);
4012 mIntentSenderRecords.put(key, rec.ref);
4013 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4014 if (activity.pendingResults == null) {
4015 activity.pendingResults
4016 = new HashSet<WeakReference<PendingIntentRecord>>();
4017 }
4018 activity.pendingResults.add(rec.ref);
4019 }
4020 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 }
4022
4023 public void cancelIntentSender(IIntentSender sender) {
4024 if (!(sender instanceof PendingIntentRecord)) {
4025 return;
4026 }
4027 synchronized(this) {
4028 PendingIntentRecord rec = (PendingIntentRecord)sender;
4029 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004030 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 .getPackageUid(rec.key.packageName);
4032 if (uid != Binder.getCallingUid()) {
4033 String msg = "Permission Denial: cancelIntentSender() from pid="
4034 + Binder.getCallingPid()
4035 + ", uid=" + Binder.getCallingUid()
4036 + " is not allowed to cancel packges "
4037 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004038 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 throw new SecurityException(msg);
4040 }
4041 } catch (RemoteException e) {
4042 throw new SecurityException(e);
4043 }
4044 cancelIntentSenderLocked(rec, true);
4045 }
4046 }
4047
4048 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4049 rec.canceled = true;
4050 mIntentSenderRecords.remove(rec.key);
4051 if (cleanActivity && rec.key.activity != null) {
4052 rec.key.activity.pendingResults.remove(rec.ref);
4053 }
4054 }
4055
4056 public String getPackageForIntentSender(IIntentSender pendingResult) {
4057 if (!(pendingResult instanceof PendingIntentRecord)) {
4058 return null;
4059 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004060 try {
4061 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4062 return res.key.packageName;
4063 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 }
4065 return null;
4066 }
4067
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004068 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4069 if (!(pendingResult instanceof PendingIntentRecord)) {
4070 return false;
4071 }
4072 try {
4073 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4074 if (res.key.allIntents == null) {
4075 return false;
4076 }
4077 for (int i=0; i<res.key.allIntents.length; i++) {
4078 Intent intent = res.key.allIntents[i];
4079 if (intent.getPackage() != null && intent.getComponent() != null) {
4080 return false;
4081 }
4082 }
4083 return true;
4084 } catch (ClassCastException e) {
4085 }
4086 return false;
4087 }
4088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 public void setProcessLimit(int max) {
4090 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4091 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004092 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004093 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004094 mProcessLimitOverride = max;
4095 }
4096 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 }
4098
4099 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004100 synchronized (this) {
4101 return mProcessLimitOverride;
4102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103 }
4104
4105 void foregroundTokenDied(ForegroundToken token) {
4106 synchronized (ActivityManagerService.this) {
4107 synchronized (mPidsSelfLocked) {
4108 ForegroundToken cur
4109 = mForegroundProcesses.get(token.pid);
4110 if (cur != token) {
4111 return;
4112 }
4113 mForegroundProcesses.remove(token.pid);
4114 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4115 if (pr == null) {
4116 return;
4117 }
4118 pr.forcingToForeground = null;
4119 pr.foregroundServices = false;
4120 }
4121 updateOomAdjLocked();
4122 }
4123 }
4124
4125 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4126 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4127 "setProcessForeground()");
4128 synchronized(this) {
4129 boolean changed = false;
4130
4131 synchronized (mPidsSelfLocked) {
4132 ProcessRecord pr = mPidsSelfLocked.get(pid);
4133 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004134 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 return;
4136 }
4137 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4138 if (oldToken != null) {
4139 oldToken.token.unlinkToDeath(oldToken, 0);
4140 mForegroundProcesses.remove(pid);
4141 pr.forcingToForeground = null;
4142 changed = true;
4143 }
4144 if (isForeground && token != null) {
4145 ForegroundToken newToken = new ForegroundToken() {
4146 public void binderDied() {
4147 foregroundTokenDied(this);
4148 }
4149 };
4150 newToken.pid = pid;
4151 newToken.token = token;
4152 try {
4153 token.linkToDeath(newToken, 0);
4154 mForegroundProcesses.put(pid, newToken);
4155 pr.forcingToForeground = token;
4156 changed = true;
4157 } catch (RemoteException e) {
4158 // If the process died while doing this, we will later
4159 // do the cleanup with the process death link.
4160 }
4161 }
4162 }
4163
4164 if (changed) {
4165 updateOomAdjLocked();
4166 }
4167 }
4168 }
4169
4170 // =========================================================
4171 // PERMISSIONS
4172 // =========================================================
4173
4174 static class PermissionController extends IPermissionController.Stub {
4175 ActivityManagerService mActivityManagerService;
4176 PermissionController(ActivityManagerService activityManagerService) {
4177 mActivityManagerService = activityManagerService;
4178 }
4179
4180 public boolean checkPermission(String permission, int pid, int uid) {
4181 return mActivityManagerService.checkPermission(permission, pid,
4182 uid) == PackageManager.PERMISSION_GRANTED;
4183 }
4184 }
4185
4186 /**
4187 * This can be called with or without the global lock held.
4188 */
4189 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004190 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 // We might be performing an operation on behalf of an indirect binder
4192 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4193 // client identity accordingly before proceeding.
4194 Identity tlsIdentity = sCallerIdentity.get();
4195 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004196 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4198 uid = tlsIdentity.uid;
4199 pid = tlsIdentity.pid;
4200 }
4201
4202 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004203 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004204 return PackageManager.PERMISSION_GRANTED;
4205 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004206 // If there is a uid that owns whatever is being accessed, it has
4207 // blanket access to it regardless of the permissions it requires.
4208 if (owningUid >= 0 && uid == owningUid) {
4209 return PackageManager.PERMISSION_GRANTED;
4210 }
4211 // If the target is not exported, then nobody else can get to it.
4212 if (!exported) {
4213 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004214 return PackageManager.PERMISSION_DENIED;
4215 }
4216 if (permission == null) {
4217 return PackageManager.PERMISSION_GRANTED;
4218 }
4219 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004220 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004221 .checkUidPermission(permission, uid);
4222 } catch (RemoteException e) {
4223 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004224 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 }
4226 return PackageManager.PERMISSION_DENIED;
4227 }
4228
4229 /**
4230 * As the only public entry point for permissions checking, this method
4231 * can enforce the semantic that requesting a check on a null global
4232 * permission is automatically denied. (Internally a null permission
4233 * string is used when calling {@link #checkComponentPermission} in cases
4234 * when only uid-based security is needed.)
4235 *
4236 * This can be called with or without the global lock held.
4237 */
4238 public int checkPermission(String permission, int pid, int uid) {
4239 if (permission == null) {
4240 return PackageManager.PERMISSION_DENIED;
4241 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004242 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004243 }
4244
4245 /**
4246 * Binder IPC calls go through the public entry point.
4247 * This can be called with or without the global lock held.
4248 */
4249 int checkCallingPermission(String permission) {
4250 return checkPermission(permission,
4251 Binder.getCallingPid(),
4252 Binder.getCallingUid());
4253 }
4254
4255 /**
4256 * This can be called with or without the global lock held.
4257 */
4258 void enforceCallingPermission(String permission, String func) {
4259 if (checkCallingPermission(permission)
4260 == PackageManager.PERMISSION_GRANTED) {
4261 return;
4262 }
4263
4264 String msg = "Permission Denial: " + func + " from pid="
4265 + Binder.getCallingPid()
4266 + ", uid=" + Binder.getCallingUid()
4267 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004268 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 throw new SecurityException(msg);
4270 }
4271
4272 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004273 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4274 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4275 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4276 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4277 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004279 // Is the component private from the target uid?
4280 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4281
4282 // Acceptable if the there is no read permission needed from the
4283 // target or the target is holding the read permission.
4284 if (!readPerm) {
4285 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004287 == PackageManager.PERMISSION_GRANTED)) {
4288 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 }
4290 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004291
4292 // Acceptable if the there is no write permission needed from the
4293 // target or the target is holding the read permission.
4294 if (!writePerm) {
4295 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004297 == PackageManager.PERMISSION_GRANTED)) {
4298 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 }
4300 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004301
4302 // Acceptable if there is a path permission matching the URI that
4303 // the target holds the permission on.
4304 PathPermission[] pps = pi.pathPermissions;
4305 if (pps != null && (!readPerm || !writePerm)) {
4306 final String path = uri.getPath();
4307 int i = pps.length;
4308 while (i > 0 && (!readPerm || !writePerm)) {
4309 i--;
4310 PathPermission pp = pps[i];
4311 if (!readPerm) {
4312 final String pprperm = pp.getReadPermission();
4313 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4314 + pprperm + " for " + pp.getPath()
4315 + ": match=" + pp.match(path)
4316 + " check=" + pm.checkUidPermission(pprperm, uid));
4317 if (pprperm != null && pp.match(path) &&
4318 (pm.checkUidPermission(pprperm, uid)
4319 == PackageManager.PERMISSION_GRANTED)) {
4320 readPerm = true;
4321 }
4322 }
4323 if (!writePerm) {
4324 final String ppwperm = pp.getWritePermission();
4325 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4326 + ppwperm + " for " + pp.getPath()
4327 + ": match=" + pp.match(path)
4328 + " check=" + pm.checkUidPermission(ppwperm, uid));
4329 if (ppwperm != null && pp.match(path) &&
4330 (pm.checkUidPermission(ppwperm, uid)
4331 == PackageManager.PERMISSION_GRANTED)) {
4332 writePerm = true;
4333 }
4334 }
4335 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 } catch (RemoteException e) {
4338 return false;
4339 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004340
4341 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342 }
4343
4344 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4345 int modeFlags) {
4346 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004347 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 return true;
4349 }
4350 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4351 if (perms == null) return false;
4352 UriPermission perm = perms.get(uri);
4353 if (perm == null) return false;
4354 return (modeFlags&perm.modeFlags) == modeFlags;
4355 }
4356
4357 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4358 // Another redirected-binder-call permissions check as in
4359 // {@link checkComponentPermission}.
4360 Identity tlsIdentity = sCallerIdentity.get();
4361 if (tlsIdentity != null) {
4362 uid = tlsIdentity.uid;
4363 pid = tlsIdentity.pid;
4364 }
4365
4366 // Our own process gets to do everything.
4367 if (pid == MY_PID) {
4368 return PackageManager.PERMISSION_GRANTED;
4369 }
4370 synchronized(this) {
4371 return checkUriPermissionLocked(uri, uid, modeFlags)
4372 ? PackageManager.PERMISSION_GRANTED
4373 : PackageManager.PERMISSION_DENIED;
4374 }
4375 }
4376
Dianne Hackborn39792d22010-08-19 18:01:52 -07004377 /**
4378 * Check if the targetPkg can be granted permission to access uri by
4379 * the callingUid using the given modeFlags. Throws a security exception
4380 * if callingUid is not allowed to do this. Returns the uid of the target
4381 * if the URI permission grant should be performed; returns -1 if it is not
4382 * needed (for example targetPkg already has permission to access the URI).
4383 */
4384 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4385 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4387 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4388 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004389 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 }
4391
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004392 if (targetPkg != null) {
4393 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4394 "Checking grant " + targetPkg + " permission to " + uri);
4395 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004396
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004397 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398
4399 // If this is not a content: uri, we can't do anything with it.
4400 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004401 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004402 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004403 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 }
4405
4406 String name = uri.getAuthority();
4407 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004408 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 if (cpr != null) {
4410 pi = cpr.info;
4411 } else {
4412 try {
4413 pi = pm.resolveContentProvider(name,
4414 PackageManager.GET_URI_PERMISSION_PATTERNS);
4415 } catch (RemoteException ex) {
4416 }
4417 }
4418 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004419 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004420 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 }
4422
4423 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004424 if (targetPkg != null) {
4425 try {
4426 targetUid = pm.getPackageUid(targetPkg);
4427 if (targetUid < 0) {
4428 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4429 "Can't grant URI permission no uid for: " + targetPkg);
4430 return -1;
4431 }
4432 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004433 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004435 } else {
4436 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004439 if (targetUid >= 0) {
4440 // First... does the target actually need this permission?
4441 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4442 // No need to grant the target this permission.
4443 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4444 "Target " + targetPkg + " already has full permission to " + uri);
4445 return -1;
4446 }
4447 } else {
4448 // First... there is no target package, so can anyone access it?
4449 boolean allowed = pi.exported;
4450 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4451 if (pi.readPermission != null) {
4452 allowed = false;
4453 }
4454 }
4455 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4456 if (pi.writePermission != null) {
4457 allowed = false;
4458 }
4459 }
4460 if (allowed) {
4461 return -1;
4462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 }
4464
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004465 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 if (!pi.grantUriPermissions) {
4467 throw new SecurityException("Provider " + pi.packageName
4468 + "/" + pi.name
4469 + " does not allow granting of Uri permissions (uri "
4470 + uri + ")");
4471 }
4472 if (pi.uriPermissionPatterns != null) {
4473 final int N = pi.uriPermissionPatterns.length;
4474 boolean allowed = false;
4475 for (int i=0; i<N; i++) {
4476 if (pi.uriPermissionPatterns[i] != null
4477 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4478 allowed = true;
4479 break;
4480 }
4481 }
4482 if (!allowed) {
4483 throw new SecurityException("Provider " + pi.packageName
4484 + "/" + pi.name
4485 + " does not allow granting of permission to path of Uri "
4486 + uri);
4487 }
4488 }
4489
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004490 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004492 if (callingUid != Process.myUid()) {
4493 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4494 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4495 throw new SecurityException("Uid " + callingUid
4496 + " does not have permission to uri " + uri);
4497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 }
4499 }
4500
Dianne Hackborn39792d22010-08-19 18:01:52 -07004501 return targetUid;
4502 }
4503
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004504 public int checkGrantUriPermission(int callingUid, String targetPkg,
4505 Uri uri, int modeFlags) {
4506 synchronized(this) {
4507 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4508 }
4509 }
4510
Dianne Hackborn39792d22010-08-19 18:01:52 -07004511 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4512 Uri uri, int modeFlags, UriPermissionOwner owner) {
4513 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4514 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4515 if (modeFlags == 0) {
4516 return;
4517 }
4518
4519 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 // to the uri, and the target doesn't. Let's now give this to
4521 // the target.
4522
Joe Onorato8a9b2202010-02-26 18:56:32 -08004523 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004524 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 HashMap<Uri, UriPermission> targetUris
4527 = mGrantedUriPermissions.get(targetUid);
4528 if (targetUris == null) {
4529 targetUris = new HashMap<Uri, UriPermission>();
4530 mGrantedUriPermissions.put(targetUid, targetUris);
4531 }
4532
4533 UriPermission perm = targetUris.get(uri);
4534 if (perm == null) {
4535 perm = new UriPermission(targetUid, uri);
4536 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004537 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004540 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004542 } else {
4543 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4544 perm.readOwners.add(owner);
4545 owner.addReadPermission(perm);
4546 }
4547 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4548 perm.writeOwners.add(owner);
4549 owner.addWritePermission(perm);
4550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 }
4552 }
4553
Dianne Hackborn39792d22010-08-19 18:01:52 -07004554 void grantUriPermissionLocked(int callingUid,
4555 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004556 if (targetPkg == null) {
4557 throw new NullPointerException("targetPkg");
4558 }
4559
Dianne Hackborn39792d22010-08-19 18:01:52 -07004560 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4561 if (targetUid < 0) {
4562 return;
4563 }
4564
4565 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4566 }
4567
4568 /**
4569 * Like checkGrantUriPermissionLocked, but takes an Intent.
4570 */
4571 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4572 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004573 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004574 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004575 + " from " + intent + "; flags=0x"
4576 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4577
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004578 if (targetPkg == null) {
4579 throw new NullPointerException("targetPkg");
4580 }
4581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004583 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 }
4585 Uri data = intent.getData();
4586 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004587 return -1;
4588 }
4589 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4590 intent.getFlags());
4591 }
4592
4593 /**
4594 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4595 */
4596 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4597 String targetPkg, Intent intent, UriPermissionOwner owner) {
4598 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4599 intent.getFlags(), owner);
4600 }
4601
4602 void grantUriPermissionFromIntentLocked(int callingUid,
4603 String targetPkg, Intent intent, UriPermissionOwner owner) {
4604 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4605 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 return;
4607 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004608
4609 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 }
4611
4612 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4613 Uri uri, int modeFlags) {
4614 synchronized(this) {
4615 final ProcessRecord r = getRecordForAppLocked(caller);
4616 if (r == null) {
4617 throw new SecurityException("Unable to find app for caller "
4618 + caller
4619 + " when granting permission to uri " + uri);
4620 }
4621 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004622 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 }
4624 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004625 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627
4628 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4629 null);
4630 }
4631 }
4632
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004633 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4635 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4636 HashMap<Uri, UriPermission> perms
4637 = mGrantedUriPermissions.get(perm.uid);
4638 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004639 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004640 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 perms.remove(perm.uri);
4642 if (perms.size() == 0) {
4643 mGrantedUriPermissions.remove(perm.uid);
4644 }
4645 }
4646 }
4647 }
4648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004649 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4650 int modeFlags) {
4651 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4652 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4653 if (modeFlags == 0) {
4654 return;
4655 }
4656
Joe Onorato8a9b2202010-02-26 18:56:32 -08004657 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004658 "Revoking all granted permissions to " + uri);
4659
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004660 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661
4662 final String authority = uri.getAuthority();
4663 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004664 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004665 if (cpr != null) {
4666 pi = cpr.info;
4667 } else {
4668 try {
4669 pi = pm.resolveContentProvider(authority,
4670 PackageManager.GET_URI_PERMISSION_PATTERNS);
4671 } catch (RemoteException ex) {
4672 }
4673 }
4674 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004675 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 return;
4677 }
4678
4679 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004680 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 // Right now, if you are not the original owner of the permission,
4682 // you are not allowed to revoke it.
4683 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4684 throw new SecurityException("Uid " + callingUid
4685 + " does not have permission to uri " + uri);
4686 //}
4687 }
4688
4689 // Go through all of the permissions and remove any that match.
4690 final List<String> SEGMENTS = uri.getPathSegments();
4691 if (SEGMENTS != null) {
4692 final int NS = SEGMENTS.size();
4693 int N = mGrantedUriPermissions.size();
4694 for (int i=0; i<N; i++) {
4695 HashMap<Uri, UriPermission> perms
4696 = mGrantedUriPermissions.valueAt(i);
4697 Iterator<UriPermission> it = perms.values().iterator();
4698 toploop:
4699 while (it.hasNext()) {
4700 UriPermission perm = it.next();
4701 Uri targetUri = perm.uri;
4702 if (!authority.equals(targetUri.getAuthority())) {
4703 continue;
4704 }
4705 List<String> targetSegments = targetUri.getPathSegments();
4706 if (targetSegments == null) {
4707 continue;
4708 }
4709 if (targetSegments.size() < NS) {
4710 continue;
4711 }
4712 for (int j=0; j<NS; j++) {
4713 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4714 continue toploop;
4715 }
4716 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004717 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004718 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 perm.clearModes(modeFlags);
4720 if (perm.modeFlags == 0) {
4721 it.remove();
4722 }
4723 }
4724 if (perms.size() == 0) {
4725 mGrantedUriPermissions.remove(
4726 mGrantedUriPermissions.keyAt(i));
4727 N--;
4728 i--;
4729 }
4730 }
4731 }
4732 }
4733
4734 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4735 int modeFlags) {
4736 synchronized(this) {
4737 final ProcessRecord r = getRecordForAppLocked(caller);
4738 if (r == null) {
4739 throw new SecurityException("Unable to find app for caller "
4740 + caller
4741 + " when revoking permission to uri " + uri);
4742 }
4743 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004744 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 return;
4746 }
4747
4748 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4749 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4750 if (modeFlags == 0) {
4751 return;
4752 }
4753
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004754 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755
4756 final String authority = uri.getAuthority();
4757 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004758 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 if (cpr != null) {
4760 pi = cpr.info;
4761 } else {
4762 try {
4763 pi = pm.resolveContentProvider(authority,
4764 PackageManager.GET_URI_PERMISSION_PATTERNS);
4765 } catch (RemoteException ex) {
4766 }
4767 }
4768 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004769 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 return;
4771 }
4772
4773 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4774 }
4775 }
4776
Dianne Hackborn7e269642010-08-25 19:50:20 -07004777 @Override
4778 public IBinder newUriPermissionOwner(String name) {
4779 synchronized(this) {
4780 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4781 return owner.getExternalTokenLocked();
4782 }
4783 }
4784
4785 @Override
4786 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4787 Uri uri, int modeFlags) {
4788 synchronized(this) {
4789 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4790 if (owner == null) {
4791 throw new IllegalArgumentException("Unknown owner: " + token);
4792 }
4793 if (fromUid != Binder.getCallingUid()) {
4794 if (Binder.getCallingUid() != Process.myUid()) {
4795 // Only system code can grant URI permissions on behalf
4796 // of other users.
4797 throw new SecurityException("nice try");
4798 }
4799 }
4800 if (targetPkg == null) {
4801 throw new IllegalArgumentException("null target");
4802 }
4803 if (uri == null) {
4804 throw new IllegalArgumentException("null uri");
4805 }
4806
4807 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4808 }
4809 }
4810
4811 @Override
4812 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4813 synchronized(this) {
4814 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4815 if (owner == null) {
4816 throw new IllegalArgumentException("Unknown owner: " + token);
4817 }
4818
4819 if (uri == null) {
4820 owner.removeUriPermissionsLocked(mode);
4821 } else {
4822 owner.removeUriPermissionLocked(uri, mode);
4823 }
4824 }
4825 }
4826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4828 synchronized (this) {
4829 ProcessRecord app =
4830 who != null ? getRecordForAppLocked(who) : null;
4831 if (app == null) return;
4832
4833 Message msg = Message.obtain();
4834 msg.what = WAIT_FOR_DEBUGGER_MSG;
4835 msg.obj = app;
4836 msg.arg1 = waiting ? 1 : 0;
4837 mHandler.sendMessage(msg);
4838 }
4839 }
4840
4841 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004842 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4843 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004845 outInfo.threshold = homeAppMem;
4846 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4847 outInfo.hiddenAppThreshold = hiddenAppMem;
4848 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4849 ProcessList.SECONDARY_SERVER_ADJ);
4850 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4851 ProcessList.VISIBLE_APP_ADJ);
4852 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4853 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 }
4855
4856 // =========================================================
4857 // TASK MANAGEMENT
4858 // =========================================================
4859
4860 public List getTasks(int maxNum, int flags,
4861 IThumbnailReceiver receiver) {
4862 ArrayList list = new ArrayList();
4863
4864 PendingThumbnailsRecord pending = null;
4865 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004866 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867
4868 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004869 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4871 + ", receiver=" + receiver);
4872
4873 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4874 != PackageManager.PERMISSION_GRANTED) {
4875 if (receiver != null) {
4876 // If the caller wants to wait for pending thumbnails,
4877 // it ain't gonna get them.
4878 try {
4879 receiver.finished();
4880 } catch (RemoteException ex) {
4881 }
4882 }
4883 String msg = "Permission Denial: getTasks() from pid="
4884 + Binder.getCallingPid()
4885 + ", uid=" + Binder.getCallingUid()
4886 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004887 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 throw new SecurityException(msg);
4889 }
4890
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004891 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004892 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004893 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004894 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 TaskRecord curTask = null;
4896 int numActivities = 0;
4897 int numRunning = 0;
4898 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004899 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004901 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004902
4903 // Initialize state for next task if needed.
4904 if (top == null ||
4905 (top.state == ActivityState.INITIALIZING
4906 && top.task == r.task)) {
4907 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 curTask = r.task;
4909 numActivities = numRunning = 0;
4910 }
4911
4912 // Add 'r' into the current task.
4913 numActivities++;
4914 if (r.app != null && r.app.thread != null) {
4915 numRunning++;
4916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917
Joe Onorato8a9b2202010-02-26 18:56:32 -08004918 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 TAG, r.intent.getComponent().flattenToShortString()
4920 + ": task=" + r.task);
4921
4922 // If the next one is a different task, generate a new
4923 // TaskInfo entry for what we have.
4924 if (next == null || next.task != curTask) {
4925 ActivityManager.RunningTaskInfo ci
4926 = new ActivityManager.RunningTaskInfo();
4927 ci.id = curTask.taskId;
4928 ci.baseActivity = r.intent.getComponent();
4929 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004930 if (top.thumbHolder != null) {
4931 ci.description = top.thumbHolder.lastDescription;
4932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 ci.numActivities = numActivities;
4934 ci.numRunning = numRunning;
4935 //System.out.println(
4936 // "#" + maxNum + ": " + " descr=" + ci.description);
4937 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004938 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939 TAG, "State=" + top.state + "Idle=" + top.idle
4940 + " app=" + top.app
4941 + " thr=" + (top.app != null ? top.app.thread : null));
4942 if (top.state == ActivityState.RESUMED
4943 || top.state == ActivityState.PAUSING) {
4944 if (top.idle && top.app != null
4945 && top.app.thread != null) {
4946 topRecord = top;
4947 topThumbnail = top.app.thread;
4948 } else {
4949 top.thumbnailNeeded = true;
4950 }
4951 }
4952 if (pending == null) {
4953 pending = new PendingThumbnailsRecord(receiver);
4954 }
4955 pending.pendingRecords.add(top);
4956 }
4957 list.add(ci);
4958 maxNum--;
4959 top = null;
4960 }
4961 }
4962
4963 if (pending != null) {
4964 mPendingThumbnails.add(pending);
4965 }
4966 }
4967
Joe Onorato8a9b2202010-02-26 18:56:32 -08004968 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969
4970 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004971 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972 try {
4973 topThumbnail.requestThumbnail(topRecord);
4974 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004975 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 sendPendingThumbnail(null, topRecord, null, null, true);
4977 }
4978 }
4979
4980 if (pending == null && receiver != null) {
4981 // In this case all thumbnails were available and the client
4982 // is being asked to be told when the remaining ones come in...
4983 // which is unusually, since the top-most currently running
4984 // activity should never have a canned thumbnail! Oh well.
4985 try {
4986 receiver.finished();
4987 } catch (RemoteException ex) {
4988 }
4989 }
4990
4991 return list;
4992 }
4993
4994 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4995 int flags) {
4996 synchronized (this) {
4997 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4998 "getRecentTasks()");
4999
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005000 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 final int N = mRecentTasks.size();
5003 ArrayList<ActivityManager.RecentTaskInfo> res
5004 = new ArrayList<ActivityManager.RecentTaskInfo>(
5005 maxNum < N ? maxNum : N);
5006 for (int i=0; i<N && maxNum > 0; i++) {
5007 TaskRecord tr = mRecentTasks.get(i);
5008 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5009 || (tr.intent == null)
5010 || ((tr.intent.getFlags()
5011 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5012 ActivityManager.RecentTaskInfo rti
5013 = new ActivityManager.RecentTaskInfo();
5014 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005015 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005016 rti.baseIntent = new Intent(
5017 tr.intent != null ? tr.intent : tr.affinityIntent);
5018 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005019 rti.description = tr.lastDescription;
5020
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005021 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5022 // Check whether this activity is currently available.
5023 try {
5024 if (rti.origActivity != null) {
5025 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5026 continue;
5027 }
5028 } else if (rti.baseIntent != null) {
5029 if (pm.queryIntentActivities(rti.baseIntent,
5030 null, 0) == null) {
5031 continue;
5032 }
5033 }
5034 } catch (RemoteException e) {
5035 // Will never happen.
5036 }
5037 }
5038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 res.add(rti);
5040 maxNum--;
5041 }
5042 }
5043 return res;
5044 }
5045 }
5046
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005047 private TaskRecord taskForIdLocked(int id) {
5048 final int N = mRecentTasks.size();
5049 for (int i=0; i<N; i++) {
5050 TaskRecord tr = mRecentTasks.get(i);
5051 if (tr.taskId == id) {
5052 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005053 }
5054 }
5055 return null;
5056 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005057
5058 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5059 synchronized (this) {
5060 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5061 "getTaskThumbnails()");
5062 TaskRecord tr = taskForIdLocked(id);
5063 if (tr != null) {
5064 return mMainStack.getTaskThumbnailsLocked(tr);
5065 }
5066 }
5067 return null;
5068 }
5069
5070 public boolean removeSubTask(int taskId, int subTaskIndex) {
5071 synchronized (this) {
5072 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5073 "removeSubTask()");
5074 long ident = Binder.clearCallingIdentity();
5075 try {
5076 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5077 } finally {
5078 Binder.restoreCallingIdentity(ident);
5079 }
5080 }
5081 }
5082
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005083 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005084 TaskRecord tr = root.task;
5085 Intent baseIntent = new Intent(
5086 tr.intent != null ? tr.intent : tr.affinityIntent);
5087 ComponentName component = baseIntent.getComponent();
5088 if (component == null) {
5089 Slog.w(TAG, "Now component for base intent of task: " + tr);
5090 return;
5091 }
5092
5093 // Find any running services associated with this app.
5094 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5095 for (ServiceRecord sr : mServices.values()) {
5096 if (sr.packageName.equals(component.getPackageName())) {
5097 services.add(sr);
5098 }
5099 }
5100
5101 // Take care of any running services associated with the app.
5102 for (int i=0; i<services.size(); i++) {
5103 ServiceRecord sr = services.get(i);
5104 if (sr.startRequested) {
5105 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005106 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005107 stopServiceLocked(sr);
5108 } else {
5109 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5110 sr.makeNextStartId(), baseIntent, -1));
5111 if (sr.app != null && sr.app.thread != null) {
5112 sendServiceArgsLocked(sr, false);
5113 }
5114 }
5115 }
5116 }
5117
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005118 if (killProcesses) {
5119 // Find any running processes associated with this app.
5120 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5121 SparseArray<ProcessRecord> appProcs
5122 = mProcessNames.getMap().get(component.getPackageName());
5123 if (appProcs != null) {
5124 for (int i=0; i<appProcs.size(); i++) {
5125 procs.add(appProcs.valueAt(i));
5126 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005127 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005128
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005129 // Kill the running processes.
5130 for (int i=0; i<procs.size(); i++) {
5131 ProcessRecord pr = procs.get(i);
5132 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5133 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5134 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5135 pr.processName, pr.setAdj, "remove task");
5136 Process.killProcessQuiet(pr.pid);
5137 } else {
5138 pr.waitingToKill = "remove task";
5139 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005140 }
5141 }
5142 }
5143
5144 public boolean removeTask(int taskId, int flags) {
5145 synchronized (this) {
5146 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5147 "removeTask()");
5148 long ident = Binder.clearCallingIdentity();
5149 try {
5150 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5151 if (r != null) {
5152 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005153 cleanUpRemovedTaskLocked(r,
5154 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005155 return true;
5156 }
5157 } finally {
5158 Binder.restoreCallingIdentity(ident);
5159 }
5160 }
5161 return false;
5162 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005164 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5165 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005166 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005167 TaskRecord jt = startTask;
5168
5169 // First look backwards
5170 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005171 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005172 if (r.task != jt) {
5173 jt = r.task;
5174 if (affinity.equals(jt.affinity)) {
5175 return j;
5176 }
5177 }
5178 }
5179
5180 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005181 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 jt = startTask;
5183 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005184 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 if (r.task != jt) {
5186 if (affinity.equals(jt.affinity)) {
5187 return j;
5188 }
5189 jt = r.task;
5190 }
5191 }
5192
5193 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005194 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005195 return N-1;
5196 }
5197
5198 return -1;
5199 }
5200
5201 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005202 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005203 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005204 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005205 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5206 "moveTaskToFront()");
5207
5208 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005209 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5210 Binder.getCallingUid(), "Task to front")) {
5211 return;
5212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 final long origId = Binder.clearCallingIdentity();
5214 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005215 TaskRecord tr = taskForIdLocked(task);
5216 if (tr != null) {
5217 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5218 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005220 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5221 // Caller wants the home activity moved with it. To accomplish this,
5222 // we'll just move the home task to the top first.
5223 mMainStack.moveHomeToFrontLocked();
5224 }
5225 mMainStack.moveTaskToFrontLocked(tr, null);
5226 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005228 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5229 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005230 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005231 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5232 mMainStack.mUserLeaving = true;
5233 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005234 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5235 // Caller wants the home activity moved with it. To accomplish this,
5236 // we'll just move the home task to the top first.
5237 mMainStack.moveHomeToFrontLocked();
5238 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005239 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005240 return;
5241 }
5242 }
5243 } finally {
5244 Binder.restoreCallingIdentity(origId);
5245 }
5246 }
5247 }
5248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 public void moveTaskToBack(int task) {
5250 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5251 "moveTaskToBack()");
5252
5253 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005254 if (mMainStack.mResumedActivity != null
5255 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005256 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5257 Binder.getCallingUid(), "Task to back")) {
5258 return;
5259 }
5260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005262 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 Binder.restoreCallingIdentity(origId);
5264 }
5265 }
5266
5267 /**
5268 * Moves an activity, and all of the other activities within the same task, to the bottom
5269 * of the history stack. The activity's order within the task is unchanged.
5270 *
5271 * @param token A reference to the activity we wish to move
5272 * @param nonRoot If false then this only works if the activity is the root
5273 * of a task; if true it will work for any activity in a task.
5274 * @return Returns true if the move completed, false if not.
5275 */
5276 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5277 synchronized(this) {
5278 final long origId = Binder.clearCallingIdentity();
5279 int taskId = getTaskForActivityLocked(token, !nonRoot);
5280 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005281 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 }
5283 Binder.restoreCallingIdentity(origId);
5284 }
5285 return false;
5286 }
5287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 public void moveTaskBackwards(int task) {
5289 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5290 "moveTaskBackwards()");
5291
5292 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005293 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5294 Binder.getCallingUid(), "Task backwards")) {
5295 return;
5296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 final long origId = Binder.clearCallingIdentity();
5298 moveTaskBackwardsLocked(task);
5299 Binder.restoreCallingIdentity(origId);
5300 }
5301 }
5302
5303 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005304 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005305 }
5306
5307 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5308 synchronized(this) {
5309 return getTaskForActivityLocked(token, onlyRoot);
5310 }
5311 }
5312
5313 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005314 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 TaskRecord lastTask = null;
5316 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005317 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 if (r == token) {
5319 if (!onlyRoot || lastTask != r.task) {
5320 return r.task.taskId;
5321 }
5322 return -1;
5323 }
5324 lastTask = r.task;
5325 }
5326
5327 return -1;
5328 }
5329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 public void finishOtherInstances(IBinder token, ComponentName className) {
5331 synchronized(this) {
5332 final long origId = Binder.clearCallingIdentity();
5333
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005334 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335 TaskRecord lastTask = null;
5336 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005337 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 if (r.realActivity.equals(className)
5339 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005340 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 null, "others")) {
5342 i--;
5343 N--;
5344 }
5345 }
5346 lastTask = r.task;
5347 }
5348
5349 Binder.restoreCallingIdentity(origId);
5350 }
5351 }
5352
5353 // =========================================================
5354 // THUMBNAILS
5355 // =========================================================
5356
5357 public void reportThumbnail(IBinder token,
5358 Bitmap thumbnail, CharSequence description) {
5359 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5360 final long origId = Binder.clearCallingIdentity();
5361 sendPendingThumbnail(null, token, thumbnail, description, true);
5362 Binder.restoreCallingIdentity(origId);
5363 }
5364
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005365 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 Bitmap thumbnail, CharSequence description, boolean always) {
5367 TaskRecord task = null;
5368 ArrayList receivers = null;
5369
5370 //System.out.println("Send pending thumbnail: " + r);
5371
5372 synchronized(this) {
5373 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005374 r = mMainStack.isInStackLocked(token);
5375 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 return;
5377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005378 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005379 if (thumbnail == null && r.thumbHolder != null) {
5380 thumbnail = r.thumbHolder.lastThumbnail;
5381 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 }
5383 if (thumbnail == null && !always) {
5384 // If there is no thumbnail, and this entry is not actually
5385 // going away, then abort for now and pick up the next
5386 // thumbnail we get.
5387 return;
5388 }
5389 task = r.task;
5390
5391 int N = mPendingThumbnails.size();
5392 int i=0;
5393 while (i<N) {
5394 PendingThumbnailsRecord pr =
5395 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5396 //System.out.println("Looking in " + pr.pendingRecords);
5397 if (pr.pendingRecords.remove(r)) {
5398 if (receivers == null) {
5399 receivers = new ArrayList();
5400 }
5401 receivers.add(pr);
5402 if (pr.pendingRecords.size() == 0) {
5403 pr.finished = true;
5404 mPendingThumbnails.remove(i);
5405 N--;
5406 continue;
5407 }
5408 }
5409 i++;
5410 }
5411 }
5412
5413 if (receivers != null) {
5414 final int N = receivers.size();
5415 for (int i=0; i<N; i++) {
5416 try {
5417 PendingThumbnailsRecord pr =
5418 (PendingThumbnailsRecord)receivers.get(i);
5419 pr.receiver.newThumbnail(
5420 task != null ? task.taskId : -1, thumbnail, description);
5421 if (pr.finished) {
5422 pr.receiver.finished();
5423 }
5424 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005425 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005426 }
5427 }
5428 }
5429 }
5430
5431 // =========================================================
5432 // CONTENT PROVIDERS
5433 // =========================================================
5434
Jeff Brown10e89712011-07-08 18:52:57 -07005435 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5436 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005437 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005438 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005440 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 } catch (RemoteException ex) {
5442 }
5443 if (providers != null) {
5444 final int N = providers.size();
5445 for (int i=0; i<N; i++) {
5446 ProviderInfo cpi =
5447 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005448 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5449 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 if (cpr == null) {
5451 cpr = new ContentProviderRecord(cpi, app.info);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005452 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005453 }
5454 app.pubProviders.put(cpi.name, cpr);
5455 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005456 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005457 }
5458 }
5459 return providers;
5460 }
5461
5462 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005463 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5465 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5466 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005467 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005468 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005469 return null;
5470 }
5471 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005472 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 == PackageManager.PERMISSION_GRANTED) {
5474 return null;
5475 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005476
5477 PathPermission[] pps = cpi.pathPermissions;
5478 if (pps != null) {
5479 int i = pps.length;
5480 while (i > 0) {
5481 i--;
5482 PathPermission pp = pps[i];
5483 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005484 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005485 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005486 return null;
5487 }
5488 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005489 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005490 == PackageManager.PERMISSION_GRANTED) {
5491 return null;
5492 }
5493 }
5494 }
5495
Dianne Hackbornb424b632010-08-18 15:59:05 -07005496 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5497 if (perms != null) {
5498 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5499 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5500 return null;
5501 }
5502 }
5503 }
5504
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005505 String msg;
5506 if (!cpi.exported) {
5507 msg = "Permission Denial: opening provider " + cpi.name
5508 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5509 + ", uid=" + callingUid + ") that is not exported from uid "
5510 + cpi.applicationInfo.uid;
5511 } else {
5512 msg = "Permission Denial: opening provider " + cpi.name
5513 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5514 + ", uid=" + callingUid + ") requires "
5515 + cpi.readPermission + " or " + cpi.writePermission;
5516 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005517 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 return msg;
5519 }
5520
5521 private final ContentProviderHolder getContentProviderImpl(
5522 IApplicationThread caller, String name) {
5523 ContentProviderRecord cpr;
5524 ProviderInfo cpi = null;
5525
5526 synchronized(this) {
5527 ProcessRecord r = null;
5528 if (caller != null) {
5529 r = getRecordForAppLocked(caller);
5530 if (r == null) {
5531 throw new SecurityException(
5532 "Unable to find app for caller " + caller
5533 + " (pid=" + Binder.getCallingPid()
5534 + ") when getting content provider " + name);
5535 }
5536 }
5537
5538 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005539 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005540 if (cpr != null) {
5541 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005542 String msg;
5543 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5544 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 }
5546
5547 if (r != null && cpr.canRunHere(r)) {
5548 // This provider has been published or is in the process
5549 // of being published... but it is also allowed to run
5550 // in the caller's process, so don't make a connection
5551 // and just let the caller instantiate its own instance.
5552 if (cpr.provider != null) {
5553 // don't give caller the provider object, it needs
5554 // to make its own.
5555 cpr = new ContentProviderRecord(cpr);
5556 }
5557 return cpr;
5558 }
5559
5560 final long origId = Binder.clearCallingIdentity();
5561
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005562 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 // return it right away.
5564 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005565 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005566 "Adding provider requested by "
5567 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005568 + cpr.info.processName);
5569 Integer cnt = r.conProviders.get(cpr);
5570 if (cnt == null) {
5571 r.conProviders.put(cpr, new Integer(1));
5572 } else {
5573 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 cpr.clients.add(r);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005576 if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005577 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005578 // make sure to count it as being accessed and thus
5579 // back up on the LRU list. This is good because
5580 // content providers are often expensive to start.
5581 updateLruProcessLocked(cpr.app, false, true);
5582 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005583 } else {
5584 cpr.externals++;
5585 }
5586
5587 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005588 updateOomAdjLocked(cpr.app);
5589 }
5590
5591 Binder.restoreCallingIdentity(origId);
5592
5593 } else {
5594 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005595 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005596 resolveContentProvider(name,
5597 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 } catch (RemoteException ex) {
5599 }
5600 if (cpi == null) {
5601 return null;
5602 }
5603
Dianne Hackbornb424b632010-08-18 15:59:05 -07005604 String msg;
5605 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5606 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005607 }
5608
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005609 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005610 && !cpi.processName.equals("system")) {
5611 // If this content provider does not run in the system
5612 // process, and the system is not yet ready to run other
5613 // processes, then fail fast instead of hanging.
5614 throw new IllegalArgumentException(
5615 "Attempt to launch content provider before system ready");
5616 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005617
5618 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5619 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005620 final boolean firstClass = cpr == null;
5621 if (firstClass) {
5622 try {
5623 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005624 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005625 getApplicationInfo(
5626 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005627 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005629 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 + cpi.name);
5631 return null;
5632 }
5633 cpr = new ContentProviderRecord(cpi, ai);
5634 } catch (RemoteException ex) {
5635 // pm is in same process, this will never happen.
5636 }
5637 }
5638
5639 if (r != null && cpr.canRunHere(r)) {
5640 // If this is a multiprocess provider, then just return its
5641 // info and allow the caller to instantiate it. Only do
5642 // this if the provider is the same user as the caller's
5643 // process, or can run as root (so can be in any process).
5644 return cpr;
5645 }
5646
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005647 if (DEBUG_PROVIDER) {
5648 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005649 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005650 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005651 }
5652
5653 // This is single process, and our app is now connecting to it.
5654 // See if we are already in the process of launching this
5655 // provider.
5656 final int N = mLaunchingProviders.size();
5657 int i;
5658 for (i=0; i<N; i++) {
5659 if (mLaunchingProviders.get(i) == cpr) {
5660 break;
5661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 }
5663
5664 // If the provider is not already being launched, then get it
5665 // started.
5666 if (i >= N) {
5667 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005668
5669 try {
5670 // Content provider is now in use, its package can't be stopped.
5671 try {
5672 AppGlobals.getPackageManager().setPackageStoppedState(
5673 cpr.appInfo.packageName, false);
5674 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005675 } catch (IllegalArgumentException e) {
5676 Slog.w(TAG, "Failed trying to unstop package "
5677 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005678 }
5679
5680 ProcessRecord proc = startProcessLocked(cpi.processName,
5681 cpr.appInfo, false, 0, "content provider",
5682 new ComponentName(cpi.applicationInfo.packageName,
5683 cpi.name), false);
5684 if (proc == null) {
5685 Slog.w(TAG, "Unable to launch app "
5686 + cpi.applicationInfo.packageName + "/"
5687 + cpi.applicationInfo.uid + " for provider "
5688 + name + ": process is bad");
5689 return null;
5690 }
5691 cpr.launchingApp = proc;
5692 mLaunchingProviders.add(cpr);
5693 } finally {
5694 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 }
5697
5698 // Make sure the provider is published (the same provider class
5699 // may be published under multiple names).
5700 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005701 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 }
5703 mProvidersByName.put(name, cpr);
5704
5705 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005706 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005707 "Adding provider requested by "
5708 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005709 + cpr.info.processName);
5710 Integer cnt = r.conProviders.get(cpr);
5711 if (cnt == null) {
5712 r.conProviders.put(cpr, new Integer(1));
5713 } else {
5714 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5715 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 cpr.clients.add(r);
5717 } else {
5718 cpr.externals++;
5719 }
5720 }
5721 }
5722
5723 // Wait for the provider to be published...
5724 synchronized (cpr) {
5725 while (cpr.provider == null) {
5726 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005727 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005728 + cpi.applicationInfo.packageName + "/"
5729 + cpi.applicationInfo.uid + " for provider "
5730 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005731 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005732 cpi.applicationInfo.packageName,
5733 cpi.applicationInfo.uid, name);
5734 return null;
5735 }
5736 try {
5737 cpr.wait();
5738 } catch (InterruptedException ex) {
5739 }
5740 }
5741 }
5742 return cpr;
5743 }
5744
5745 public final ContentProviderHolder getContentProvider(
5746 IApplicationThread caller, String name) {
5747 if (caller == null) {
5748 String msg = "null IApplicationThread when getting content provider "
5749 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005750 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 throw new SecurityException(msg);
5752 }
5753
5754 return getContentProviderImpl(caller, name);
5755 }
5756
5757 private ContentProviderHolder getContentProviderExternal(String name) {
5758 return getContentProviderImpl(null, name);
5759 }
5760
5761 /**
5762 * Drop a content provider from a ProcessRecord's bookkeeping
5763 * @param cpr
5764 */
5765 public void removeContentProvider(IApplicationThread caller, String name) {
5766 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005767 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005768 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005769 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005770 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005771 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772 return;
5773 }
5774 final ProcessRecord r = getRecordForAppLocked(caller);
5775 if (r == null) {
5776 throw new SecurityException(
5777 "Unable to find app for caller " + caller +
5778 " when removing content provider " + name);
5779 }
5780 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005781 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5782 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005783 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005784 + r.info.processName + " from process "
5785 + localCpr.appInfo.processName);
5786 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005787 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005788 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005789 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 return;
5791 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005792 Integer cnt = r.conProviders.get(localCpr);
5793 if (cnt == null || cnt.intValue() <= 1) {
5794 localCpr.clients.remove(r);
5795 r.conProviders.remove(localCpr);
5796 } else {
5797 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 }
5800 updateOomAdjLocked();
5801 }
5802 }
5803
5804 private void removeContentProviderExternal(String name) {
5805 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005806 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005807 if(cpr == null) {
5808 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005809 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 return;
5811 }
5812
5813 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005814 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5815 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005816 localCpr.externals--;
5817 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005818 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005819 }
5820 updateOomAdjLocked();
5821 }
5822 }
5823
5824 public final void publishContentProviders(IApplicationThread caller,
5825 List<ContentProviderHolder> providers) {
5826 if (providers == null) {
5827 return;
5828 }
5829
5830 synchronized(this) {
5831 final ProcessRecord r = getRecordForAppLocked(caller);
5832 if (r == null) {
5833 throw new SecurityException(
5834 "Unable to find app for caller " + caller
5835 + " (pid=" + Binder.getCallingPid()
5836 + ") when publishing content providers");
5837 }
5838
5839 final long origId = Binder.clearCallingIdentity();
5840
5841 final int N = providers.size();
5842 for (int i=0; i<N; i++) {
5843 ContentProviderHolder src = providers.get(i);
5844 if (src == null || src.info == null || src.provider == null) {
5845 continue;
5846 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005847 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005849 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5850 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005851 String names[] = dst.info.authority.split(";");
5852 for (int j = 0; j < names.length; j++) {
5853 mProvidersByName.put(names[j], dst);
5854 }
5855
5856 int NL = mLaunchingProviders.size();
5857 int j;
5858 for (j=0; j<NL; j++) {
5859 if (mLaunchingProviders.get(j) == dst) {
5860 mLaunchingProviders.remove(j);
5861 j--;
5862 NL--;
5863 }
5864 }
5865 synchronized (dst) {
5866 dst.provider = src.provider;
5867 dst.app = r;
5868 dst.notifyAll();
5869 }
5870 updateOomAdjLocked(r);
5871 }
5872 }
5873
5874 Binder.restoreCallingIdentity(origId);
5875 }
5876 }
5877
5878 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005879 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005880 synchronized (mSelf) {
5881 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5882 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005883 if (providers != null) {
5884 for (int i=providers.size()-1; i>=0; i--) {
5885 ProviderInfo pi = (ProviderInfo)providers.get(i);
5886 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5887 Slog.w(TAG, "Not installing system proc provider " + pi.name
5888 + ": not system .apk");
5889 providers.remove(i);
5890 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005891 }
5892 }
5893 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005894 if (providers != null) {
5895 mSystemThread.installSystemProviders(providers);
5896 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005897
5898 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005899
5900 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005901 }
5902
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005903 /**
5904 * Allows app to retrieve the MIME type of a URI without having permission
5905 * to access its content provider.
5906 *
5907 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5908 *
5909 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5910 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5911 */
5912 public String getProviderMimeType(Uri uri) {
5913 final String name = uri.getAuthority();
5914 final long ident = Binder.clearCallingIdentity();
5915 ContentProviderHolder holder = null;
5916
5917 try {
5918 holder = getContentProviderExternal(name);
5919 if (holder != null) {
5920 return holder.provider.getType(uri);
5921 }
5922 } catch (RemoteException e) {
5923 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5924 return null;
5925 } finally {
5926 if (holder != null) {
5927 removeContentProviderExternal(name);
5928 }
5929 Binder.restoreCallingIdentity(ident);
5930 }
5931
5932 return null;
5933 }
5934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005935 // =========================================================
5936 // GLOBAL MANAGEMENT
5937 // =========================================================
5938
5939 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5940 ApplicationInfo info, String customProcess) {
5941 String proc = customProcess != null ? customProcess : info.processName;
5942 BatteryStatsImpl.Uid.Proc ps = null;
5943 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5944 synchronized (stats) {
5945 ps = stats.getProcessStatsLocked(info.uid, proc);
5946 }
5947 return new ProcessRecord(ps, thread, info, proc);
5948 }
5949
5950 final ProcessRecord addAppLocked(ApplicationInfo info) {
5951 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5952
5953 if (app == null) {
5954 app = newProcessRecordLocked(null, info, null);
5955 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005956 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005957 }
5958
Dianne Hackborne7f97212011-02-24 14:40:20 -08005959 // This package really, really can not be stopped.
5960 try {
5961 AppGlobals.getPackageManager().setPackageStoppedState(
5962 info.packageName, false);
5963 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005964 } catch (IllegalArgumentException e) {
5965 Slog.w(TAG, "Failed trying to unstop package "
5966 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005967 }
5968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005969 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5970 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5971 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07005972 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 }
5974 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5975 mPersistentStartingProcesses.add(app);
5976 startProcessLocked(app, "added application", app.processName);
5977 }
5978
5979 return app;
5980 }
5981
5982 public void unhandledBack() {
5983 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5984 "unhandledBack()");
5985
5986 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005987 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005988 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005989 TAG, "Performing unhandledBack(): stack size = " + count);
5990 if (count > 1) {
5991 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005992 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5994 Binder.restoreCallingIdentity(origId);
5995 }
5996 }
5997 }
5998
5999 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6000 String name = uri.getAuthority();
6001 ContentProviderHolder cph = getContentProviderExternal(name);
6002 ParcelFileDescriptor pfd = null;
6003 if (cph != null) {
6004 // We record the binder invoker's uid in thread-local storage before
6005 // going to the content provider to open the file. Later, in the code
6006 // that handles all permissions checks, we look for this uid and use
6007 // that rather than the Activity Manager's own uid. The effect is that
6008 // we do the check against the caller's permissions even though it looks
6009 // to the content provider like the Activity Manager itself is making
6010 // the request.
6011 sCallerIdentity.set(new Identity(
6012 Binder.getCallingPid(), Binder.getCallingUid()));
6013 try {
6014 pfd = cph.provider.openFile(uri, "r");
6015 } catch (FileNotFoundException e) {
6016 // do nothing; pfd will be returned null
6017 } finally {
6018 // Ensure that whatever happens, we clean up the identity state
6019 sCallerIdentity.remove();
6020 }
6021
6022 // We've got the fd now, so we're done with the provider.
6023 removeContentProviderExternal(name);
6024 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006025 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 }
6027 return pfd;
6028 }
6029
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006030 // Actually is sleeping or shutting down or whatever else in the future
6031 // is an inactive state.
6032 public boolean isSleeping() {
6033 return mSleeping || mShuttingDown;
6034 }
6035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006036 public void goingToSleep() {
6037 synchronized(this) {
6038 mSleeping = true;
6039 mWindowManager.setEventDispatching(false);
6040
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006041 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006042
6043 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006044 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006045 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6046 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006047 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 }
6049 }
6050
Dianne Hackborn55280a92009-05-07 15:53:46 -07006051 public boolean shutdown(int timeout) {
6052 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6053 != PackageManager.PERMISSION_GRANTED) {
6054 throw new SecurityException("Requires permission "
6055 + android.Manifest.permission.SHUTDOWN);
6056 }
6057
6058 boolean timedout = false;
6059
6060 synchronized(this) {
6061 mShuttingDown = true;
6062 mWindowManager.setEventDispatching(false);
6063
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006064 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006065 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006066 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006067 while (mMainStack.mResumedActivity != null
6068 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006069 long delay = endTime - System.currentTimeMillis();
6070 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006071 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006072 timedout = true;
6073 break;
6074 }
6075 try {
6076 this.wait();
6077 } catch (InterruptedException e) {
6078 }
6079 }
6080 }
6081 }
6082
6083 mUsageStatsService.shutdown();
6084 mBatteryStatsService.shutdown();
6085
6086 return timedout;
6087 }
6088
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006089 public final void activitySlept(IBinder token) {
6090 if (localLOGV) Slog.v(
6091 TAG, "Activity slept: token=" + token);
6092
6093 ActivityRecord r = null;
6094
6095 final long origId = Binder.clearCallingIdentity();
6096
6097 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006098 r = mMainStack.isInStackLocked(token);
6099 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006100 mMainStack.activitySleptLocked(r);
6101 }
6102 }
6103
6104 Binder.restoreCallingIdentity(origId);
6105 }
6106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006107 public void wakingUp() {
6108 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 mWindowManager.setEventDispatching(true);
6110 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006111 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006112 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 }
6114 }
6115
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006116 public void stopAppSwitches() {
6117 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6118 != PackageManager.PERMISSION_GRANTED) {
6119 throw new SecurityException("Requires permission "
6120 + android.Manifest.permission.STOP_APP_SWITCHES);
6121 }
6122
6123 synchronized(this) {
6124 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6125 + APP_SWITCH_DELAY_TIME;
6126 mDidAppSwitch = false;
6127 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6128 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6129 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6130 }
6131 }
6132
6133 public void resumeAppSwitches() {
6134 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6135 != PackageManager.PERMISSION_GRANTED) {
6136 throw new SecurityException("Requires permission "
6137 + android.Manifest.permission.STOP_APP_SWITCHES);
6138 }
6139
6140 synchronized(this) {
6141 // Note that we don't execute any pending app switches... we will
6142 // let those wait until either the timeout, or the next start
6143 // activity request.
6144 mAppSwitchesAllowedTime = 0;
6145 }
6146 }
6147
6148 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6149 String name) {
6150 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6151 return true;
6152 }
6153
6154 final int perm = checkComponentPermission(
6155 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006156 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006157 if (perm == PackageManager.PERMISSION_GRANTED) {
6158 return true;
6159 }
6160
Joe Onorato8a9b2202010-02-26 18:56:32 -08006161 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006162 return false;
6163 }
6164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006165 public void setDebugApp(String packageName, boolean waitForDebugger,
6166 boolean persistent) {
6167 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6168 "setDebugApp()");
6169
6170 // Note that this is not really thread safe if there are multiple
6171 // callers into it at the same time, but that's not a situation we
6172 // care about.
6173 if (persistent) {
6174 final ContentResolver resolver = mContext.getContentResolver();
6175 Settings.System.putString(
6176 resolver, Settings.System.DEBUG_APP,
6177 packageName);
6178 Settings.System.putInt(
6179 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6180 waitForDebugger ? 1 : 0);
6181 }
6182
6183 synchronized (this) {
6184 if (!persistent) {
6185 mOrigDebugApp = mDebugApp;
6186 mOrigWaitForDebugger = mWaitForDebugger;
6187 }
6188 mDebugApp = packageName;
6189 mWaitForDebugger = waitForDebugger;
6190 mDebugTransient = !persistent;
6191 if (packageName != null) {
6192 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006193 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006194 Binder.restoreCallingIdentity(origId);
6195 }
6196 }
6197 }
6198
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006199 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6200 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6201 synchronized (this) {
6202 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6203 if (!isDebuggable) {
6204 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6205 throw new SecurityException("Process not debuggable: " + app.packageName);
6206 }
6207 }
6208 mProfileApp = processName;
6209 mProfileFile = profileFile;
6210 if (mProfileFd != null) {
6211 try {
6212 mProfileFd.close();
6213 } catch (IOException e) {
6214 }
6215 mProfileFd = null;
6216 }
6217 mProfileFd = profileFd;
6218 mProfileType = 0;
6219 mAutoStopProfiler = autoStopProfiler;
6220 }
6221 }
6222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006223 public void setAlwaysFinish(boolean enabled) {
6224 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6225 "setAlwaysFinish()");
6226
6227 Settings.System.putInt(
6228 mContext.getContentResolver(),
6229 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6230
6231 synchronized (this) {
6232 mAlwaysFinishActivities = enabled;
6233 }
6234 }
6235
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006236 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006238 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006239 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006240 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 }
6242 }
6243
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006244 public boolean isUserAMonkey() {
6245 // For now the fact that there is a controller implies
6246 // we have a monkey.
6247 synchronized (this) {
6248 return mController != null;
6249 }
6250 }
6251
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006252 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006253 synchronized (this) {
6254 mWatchers.register(watcher);
6255 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006256 }
6257
6258 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006259 synchronized (this) {
6260 mWatchers.unregister(watcher);
6261 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006262 }
6263
Jeff Sharkeya4620792011-05-20 15:29:23 -07006264 public void registerProcessObserver(IProcessObserver observer) {
6265 mProcessObservers.register(observer);
6266 }
6267
6268 public void unregisterProcessObserver(IProcessObserver observer) {
6269 mProcessObservers.unregister(observer);
6270 }
6271
Daniel Sandler69a48172010-06-23 16:29:36 -04006272 public void setImmersive(IBinder token, boolean immersive) {
6273 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006274 ActivityRecord r = mMainStack.isInStackLocked(token);
6275 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006276 throw new IllegalArgumentException();
6277 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006278 r.immersive = immersive;
6279 }
6280 }
6281
6282 public boolean isImmersive(IBinder token) {
6283 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006284 ActivityRecord r = mMainStack.isInStackLocked(token);
6285 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006286 throw new IllegalArgumentException();
6287 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006288 return r.immersive;
6289 }
6290 }
6291
6292 public boolean isTopActivityImmersive() {
6293 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006294 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006295 return (r != null) ? r.immersive : false;
6296 }
6297 }
6298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 public final void enterSafeMode() {
6300 synchronized(this) {
6301 // It only makes sense to do this before the system is ready
6302 // and started launching other packages.
6303 if (!mSystemReady) {
6304 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006305 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 } catch (RemoteException e) {
6307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 }
6309 }
6310 }
6311
Jeff Brownb09abc12011-01-13 21:08:27 -08006312 public final void showSafeModeOverlay() {
6313 View v = LayoutInflater.from(mContext).inflate(
6314 com.android.internal.R.layout.safe_mode, null);
6315 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6316 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6317 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6318 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6319 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6320 lp.format = v.getBackground().getOpacity();
6321 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6322 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6323 ((WindowManager)mContext.getSystemService(
6324 Context.WINDOW_SERVICE)).addView(v, lp);
6325 }
6326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 public void noteWakeupAlarm(IIntentSender sender) {
6328 if (!(sender instanceof PendingIntentRecord)) {
6329 return;
6330 }
6331 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6332 synchronized (stats) {
6333 if (mBatteryStatsService.isOnBattery()) {
6334 mBatteryStatsService.enforceCallingPermission();
6335 PendingIntentRecord rec = (PendingIntentRecord)sender;
6336 int MY_UID = Binder.getCallingUid();
6337 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6338 BatteryStatsImpl.Uid.Pkg pkg =
6339 stats.getPackageStatsLocked(uid, rec.key.packageName);
6340 pkg.incWakeupsLocked();
6341 }
6342 }
6343 }
6344
Dianne Hackborn64825172011-03-02 21:32:58 -08006345 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006347 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006348 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006349 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006350 // XXX Note: don't acquire main activity lock here, because the window
6351 // manager calls in with its locks held.
6352
6353 boolean killed = false;
6354 synchronized (mPidsSelfLocked) {
6355 int[] types = new int[pids.length];
6356 int worstType = 0;
6357 for (int i=0; i<pids.length; i++) {
6358 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6359 if (proc != null) {
6360 int type = proc.setAdj;
6361 types[i] = type;
6362 if (type > worstType) {
6363 worstType = type;
6364 }
6365 }
6366 }
6367
Dianne Hackborn64825172011-03-02 21:32:58 -08006368 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006369 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006370 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6371 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006373
6374 // If this is not a secure call, don't let it kill processes that
6375 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006376 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6377 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006378 }
6379
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006380 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 for (int i=0; i<pids.length; i++) {
6382 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6383 if (proc == null) {
6384 continue;
6385 }
6386 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006387 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006388 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006389 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6390 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006391 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006392 proc.killedBackground = true;
6393 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006394 }
6395 }
6396 }
6397 return killed;
6398 }
6399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006400 public final void startRunning(String pkg, String cls, String action,
6401 String data) {
6402 synchronized(this) {
6403 if (mStartRunning) {
6404 return;
6405 }
6406 mStartRunning = true;
6407 mTopComponent = pkg != null && cls != null
6408 ? new ComponentName(pkg, cls) : null;
6409 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6410 mTopData = data;
6411 if (!mSystemReady) {
6412 return;
6413 }
6414 }
6415
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006416 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 }
6418
6419 private void retrieveSettings() {
6420 final ContentResolver resolver = mContext.getContentResolver();
6421 String debugApp = Settings.System.getString(
6422 resolver, Settings.System.DEBUG_APP);
6423 boolean waitForDebugger = Settings.System.getInt(
6424 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6425 boolean alwaysFinishActivities = Settings.System.getInt(
6426 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6427
6428 Configuration configuration = new Configuration();
6429 Settings.System.getConfiguration(resolver, configuration);
6430
6431 synchronized (this) {
6432 mDebugApp = mOrigDebugApp = debugApp;
6433 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6434 mAlwaysFinishActivities = alwaysFinishActivities;
6435 // This happens before any activities are started, so we can
6436 // change mConfiguration in-place.
6437 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006438 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006439 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006440 }
6441 }
6442
6443 public boolean testIsSystemReady() {
6444 // no need to synchronize(this) just to read & return the value
6445 return mSystemReady;
6446 }
6447
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006448 private static File getCalledPreBootReceiversFile() {
6449 File dataDir = Environment.getDataDirectory();
6450 File systemDir = new File(dataDir, "system");
6451 File fname = new File(systemDir, "called_pre_boots.dat");
6452 return fname;
6453 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006454
6455 static final int LAST_DONE_VERSION = 10000;
6456
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006457 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6458 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6459 File file = getCalledPreBootReceiversFile();
6460 FileInputStream fis = null;
6461 try {
6462 fis = new FileInputStream(file);
6463 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006464 int fvers = dis.readInt();
6465 if (fvers == LAST_DONE_VERSION) {
6466 String vers = dis.readUTF();
6467 String codename = dis.readUTF();
6468 String build = dis.readUTF();
6469 if (android.os.Build.VERSION.RELEASE.equals(vers)
6470 && android.os.Build.VERSION.CODENAME.equals(codename)
6471 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6472 int num = dis.readInt();
6473 while (num > 0) {
6474 num--;
6475 String pkg = dis.readUTF();
6476 String cls = dis.readUTF();
6477 lastDoneReceivers.add(new ComponentName(pkg, cls));
6478 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006479 }
6480 }
6481 } catch (FileNotFoundException e) {
6482 } catch (IOException e) {
6483 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6484 } finally {
6485 if (fis != null) {
6486 try {
6487 fis.close();
6488 } catch (IOException e) {
6489 }
6490 }
6491 }
6492 return lastDoneReceivers;
6493 }
6494
6495 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6496 File file = getCalledPreBootReceiversFile();
6497 FileOutputStream fos = null;
6498 DataOutputStream dos = null;
6499 try {
6500 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6501 fos = new FileOutputStream(file);
6502 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006503 dos.writeInt(LAST_DONE_VERSION);
6504 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006505 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006506 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006507 dos.writeInt(list.size());
6508 for (int i=0; i<list.size(); i++) {
6509 dos.writeUTF(list.get(i).getPackageName());
6510 dos.writeUTF(list.get(i).getClassName());
6511 }
6512 } catch (IOException e) {
6513 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6514 file.delete();
6515 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006516 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006517 if (dos != null) {
6518 try {
6519 dos.close();
6520 } catch (IOException e) {
6521 // TODO Auto-generated catch block
6522 e.printStackTrace();
6523 }
6524 }
6525 }
6526 }
6527
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006528 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 synchronized(this) {
6530 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006531 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006532 return;
6533 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006534
6535 // Check to see if there are any update receivers to run.
6536 if (!mDidUpdate) {
6537 if (mWaitingUpdate) {
6538 return;
6539 }
6540 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6541 List<ResolveInfo> ris = null;
6542 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006543 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006544 intent, null, 0);
6545 } catch (RemoteException e) {
6546 }
6547 if (ris != null) {
6548 for (int i=ris.size()-1; i>=0; i--) {
6549 if ((ris.get(i).activityInfo.applicationInfo.flags
6550 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6551 ris.remove(i);
6552 }
6553 }
6554 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006555
6556 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6557
6558 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006559 for (int i=0; i<ris.size(); i++) {
6560 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006561 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6562 if (lastDoneReceivers.contains(comp)) {
6563 ris.remove(i);
6564 i--;
6565 }
6566 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006567
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006568 for (int i=0; i<ris.size(); i++) {
6569 ActivityInfo ai = ris.get(i).activityInfo;
6570 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6571 doneReceivers.add(comp);
6572 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006573 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006574 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006575 finisher = new IIntentReceiver.Stub() {
6576 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006577 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006578 boolean sticky) {
6579 // The raw IIntentReceiver interface is called
6580 // with the AM lock held, so redispatch to
6581 // execute our code without the lock.
6582 mHandler.post(new Runnable() {
6583 public void run() {
6584 synchronized (ActivityManagerService.this) {
6585 mDidUpdate = true;
6586 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006587 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006588 showBootMessage(mContext.getText(
6589 R.string.android_upgrading_complete),
6590 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006591 systemReady(goingCallback);
6592 }
6593 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006594 }
6595 };
6596 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006597 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006598 broadcastIntentLocked(null, null, intent, null, finisher,
6599 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006600 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006601 mWaitingUpdate = true;
6602 }
6603 }
6604 }
6605 if (mWaitingUpdate) {
6606 return;
6607 }
6608 mDidUpdate = true;
6609 }
6610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006611 mSystemReady = true;
6612 if (!mStartRunning) {
6613 return;
6614 }
6615 }
6616
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006617 ArrayList<ProcessRecord> procsToKill = null;
6618 synchronized(mPidsSelfLocked) {
6619 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6620 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6621 if (!isAllowedWhileBooting(proc.info)){
6622 if (procsToKill == null) {
6623 procsToKill = new ArrayList<ProcessRecord>();
6624 }
6625 procsToKill.add(proc);
6626 }
6627 }
6628 }
6629
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006630 synchronized(this) {
6631 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006632 for (int i=procsToKill.size()-1; i>=0; i--) {
6633 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006634 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006635 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006636 }
6637 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006638
6639 // Now that we have cleaned up any update processes, we
6640 // are ready to start launching real processes and know that
6641 // we won't trample on them any more.
6642 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006643 }
6644
Joe Onorato8a9b2202010-02-26 18:56:32 -08006645 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006646 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 SystemClock.uptimeMillis());
6648
6649 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006650 // Make sure we have no pre-ready processes sitting around.
6651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006652 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6653 ResolveInfo ri = mContext.getPackageManager()
6654 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006655 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 CharSequence errorMsg = null;
6657 if (ri != null) {
6658 ActivityInfo ai = ri.activityInfo;
6659 ApplicationInfo app = ai.applicationInfo;
6660 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6661 mTopAction = Intent.ACTION_FACTORY_TEST;
6662 mTopData = null;
6663 mTopComponent = new ComponentName(app.packageName,
6664 ai.name);
6665 } else {
6666 errorMsg = mContext.getResources().getText(
6667 com.android.internal.R.string.factorytest_not_system);
6668 }
6669 } else {
6670 errorMsg = mContext.getResources().getText(
6671 com.android.internal.R.string.factorytest_no_action);
6672 }
6673 if (errorMsg != null) {
6674 mTopAction = null;
6675 mTopData = null;
6676 mTopComponent = null;
6677 Message msg = Message.obtain();
6678 msg.what = SHOW_FACTORY_ERROR_MSG;
6679 msg.getData().putCharSequence("msg", errorMsg);
6680 mHandler.sendMessage(msg);
6681 }
6682 }
6683 }
6684
6685 retrieveSettings();
6686
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006687 if (goingCallback != null) goingCallback.run();
6688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006689 synchronized (this) {
6690 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6691 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006692 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006693 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 if (apps != null) {
6695 int N = apps.size();
6696 int i;
6697 for (i=0; i<N; i++) {
6698 ApplicationInfo info
6699 = (ApplicationInfo)apps.get(i);
6700 if (info != null &&
6701 !info.packageName.equals("android")) {
6702 addAppLocked(info);
6703 }
6704 }
6705 }
6706 } catch (RemoteException ex) {
6707 // pm is in same process, this will never happen.
6708 }
6709 }
6710
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006711 // Start up initial activity.
6712 mBooting = true;
6713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006715 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 Message msg = Message.obtain();
6717 msg.what = SHOW_UID_ERROR_MSG;
6718 mHandler.sendMessage(msg);
6719 }
6720 } catch (RemoteException e) {
6721 }
6722
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006723 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006724 }
6725 }
6726
Dan Egnorb7f03672009-12-09 16:22:32 -08006727 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006728 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006729 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006730 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006731 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 startAppProblemLocked(app);
6733 app.stopFreezingAllLocked();
6734 return handleAppCrashLocked(app);
6735 }
6736
Dan Egnorb7f03672009-12-09 16:22:32 -08006737 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006738 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006740 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006741 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6742 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006743 startAppProblemLocked(app);
6744 app.stopFreezingAllLocked();
6745 }
6746
6747 /**
6748 * Generate a process error record, suitable for attachment to a ProcessRecord.
6749 *
6750 * @param app The ProcessRecord in which the error occurred.
6751 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6752 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006753 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 * @param shortMsg Short message describing the crash.
6755 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006756 * @param stackTrace Full crash stack trace, may be null.
6757 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 * @return Returns a fully-formed AppErrorStateInfo record.
6759 */
6760 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006761 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006764 report.condition = condition;
6765 report.processName = app.processName;
6766 report.pid = app.pid;
6767 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006768 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 report.shortMsg = shortMsg;
6770 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006771 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772
6773 return report;
6774 }
6775
Dan Egnor42471dd2010-01-07 17:25:22 -08006776 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 synchronized (this) {
6778 app.crashing = false;
6779 app.crashingReport = null;
6780 app.notResponding = false;
6781 app.notRespondingReport = null;
6782 if (app.anrDialog == fromDialog) {
6783 app.anrDialog = null;
6784 }
6785 if (app.waitDialog == fromDialog) {
6786 app.waitDialog = null;
6787 }
6788 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006789 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006790 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006791 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6792 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006793 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 }
6796 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006797
Dan Egnorb7f03672009-12-09 16:22:32 -08006798 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 long now = SystemClock.uptimeMillis();
6800
6801 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6802 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006803 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006805 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006806 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006807 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006808 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006809 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6810 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006812 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006814 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 }
6816 }
6817 if (!app.persistent) {
6818 // We don't want to start this process again until the user
6819 // explicitly does so... but for persistent process, we really
6820 // need to keep it running. If a persistent process is actually
6821 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006822 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006823 app.info.processName);
6824 mBadProcesses.put(app.info.processName, app.info.uid, now);
6825 app.bad = true;
6826 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6827 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006828 // Don't let services in this process be restarted and potentially
6829 // annoy the user repeatedly. Unless it is persistent, since those
6830 // processes run critical code.
6831 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006832 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 return false;
6834 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006835 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006836 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006837 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006838 if (r.app == app) {
6839 // If the top running activity is from this crashing
6840 // process, then terminate it to avoid getting in a loop.
6841 Slog.w(TAG, " Force finishing activity "
6842 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006843 int index = mMainStack.indexOfTokenLocked(r);
6844 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006845 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006846 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006847 // stopped, to avoid a situation where one will get
6848 // re-start our crashing activity once it gets resumed again.
6849 index--;
6850 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006851 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006852 if (r.state == ActivityState.RESUMED
6853 || r.state == ActivityState.PAUSING
6854 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006855 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006856 Slog.w(TAG, " Force finishing activity "
6857 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006858 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006859 Activity.RESULT_CANCELED, null, "crashed");
6860 }
6861 }
6862 }
6863 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006864 }
6865
6866 // Bump up the crash count of any services currently running in the proc.
6867 if (app.services.size() != 0) {
6868 // Any services running in the application need to be placed
6869 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006870 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006872 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 sr.crashCount++;
6874 }
6875 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006876
6877 // If the crashing process is what we consider to be the "home process" and it has been
6878 // replaced by a third-party app, clear the package preferred activities from packages
6879 // with a home activity running in the process to prevent a repeatedly crashing app
6880 // from blocking the user to manually clear the list.
6881 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6882 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6883 Iterator it = mHomeProcess.activities.iterator();
6884 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006885 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006886 if (r.isHomeActivity) {
6887 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6888 try {
6889 ActivityThread.getPackageManager()
6890 .clearPackagePreferredActivities(r.packageName);
6891 } catch (RemoteException c) {
6892 // pm is in same process, this will never happen.
6893 }
6894 }
6895 }
6896 }
6897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006898 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6899 return true;
6900 }
6901
6902 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006903 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6904 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006905 skipCurrentReceiverLocked(app);
6906 }
6907
6908 void skipCurrentReceiverLocked(ProcessRecord app) {
6909 boolean reschedule = false;
6910 BroadcastRecord r = app.curReceiver;
6911 if (r != null) {
6912 // The current broadcast is waiting for this app's receiver
6913 // to be finished. Looks like that's not going to happen, so
6914 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006915 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6917 r.resultExtras, r.resultAbort, true);
6918 reschedule = true;
6919 }
6920 r = mPendingBroadcast;
6921 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006922 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006923 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006924 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006925 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6926 r.resultExtras, r.resultAbort, true);
6927 reschedule = true;
6928 }
6929 if (reschedule) {
6930 scheduleBroadcastsLocked();
6931 }
6932 }
6933
Dan Egnor60d87622009-12-16 16:32:58 -08006934 /**
6935 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6936 * The application process will exit immediately after this call returns.
6937 * @param app object of the crashing app, null for the system server
6938 * @param crashInfo describing the exception
6939 */
6940 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006941 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006942
6943 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6944 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006945 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006946 crashInfo.exceptionClassName,
6947 crashInfo.exceptionMessage,
6948 crashInfo.throwFileName,
6949 crashInfo.throwLineNumber);
6950
Dan Egnor42471dd2010-01-07 17:25:22 -08006951 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006952
6953 crashApplication(r, crashInfo);
6954 }
6955
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006956 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006957 IBinder app,
6958 int violationMask,
6959 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006960 ProcessRecord r = findAppProcess(app, "StrictMode");
6961 if (r == null) {
6962 return;
6963 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006964
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006965 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006966 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006967 boolean logIt = true;
6968 synchronized (mAlreadyLoggedViolatedStacks) {
6969 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6970 logIt = false;
6971 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006972 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006973 // the relative pain numbers, without logging all
6974 // the stack traces repeatedly. We'd want to do
6975 // likewise in the client code, which also does
6976 // dup suppression, before the Binder call.
6977 } else {
6978 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6979 mAlreadyLoggedViolatedStacks.clear();
6980 }
6981 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6982 }
6983 }
6984 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006985 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006986 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006987 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006988
6989 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6990 AppErrorResult result = new AppErrorResult();
6991 synchronized (this) {
6992 final long origId = Binder.clearCallingIdentity();
6993
6994 Message msg = Message.obtain();
6995 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6996 HashMap<String, Object> data = new HashMap<String, Object>();
6997 data.put("result", result);
6998 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006999 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007000 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007001 msg.obj = data;
7002 mHandler.sendMessage(msg);
7003
7004 Binder.restoreCallingIdentity(origId);
7005 }
7006 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007007 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007008 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007009 }
7010
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007011 // Depending on the policy in effect, there could be a bunch of
7012 // these in quick succession so we try to batch these together to
7013 // minimize disk writes, number of dropbox entries, and maximize
7014 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007015 private void logStrictModeViolationToDropBox(
7016 ProcessRecord process,
7017 StrictMode.ViolationInfo info) {
7018 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007019 return;
7020 }
7021 final boolean isSystemApp = process == null ||
7022 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7023 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7024 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7025 final DropBoxManager dbox = (DropBoxManager)
7026 mContext.getSystemService(Context.DROPBOX_SERVICE);
7027
7028 // Exit early if the dropbox isn't configured to accept this report type.
7029 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7030
7031 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007032 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007033 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7034 synchronized (sb) {
7035 bufferWasEmpty = sb.length() == 0;
7036 appendDropBoxProcessHeaders(process, sb);
7037 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7038 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007039 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7040 if (info.violationNumThisLoop != 0) {
7041 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7042 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007043 if (info.numAnimationsRunning != 0) {
7044 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7045 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007046 if (info.broadcastIntentAction != null) {
7047 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7048 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007049 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007050 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007051 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007052 if (info.numInstances != -1) {
7053 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7054 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007055 if (info.tags != null) {
7056 for (String tag : info.tags) {
7057 sb.append("Span-Tag: ").append(tag).append("\n");
7058 }
7059 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007060 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007061 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7062 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007063 }
7064 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007065
7066 // Only buffer up to ~64k. Various logging bits truncate
7067 // things at 128k.
7068 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007069 }
7070
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007071 // Flush immediately if the buffer's grown too large, or this
7072 // is a non-system app. Non-system apps are isolated with a
7073 // different tag & policy and not batched.
7074 //
7075 // Batching is useful during internal testing with
7076 // StrictMode settings turned up high. Without batching,
7077 // thousands of separate files could be created on boot.
7078 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007079 new Thread("Error dump: " + dropboxTag) {
7080 @Override
7081 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007082 String report;
7083 synchronized (sb) {
7084 report = sb.toString();
7085 sb.delete(0, sb.length());
7086 sb.trimToSize();
7087 }
7088 if (report.length() != 0) {
7089 dbox.addText(dropboxTag, report);
7090 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007091 }
7092 }.start();
7093 return;
7094 }
7095
7096 // System app batching:
7097 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007098 // An existing dropbox-writing thread is outstanding, so
7099 // we don't need to start it up. The existing thread will
7100 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007101 return;
7102 }
7103
7104 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7105 // (After this point, we shouldn't access AMS internal data structures.)
7106 new Thread("Error dump: " + dropboxTag) {
7107 @Override
7108 public void run() {
7109 // 5 second sleep to let stacks arrive and be batched together
7110 try {
7111 Thread.sleep(5000); // 5 seconds
7112 } catch (InterruptedException e) {}
7113
7114 String errorReport;
7115 synchronized (mStrictModeBuffer) {
7116 errorReport = mStrictModeBuffer.toString();
7117 if (errorReport.length() == 0) {
7118 return;
7119 }
7120 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7121 mStrictModeBuffer.trimToSize();
7122 }
7123 dbox.addText(dropboxTag, errorReport);
7124 }
7125 }.start();
7126 }
7127
Dan Egnor60d87622009-12-16 16:32:58 -08007128 /**
7129 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7130 * @param app object of the crashing app, null for the system server
7131 * @param tag reported by the caller
7132 * @param crashInfo describing the context of the error
7133 * @return true if the process should exit immediately (WTF is fatal)
7134 */
7135 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007136 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007137 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007138
7139 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7140 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007141 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007142 tag, crashInfo.exceptionMessage);
7143
Dan Egnor42471dd2010-01-07 17:25:22 -08007144 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007145
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007146 if (r != null && r.pid != Process.myPid() &&
7147 Settings.Secure.getInt(mContext.getContentResolver(),
7148 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007149 crashApplication(r, crashInfo);
7150 return true;
7151 } else {
7152 return false;
7153 }
7154 }
7155
7156 /**
7157 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7158 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7159 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007160 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007161 if (app == null) {
7162 return null;
7163 }
7164
7165 synchronized (this) {
7166 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7167 final int NA = apps.size();
7168 for (int ia=0; ia<NA; ia++) {
7169 ProcessRecord p = apps.valueAt(ia);
7170 if (p.thread != null && p.thread.asBinder() == app) {
7171 return p;
7172 }
7173 }
7174 }
7175
Dianne Hackborncb44d962011-03-10 17:02:27 -08007176 Slog.w(TAG, "Can't find mystery application for " + reason
7177 + " from pid=" + Binder.getCallingPid()
7178 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007179 return null;
7180 }
7181 }
7182
7183 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007184 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7185 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007186 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007187 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007188 // Watchdog thread ends up invoking this function (with
7189 // a null ProcessRecord) to add the stack file to dropbox.
7190 // Do not acquire a lock on this (am) in such cases, as it
7191 // could cause a potential deadlock, if and when watchdog
7192 // is invoked due to unavailability of lock on am and it
7193 // would prevent watchdog from killing system_server.
7194 if (process == null) {
7195 sb.append("Process: system_server\n");
7196 return;
7197 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007198 // Note: ProcessRecord 'process' is guarded by the service
7199 // instance. (notably process.pkgList, which could otherwise change
7200 // concurrently during execution of this method)
7201 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007202 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007203 sb.append("Process: system_server\n");
7204 } else {
7205 sb.append("Process: ").append(process.processName).append("\n");
7206 }
Dan Egnora455d192010-03-12 08:52:28 -08007207 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007208 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007209 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7210 for (String pkg : process.pkgList) {
7211 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007212 try {
Dan Egnora455d192010-03-12 08:52:28 -08007213 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7214 if (pi != null) {
7215 sb.append(" v").append(pi.versionCode);
7216 if (pi.versionName != null) {
7217 sb.append(" (").append(pi.versionName).append(")");
7218 }
7219 }
7220 } catch (RemoteException e) {
7221 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007222 }
Dan Egnora455d192010-03-12 08:52:28 -08007223 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007224 }
Dan Egnora455d192010-03-12 08:52:28 -08007225 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007226 }
7227
7228 private static String processClass(ProcessRecord process) {
7229 if (process == null || process.pid == MY_PID) {
7230 return "system_server";
7231 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7232 return "system_app";
7233 } else {
7234 return "data_app";
7235 }
7236 }
7237
7238 /**
7239 * Write a description of an error (crash, WTF, ANR) to the drop box.
7240 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7241 * @param process which caused the error, null means the system server
7242 * @param activity which triggered the error, null if unknown
7243 * @param parent activity related to the error, null if unknown
7244 * @param subject line related to the error, null if absent
7245 * @param report in long form describing the error, null if absent
7246 * @param logFile to include in the report, null if none
7247 * @param crashInfo giving an application stack trace, null if absent
7248 */
7249 public void addErrorToDropBox(String eventType,
7250 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7251 final String report, final File logFile,
7252 final ApplicationErrorReport.CrashInfo crashInfo) {
7253 // NOTE -- this must never acquire the ActivityManagerService lock,
7254 // otherwise the watchdog may be prevented from resetting the system.
7255
7256 final String dropboxTag = processClass(process) + "_" + eventType;
7257 final DropBoxManager dbox = (DropBoxManager)
7258 mContext.getSystemService(Context.DROPBOX_SERVICE);
7259
7260 // Exit early if the dropbox isn't configured to accept this report type.
7261 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7262
7263 final StringBuilder sb = new StringBuilder(1024);
7264 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007265 if (activity != null) {
7266 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7267 }
7268 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7269 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7270 }
7271 if (parent != null && parent != activity) {
7272 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7273 }
7274 if (subject != null) {
7275 sb.append("Subject: ").append(subject).append("\n");
7276 }
7277 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007278 if (Debug.isDebuggerConnected()) {
7279 sb.append("Debugger: Connected\n");
7280 }
Dan Egnora455d192010-03-12 08:52:28 -08007281 sb.append("\n");
7282
7283 // Do the rest in a worker thread to avoid blocking the caller on I/O
7284 // (After this point, we shouldn't access AMS internal data structures.)
7285 Thread worker = new Thread("Error dump: " + dropboxTag) {
7286 @Override
7287 public void run() {
7288 if (report != null) {
7289 sb.append(report);
7290 }
7291 if (logFile != null) {
7292 try {
7293 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7294 } catch (IOException e) {
7295 Slog.e(TAG, "Error reading " + logFile, e);
7296 }
7297 }
7298 if (crashInfo != null && crashInfo.stackTrace != null) {
7299 sb.append(crashInfo.stackTrace);
7300 }
7301
7302 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7303 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7304 if (lines > 0) {
7305 sb.append("\n");
7306
7307 // Merge several logcat streams, and take the last N lines
7308 InputStreamReader input = null;
7309 try {
7310 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7311 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7312 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7313
7314 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7315 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7316 input = new InputStreamReader(logcat.getInputStream());
7317
7318 int num;
7319 char[] buf = new char[8192];
7320 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7321 } catch (IOException e) {
7322 Slog.e(TAG, "Error running logcat", e);
7323 } finally {
7324 if (input != null) try { input.close(); } catch (IOException e) {}
7325 }
7326 }
7327
7328 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007329 }
Dan Egnora455d192010-03-12 08:52:28 -08007330 };
7331
7332 if (process == null || process.pid == MY_PID) {
7333 worker.run(); // We may be about to die -- need to run this synchronously
7334 } else {
7335 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007336 }
7337 }
7338
7339 /**
7340 * Bring up the "unexpected error" dialog box for a crashing app.
7341 * Deal with edge cases (intercepts from instrumented applications,
7342 * ActivityController, error intent receivers, that sort of thing).
7343 * @param r the application crashing
7344 * @param crashInfo describing the failure
7345 */
7346 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007347 long timeMillis = System.currentTimeMillis();
7348 String shortMsg = crashInfo.exceptionClassName;
7349 String longMsg = crashInfo.exceptionMessage;
7350 String stackTrace = crashInfo.stackTrace;
7351 if (shortMsg != null && longMsg != null) {
7352 longMsg = shortMsg + ": " + longMsg;
7353 } else if (shortMsg != null) {
7354 longMsg = shortMsg;
7355 }
7356
Dan Egnor60d87622009-12-16 16:32:58 -08007357 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007359 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007360 try {
7361 String name = r != null ? r.processName : null;
7362 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007363 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007364 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007365 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 + " at watcher's request");
7367 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007368 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007369 }
7370 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007371 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 }
7373 }
7374
7375 final long origId = Binder.clearCallingIdentity();
7376
7377 // If this process is running instrumentation, finish it.
7378 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007379 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007381 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7382 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007383 Bundle info = new Bundle();
7384 info.putString("shortMsg", shortMsg);
7385 info.putString("longMsg", longMsg);
7386 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7387 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007388 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007389 }
7390
Dan Egnor60d87622009-12-16 16:32:58 -08007391 // If we can't identify the process or it's already exceeded its crash quota,
7392 // quit right away without showing a crash dialog.
7393 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007395 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007396 }
7397
7398 Message msg = Message.obtain();
7399 msg.what = SHOW_ERROR_MSG;
7400 HashMap data = new HashMap();
7401 data.put("result", result);
7402 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007403 msg.obj = data;
7404 mHandler.sendMessage(msg);
7405
7406 Binder.restoreCallingIdentity(origId);
7407 }
7408
7409 int res = result.get();
7410
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007411 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007412 synchronized (this) {
7413 if (r != null) {
7414 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7415 SystemClock.uptimeMillis());
7416 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007417 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007418 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007419 }
7420 }
7421
7422 if (appErrorIntent != null) {
7423 try {
7424 mContext.startActivity(appErrorIntent);
7425 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007426 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007429 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007430
7431 Intent createAppErrorIntentLocked(ProcessRecord r,
7432 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7433 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007434 if (report == null) {
7435 return null;
7436 }
7437 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7438 result.setComponent(r.errorReportReceiver);
7439 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7440 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7441 return result;
7442 }
7443
Dan Egnorb7f03672009-12-09 16:22:32 -08007444 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7445 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007446 if (r.errorReportReceiver == null) {
7447 return null;
7448 }
7449
7450 if (!r.crashing && !r.notResponding) {
7451 return null;
7452 }
7453
Dan Egnorb7f03672009-12-09 16:22:32 -08007454 ApplicationErrorReport report = new ApplicationErrorReport();
7455 report.packageName = r.info.packageName;
7456 report.installerPackageName = r.errorReportReceiver.getPackageName();
7457 report.processName = r.processName;
7458 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007459 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007460
Dan Egnorb7f03672009-12-09 16:22:32 -08007461 if (r.crashing) {
7462 report.type = ApplicationErrorReport.TYPE_CRASH;
7463 report.crashInfo = crashInfo;
7464 } else if (r.notResponding) {
7465 report.type = ApplicationErrorReport.TYPE_ANR;
7466 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007467
Dan Egnorb7f03672009-12-09 16:22:32 -08007468 report.anrInfo.activity = r.notRespondingReport.tag;
7469 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7470 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007471 }
7472
Dan Egnorb7f03672009-12-09 16:22:32 -08007473 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007474 }
7475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007476 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7477 // assume our apps are happy - lazy create the list
7478 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7479
7480 synchronized (this) {
7481
7482 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007483 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7484 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007485 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7486 // This one's in trouble, so we'll generate a report for it
7487 // crashes are higher priority (in case there's a crash *and* an anr)
7488 ActivityManager.ProcessErrorStateInfo report = null;
7489 if (app.crashing) {
7490 report = app.crashingReport;
7491 } else if (app.notResponding) {
7492 report = app.notRespondingReport;
7493 }
7494
7495 if (report != null) {
7496 if (errList == null) {
7497 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7498 }
7499 errList.add(report);
7500 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007501 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007502 " crashing = " + app.crashing +
7503 " notResponding = " + app.notResponding);
7504 }
7505 }
7506 }
7507 }
7508
7509 return errList;
7510 }
7511
7512 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7513 // Lazy instantiation of list
7514 List<ActivityManager.RunningAppProcessInfo> runList = null;
7515 synchronized (this) {
7516 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007517 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7518 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7520 // Generate process state info for running application
7521 ActivityManager.RunningAppProcessInfo currApp =
7522 new ActivityManager.RunningAppProcessInfo(app.processName,
7523 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007524 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007525 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007526 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007527 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007528 if (app.persistent) {
7529 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007531 int adj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007532 if (adj >= ProcessList.EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007534 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007535 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007536 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7537 } else if (adj >= ProcessList.HOME_APP_ADJ) {
The Android Open Source Project4df24232009-03-05 14:34:35 -08007538 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7539 currApp.lru = 0;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007540 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007542 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007543 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007544 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007545 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007546 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007547 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7548 } else {
7549 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7550 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007551 currApp.importanceReasonCode = app.adjTypeCode;
7552 if (app.adjSource instanceof ProcessRecord) {
7553 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007554 } else if (app.adjSource instanceof ActivityRecord) {
7555 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007556 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7557 }
7558 if (app.adjTarget instanceof ComponentName) {
7559 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7560 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007561 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007562 // + " lru=" + currApp.lru);
7563 if (runList == null) {
7564 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7565 }
7566 runList.add(currApp);
7567 }
7568 }
7569 }
7570 return runList;
7571 }
7572
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007573 public List<ApplicationInfo> getRunningExternalApplications() {
7574 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7575 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7576 if (runningApps != null && runningApps.size() > 0) {
7577 Set<String> extList = new HashSet<String>();
7578 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7579 if (app.pkgList != null) {
7580 for (String pkg : app.pkgList) {
7581 extList.add(pkg);
7582 }
7583 }
7584 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007585 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007586 for (String pkg : extList) {
7587 try {
7588 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7589 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7590 retList.add(info);
7591 }
7592 } catch (RemoteException e) {
7593 }
7594 }
7595 }
7596 return retList;
7597 }
7598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007599 @Override
7600 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007601 if (checkCallingPermission(android.Manifest.permission.DUMP)
7602 != PackageManager.PERMISSION_GRANTED) {
7603 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7604 + Binder.getCallingPid()
7605 + ", uid=" + Binder.getCallingUid()
7606 + " without permission "
7607 + android.Manifest.permission.DUMP);
7608 return;
7609 }
7610
7611 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007612 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007613
7614 int opti = 0;
7615 while (opti < args.length) {
7616 String opt = args[opti];
7617 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7618 break;
7619 }
7620 opti++;
7621 if ("-a".equals(opt)) {
7622 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007623 } else if ("-c".equals(opt)) {
7624 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007625 } else if ("-h".equals(opt)) {
7626 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007627 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007628 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007629 pw.println(" a[ctivities]: activity stack state");
7630 pw.println(" b[roadcasts]: broadcast state");
7631 pw.println(" i[ntents]: pending intent state");
7632 pw.println(" p[rocesses]: process state");
7633 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007634 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7635 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007636 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007637 pw.println(" all: dump all activities");
7638 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007639 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007640 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7641 pw.println(" a partial substring in a component name, a");
7642 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007643 pw.println(" -a: include all available server state.");
7644 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007645 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007646 } else {
7647 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007648 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007649 }
7650
7651 // Is the caller requesting to dump a particular piece of data?
7652 if (opti < args.length) {
7653 String cmd = args[opti];
7654 opti++;
7655 if ("activities".equals(cmd) || "a".equals(cmd)) {
7656 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007657 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007658 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007659 return;
7660 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7661 synchronized (this) {
7662 dumpBroadcastsLocked(fd, pw, args, opti, true);
7663 }
7664 return;
7665 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7666 synchronized (this) {
7667 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7668 }
7669 return;
7670 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7671 synchronized (this) {
7672 dumpProcessesLocked(fd, pw, args, opti, true);
7673 }
7674 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007675 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7676 synchronized (this) {
7677 dumpOomLocked(fd, pw, args, opti, true);
7678 }
7679 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007680 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7681 synchronized (this) {
7682 dumpProvidersLocked(fd, pw, args, opti, true);
7683 }
7684 return;
7685 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007686 String[] newArgs;
7687 String name;
7688 if (opti >= args.length) {
7689 name = null;
7690 newArgs = EMPTY_STRING_ARRAY;
7691 } else {
7692 name = args[opti];
7693 opti++;
7694 newArgs = new String[args.length - opti];
7695 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7696 }
7697 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7698 pw.println("No services match: " + name);
7699 pw.println("Use -h for help.");
7700 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007701 return;
7702 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7703 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007704 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007705 }
7706 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007707 } else {
7708 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007709 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7710 pw.println("Bad activity command, or no activities match: " + cmd);
7711 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007712 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007713 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007715 }
7716
7717 // No piece of data specified, dump everything.
7718 synchronized (this) {
7719 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007720 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007721 if (needSep) {
7722 pw.println(" ");
7723 }
7724 if (dumpAll) {
7725 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007726 }
7727 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7728 if (needSep) {
7729 pw.println(" ");
7730 }
7731 if (dumpAll) {
7732 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007733 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007734 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007735 if (needSep) {
7736 pw.println(" ");
7737 }
7738 if (dumpAll) {
7739 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007740 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007741 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007742 if (needSep) {
7743 pw.println(" ");
7744 }
7745 if (dumpAll) {
7746 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007747 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007748 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007749 if (needSep) {
7750 pw.println(" ");
7751 }
7752 if (dumpAll) {
7753 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007754 }
7755 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7756 }
7757 }
7758
7759 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007760 int opti, boolean dumpAll, boolean dumpClient) {
7761 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7762 pw.println(" Main stack:");
7763 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007764 pw.println(" ");
7765 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007766 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007767 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007768 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007769 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007770 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7771 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007772 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007773 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007774 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007775 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007776 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7777 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007779 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7780 pw.println(" ");
7781 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007782 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7783 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007784 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007785 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007786 pw.println(" ");
7787 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007788 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7789 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007791
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007792 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007793 if (mMainStack.mPausingActivity != null) {
7794 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7795 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007796 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007797 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007798 if (dumpAll) {
7799 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7800 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007803 if (mRecentTasks.size() > 0) {
7804 pw.println();
7805 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007806
7807 final int N = mRecentTasks.size();
7808 for (int i=0; i<N; i++) {
7809 TaskRecord tr = mRecentTasks.get(i);
7810 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7811 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007812 if (dumpAll) {
7813 mRecentTasks.get(i).dump(pw, " ");
7814 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007815 }
7816 }
7817
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007818 if (dumpAll) {
7819 pw.println(" ");
7820 pw.println(" mCurTask: " + mCurTask);
7821 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007822
7823 return true;
7824 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007825
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007826 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7827 int opti, boolean dumpAll) {
7828 boolean needSep = false;
7829 int numPers = 0;
7830
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007831 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7832
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007833 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007834 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7835 final int NA = procs.size();
7836 for (int ia=0; ia<NA; ia++) {
7837 if (!needSep) {
7838 pw.println(" All known processes:");
7839 needSep = true;
7840 }
7841 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007842 pw.print(r.persistent ? " *PERS*" : " *APP*");
7843 pw.print(" UID "); pw.print(procs.keyAt(ia));
7844 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007845 r.dump(pw, " ");
7846 if (r.persistent) {
7847 numPers++;
7848 }
7849 }
7850 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007851 }
7852
7853 if (mLruProcesses.size() > 0) {
7854 if (needSep) pw.println(" ");
7855 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007856 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007857 dumpProcessOomList(pw, this, mLruProcesses, " ",
7858 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007859 needSep = true;
7860 }
7861
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007862 if (dumpAll) {
7863 synchronized (mPidsSelfLocked) {
7864 if (mPidsSelfLocked.size() > 0) {
7865 if (needSep) pw.println(" ");
7866 needSep = true;
7867 pw.println(" PID mappings:");
7868 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7869 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7870 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007872 }
7873 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007874 }
7875
7876 if (mForegroundProcesses.size() > 0) {
7877 if (needSep) pw.println(" ");
7878 needSep = true;
7879 pw.println(" Foreground Processes:");
7880 for (int i=0; i<mForegroundProcesses.size(); i++) {
7881 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7882 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007883 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007884 }
7885
7886 if (mPersistentStartingProcesses.size() > 0) {
7887 if (needSep) pw.println(" ");
7888 needSep = true;
7889 pw.println(" Persisent processes that are starting:");
7890 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007891 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007893
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007894 if (mRemovedProcesses.size() > 0) {
7895 if (needSep) pw.println(" ");
7896 needSep = true;
7897 pw.println(" Processes that are being removed:");
7898 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007899 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900 }
7901
7902 if (mProcessesOnHold.size() > 0) {
7903 if (needSep) pw.println(" ");
7904 needSep = true;
7905 pw.println(" Processes that are on old until the system is ready:");
7906 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007907 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909
Dianne Hackborn287952c2010-09-22 22:34:31 -07007910 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911
7912 if (mProcessCrashTimes.getMap().size() > 0) {
7913 if (needSep) pw.println(" ");
7914 needSep = true;
7915 pw.println(" Time since processes crashed:");
7916 long now = SystemClock.uptimeMillis();
7917 for (Map.Entry<String, SparseArray<Long>> procs
7918 : mProcessCrashTimes.getMap().entrySet()) {
7919 SparseArray<Long> uids = procs.getValue();
7920 final int N = uids.size();
7921 for (int i=0; i<N; i++) {
7922 pw.print(" Process "); pw.print(procs.getKey());
7923 pw.print(" uid "); pw.print(uids.keyAt(i));
7924 pw.print(": last crashed ");
7925 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007926 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007927 }
7928 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007930
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007931 if (mBadProcesses.getMap().size() > 0) {
7932 if (needSep) pw.println(" ");
7933 needSep = true;
7934 pw.println(" Bad processes:");
7935 for (Map.Entry<String, SparseArray<Long>> procs
7936 : mBadProcesses.getMap().entrySet()) {
7937 SparseArray<Long> uids = procs.getValue();
7938 final int N = uids.size();
7939 for (int i=0; i<N; i++) {
7940 pw.print(" Bad process "); pw.print(procs.getKey());
7941 pw.print(" uid "); pw.print(uids.keyAt(i));
7942 pw.print(": crashed at time ");
7943 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007944 }
7945 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007947
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007948 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007949 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007950 if (mHeavyWeightProcess != null) {
7951 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7952 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007953 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007954 if (dumpAll) {
7955 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007956 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007957 pw.println(" mScreenCompatPackages:");
7958 for (Map.Entry<String, Integer> entry
7959 : mCompatModePackages.getPackages().entrySet()) {
7960 String pkg = entry.getKey();
7961 int mode = entry.getValue();
7962 pw.print(" "); pw.print(pkg); pw.print(": ");
7963 pw.print(mode); pw.println();
7964 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007965 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007966 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007967 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7968 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7969 || mOrigWaitForDebugger) {
7970 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7971 + " mDebugTransient=" + mDebugTransient
7972 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7973 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007974 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
7975 || mProfileFd != null) {
7976 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
7977 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
7978 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
7979 + mAutoStopProfiler);
7980 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007981 if (mAlwaysFinishActivities || mController != null) {
7982 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7983 + " mController=" + mController);
7984 }
7985 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007988 + " mProcessesReady=" + mProcessesReady
7989 + " mSystemReady=" + mSystemReady);
7990 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007991 + " mBooted=" + mBooted
7992 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007993 pw.print(" mLastPowerCheckRealtime=");
7994 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7995 pw.println("");
7996 pw.print(" mLastPowerCheckUptime=");
7997 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7998 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007999 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8000 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008001 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008002 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008003
8004 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008005 }
8006
Dianne Hackborn287952c2010-09-22 22:34:31 -07008007 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8008 int opti, boolean needSep, boolean dumpAll) {
8009 if (mProcessesToGc.size() > 0) {
8010 if (needSep) pw.println(" ");
8011 needSep = true;
8012 pw.println(" Processes that are waiting to GC:");
8013 long now = SystemClock.uptimeMillis();
8014 for (int i=0; i<mProcessesToGc.size(); i++) {
8015 ProcessRecord proc = mProcessesToGc.get(i);
8016 pw.print(" Process "); pw.println(proc);
8017 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8018 pw.print(", last gced=");
8019 pw.print(now-proc.lastRequestedGc);
8020 pw.print(" ms ago, last lowMem=");
8021 pw.print(now-proc.lastLowMemory);
8022 pw.println(" ms ago");
8023
8024 }
8025 }
8026 return needSep;
8027 }
8028
8029 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8030 int opti, boolean dumpAll) {
8031 boolean needSep = false;
8032
8033 if (mLruProcesses.size() > 0) {
8034 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8035
8036 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8037 @Override
8038 public int compare(ProcessRecord object1, ProcessRecord object2) {
8039 if (object1.setAdj != object2.setAdj) {
8040 return object1.setAdj > object2.setAdj ? -1 : 1;
8041 }
8042 if (object1.setSchedGroup != object2.setSchedGroup) {
8043 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8044 }
8045 if (object1.keeping != object2.keeping) {
8046 return object1.keeping ? -1 : 1;
8047 }
8048 if (object1.pid != object2.pid) {
8049 return object1.pid > object2.pid ? -1 : 1;
8050 }
8051 return 0;
8052 }
8053 };
8054
8055 Collections.sort(procs, comparator);
8056
8057 if (needSep) pw.println(" ");
8058 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008059 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008060 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8061 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8062 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8063 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8064 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8065 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8066 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8067 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8068 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8069 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8070 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008071
8072 if (needSep) pw.println(" ");
8073 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008074 pw.println(" Process OOM control:");
8075 dumpProcessOomList(pw, this, procs, " ",
8076 "Proc", "PERS", true);
8077 needSep = true;
8078 }
8079
8080 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8081
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008082 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008083 pw.println(" mHomeProcess: " + mHomeProcess);
8084 if (mHeavyWeightProcess != null) {
8085 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8086 }
8087
8088 return true;
8089 }
8090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 /**
8092 * There are three ways to call this:
8093 * - no service specified: dump all the services
8094 * - a flattened component name that matched an existing service was specified as the
8095 * first arg: dump that one service
8096 * - the first arg isn't the flattened component name of an existing service:
8097 * dump all services whose component contains the first arg as a substring
8098 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008099 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8100 int opti, boolean dumpAll) {
8101 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008102
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008103 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008104 synchronized (this) {
8105 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008106 services.add(r1);
8107 }
8108 }
8109 } else {
8110 ComponentName componentName = name != null
8111 ? ComponentName.unflattenFromString(name) : null;
8112 int objectId = 0;
8113 if (componentName == null) {
8114 // Not a '/' separated full component name; maybe an object ID?
8115 try {
8116 objectId = Integer.parseInt(name, 16);
8117 name = null;
8118 componentName = null;
8119 } catch (RuntimeException e) {
8120 }
8121 }
8122
8123 synchronized (this) {
8124 for (ServiceRecord r1 : mServices.values()) {
8125 if (componentName != null) {
8126 if (r1.name.equals(componentName)) {
8127 services.add(r1);
8128 }
8129 } else if (name != null) {
8130 if (r1.name.flattenToString().contains(name)) {
8131 services.add(r1);
8132 }
8133 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008134 services.add(r1);
8135 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008136 }
8137 }
8138 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008139
8140 if (services.size() <= 0) {
8141 return false;
8142 }
8143
8144 boolean needSep = false;
8145 for (int i=0; i<services.size(); i++) {
8146 if (needSep) {
8147 pw.println();
8148 }
8149 needSep = true;
8150 dumpService("", fd, pw, services.get(i), args, dumpAll);
8151 }
8152 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 }
8154
8155 /**
8156 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8157 * there is a thread associated with the service.
8158 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008159 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8160 final ServiceRecord r, String[] args, boolean dumpAll) {
8161 String innerPrefix = prefix + " ";
8162 synchronized (this) {
8163 pw.print(prefix); pw.print("SERVICE ");
8164 pw.print(r.shortName); pw.print(" ");
8165 pw.print(Integer.toHexString(System.identityHashCode(r)));
8166 pw.print(" pid=");
8167 if (r.app != null) pw.println(r.app.pid);
8168 else pw.println("(not running)");
8169 if (dumpAll) {
8170 r.dump(pw, innerPrefix);
8171 }
8172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008173 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008174 pw.print(prefix); pw.println(" Client:");
8175 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008177 TransferPipe tp = new TransferPipe();
8178 try {
8179 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8180 tp.setBufferPrefix(prefix + " ");
8181 tp.go(fd);
8182 } finally {
8183 tp.kill();
8184 }
8185 } catch (IOException e) {
8186 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008187 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008188 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008189 }
8190 }
8191 }
8192
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008193 static class ItemMatcher {
8194 ArrayList<ComponentName> components;
8195 ArrayList<String> strings;
8196 ArrayList<Integer> objects;
8197 boolean all;
8198
8199 ItemMatcher() {
8200 all = true;
8201 }
8202
8203 void build(String name) {
8204 ComponentName componentName = ComponentName.unflattenFromString(name);
8205 if (componentName != null) {
8206 if (components == null) {
8207 components = new ArrayList<ComponentName>();
8208 }
8209 components.add(componentName);
8210 all = false;
8211 } else {
8212 int objectId = 0;
8213 // Not a '/' separated full component name; maybe an object ID?
8214 try {
8215 objectId = Integer.parseInt(name, 16);
8216 if (objects == null) {
8217 objects = new ArrayList<Integer>();
8218 }
8219 objects.add(objectId);
8220 all = false;
8221 } catch (RuntimeException e) {
8222 // Not an integer; just do string match.
8223 if (strings == null) {
8224 strings = new ArrayList<String>();
8225 }
8226 strings.add(name);
8227 all = false;
8228 }
8229 }
8230 }
8231
8232 int build(String[] args, int opti) {
8233 for (; opti<args.length; opti++) {
8234 String name = args[opti];
8235 if ("--".equals(name)) {
8236 return opti+1;
8237 }
8238 build(name);
8239 }
8240 return opti;
8241 }
8242
8243 boolean match(Object object, ComponentName comp) {
8244 if (all) {
8245 return true;
8246 }
8247 if (components != null) {
8248 for (int i=0; i<components.size(); i++) {
8249 if (components.get(i).equals(comp)) {
8250 return true;
8251 }
8252 }
8253 }
8254 if (objects != null) {
8255 for (int i=0; i<objects.size(); i++) {
8256 if (System.identityHashCode(object) == objects.get(i)) {
8257 return true;
8258 }
8259 }
8260 }
8261 if (strings != null) {
8262 String flat = comp.flattenToString();
8263 for (int i=0; i<strings.size(); i++) {
8264 if (flat.contains(strings.get(i))) {
8265 return true;
8266 }
8267 }
8268 }
8269 return false;
8270 }
8271 }
8272
Dianne Hackborn625ac272010-09-17 18:29:22 -07008273 /**
8274 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008275 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008276 * - the cmd arg isn't the flattened component name of an existing activity:
8277 * dump all activity whose component contains the cmd as a substring
8278 * - A hex number of the ActivityRecord object instance.
8279 */
8280 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8281 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008282 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008283
8284 if ("all".equals(name)) {
8285 synchronized (this) {
8286 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008287 activities.add(r1);
8288 }
8289 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008290 } else if ("top".equals(name)) {
8291 synchronized (this) {
8292 final int N = mMainStack.mHistory.size();
8293 if (N > 0) {
8294 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8295 }
8296 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008297 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008298 ItemMatcher matcher = new ItemMatcher();
8299 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008300
8301 synchronized (this) {
8302 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008303 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008304 activities.add(r1);
8305 }
8306 }
8307 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008308 }
8309
8310 if (activities.size() <= 0) {
8311 return false;
8312 }
8313
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008314 String[] newArgs = new String[args.length - opti];
8315 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8316
Dianne Hackborn30d71892010-12-11 10:37:55 -08008317 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008318 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008319 for (int i=activities.size()-1; i>=0; i--) {
8320 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008321 if (needSep) {
8322 pw.println();
8323 }
8324 needSep = true;
8325 synchronized (this) {
8326 if (lastTask != r.task) {
8327 lastTask = r.task;
8328 pw.print("TASK "); pw.print(lastTask.affinity);
8329 pw.print(" id="); pw.println(lastTask.taskId);
8330 if (dumpAll) {
8331 lastTask.dump(pw, " ");
8332 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008333 }
8334 }
8335 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008336 }
8337 return true;
8338 }
8339
8340 /**
8341 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8342 * there is a thread associated with the activity.
8343 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008344 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008345 final ActivityRecord r, String[] args, boolean dumpAll) {
8346 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008347 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008348 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8349 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8350 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008351 if (r.app != null) pw.println(r.app.pid);
8352 else pw.println("(not running)");
8353 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008354 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008355 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008356 }
8357 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008358 // flush anything that is already in the PrintWriter since the thread is going
8359 // to write to the file descriptor directly
8360 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008361 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008362 TransferPipe tp = new TransferPipe();
8363 try {
8364 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8365 innerPrefix, args);
8366 tp.go(fd);
8367 } finally {
8368 tp.kill();
8369 }
8370 } catch (IOException e) {
8371 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008372 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008373 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008374 }
8375 }
8376 }
8377
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008378 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8379 int opti, boolean dumpAll) {
8380 boolean needSep = false;
8381
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008382 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008383 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008384 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008385 pw.println(" Registered Receivers:");
8386 Iterator it = mRegisteredReceivers.values().iterator();
8387 while (it.hasNext()) {
8388 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008389 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008390 r.dump(pw, " ");
8391 }
8392 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008393
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008394 pw.println();
8395 pw.println(" Receiver Resolver Table:");
8396 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008397 needSep = true;
8398 }
8399
8400 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8401 || mPendingBroadcast != null) {
8402 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008403 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008404 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008406 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8407 pw.println(" Broadcast #" + i + ":");
8408 mParallelBroadcasts.get(i).dump(pw, " ");
8409 }
8410 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008411 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008412 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008413 }
8414 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8415 pw.println(" Serialized Broadcast #" + i + ":");
8416 mOrderedBroadcasts.get(i).dump(pw, " ");
8417 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008418 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008419 pw.println(" Pending broadcast:");
8420 if (mPendingBroadcast != null) {
8421 mPendingBroadcast.dump(pw, " ");
8422 } else {
8423 pw.println(" (null)");
8424 }
8425 needSep = true;
8426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008427
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008428 if (needSep) {
8429 pw.println();
8430 }
8431 pw.println(" Historical broadcasts:");
8432 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8433 BroadcastRecord r = mBroadcastHistory[i];
8434 if (r == null) {
8435 break;
8436 }
8437 if (dumpAll) {
8438 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8439 r.dump(pw, " ");
8440 } else {
8441 if (i >= 50) {
8442 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008443 break;
8444 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008445 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008446 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008447 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008448 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008449
8450 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008451 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008452 pw.println(" Sticky broadcasts:");
8453 StringBuilder sb = new StringBuilder(128);
8454 for (Map.Entry<String, ArrayList<Intent>> ent
8455 : mStickyBroadcasts.entrySet()) {
8456 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008457 if (dumpAll) {
8458 pw.println(":");
8459 ArrayList<Intent> intents = ent.getValue();
8460 final int N = intents.size();
8461 for (int i=0; i<N; i++) {
8462 sb.setLength(0);
8463 sb.append(" Intent: ");
8464 intents.get(i).toShortString(sb, true, false);
8465 pw.println(sb.toString());
8466 Bundle bundle = intents.get(i).getExtras();
8467 if (bundle != null) {
8468 pw.print(" ");
8469 pw.println(bundle.toString());
8470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008471 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008472 } else {
8473 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 }
8475 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008476 needSep = true;
8477 }
8478
8479 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008480 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008481 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 pw.println(" mHandler:");
8483 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008484 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008486
8487 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008488 }
8489
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008490 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008491 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008492 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008493
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008494 ItemMatcher matcher = new ItemMatcher();
8495 matcher.build(args, opti);
8496
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008497 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8498 if (mServices.size() > 0) {
8499 pw.println(" Active services:");
8500 long nowReal = SystemClock.elapsedRealtime();
8501 Iterator<ServiceRecord> it = mServices.values().iterator();
8502 needSep = false;
8503 while (it.hasNext()) {
8504 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008505 if (!matcher.match(r, r.name)) {
8506 continue;
8507 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008508 if (needSep) {
8509 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008511 pw.print(" * "); pw.println(r);
8512 if (dumpAll) {
8513 r.dump(pw, " ");
8514 needSep = true;
8515 } else {
8516 pw.print(" app="); pw.println(r.app);
8517 pw.print(" created=");
8518 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8519 pw.print(" started="); pw.print(r.startRequested);
8520 pw.print(" connections="); pw.println(r.connections.size());
8521 }
8522 if (dumpClient && r.app != null && r.app.thread != null) {
8523 pw.println(" Client:");
8524 pw.flush();
8525 try {
8526 TransferPipe tp = new TransferPipe();
8527 try {
8528 r.app.thread.dumpService(
8529 tp.getWriteFd().getFileDescriptor(), r, args);
8530 tp.setBufferPrefix(" ");
8531 // Short timeout, since blocking here can
8532 // deadlock with the application.
8533 tp.go(fd, 2000);
8534 } finally {
8535 tp.kill();
8536 }
8537 } catch (IOException e) {
8538 pw.println(" Failure while dumping the service: " + e);
8539 } catch (RemoteException e) {
8540 pw.println(" Got a RemoteException while dumping the service");
8541 }
8542 needSep = true;
8543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008544 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008545 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008547
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008548 if (mPendingServices.size() > 0) {
8549 if (needSep) pw.println(" ");
8550 pw.println(" Pending services:");
8551 for (int i=0; i<mPendingServices.size(); i++) {
8552 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008553 if (!matcher.match(r, r.name)) {
8554 continue;
8555 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008556 pw.print(" * Pending "); pw.println(r);
8557 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008558 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008559 needSep = true;
8560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008561
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008562 if (mRestartingServices.size() > 0) {
8563 if (needSep) pw.println(" ");
8564 pw.println(" Restarting services:");
8565 for (int i=0; i<mRestartingServices.size(); i++) {
8566 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008567 if (!matcher.match(r, r.name)) {
8568 continue;
8569 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008570 pw.print(" * Restarting "); pw.println(r);
8571 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008573 needSep = true;
8574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008576 if (mStoppingServices.size() > 0) {
8577 if (needSep) pw.println(" ");
8578 pw.println(" Stopping services:");
8579 for (int i=0; i<mStoppingServices.size(); i++) {
8580 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008581 if (!matcher.match(r, r.name)) {
8582 continue;
8583 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008584 pw.print(" * Stopping "); pw.println(r);
8585 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008587 needSep = true;
8588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008590 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008591 if (mServiceConnections.size() > 0) {
8592 if (needSep) pw.println(" ");
8593 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008594 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008595 = mServiceConnections.values().iterator();
8596 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008597 ArrayList<ConnectionRecord> r = it.next();
8598 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008599 ConnectionRecord cr = r.get(i);
8600 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8601 continue;
8602 }
8603 pw.print(" * "); pw.println(cr);
8604 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008607 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 }
8609 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008610
8611 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008612 }
8613
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008614 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8615 int opti, boolean dumpAll) {
8616 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008617
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008618 ItemMatcher matcher = new ItemMatcher();
8619 matcher.build(args, opti);
8620
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008621 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8622 if (mProvidersByClass.size() > 0) {
8623 if (needSep) pw.println(" ");
8624 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008625 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008626 = mProvidersByClass.entrySet().iterator();
8627 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008628 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008629 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008630 ComponentName comp = e.getKey();
8631 String cls = comp.getClassName();
8632 int end = cls.lastIndexOf('.');
8633 if (end > 0 && end < (cls.length()-2)) {
8634 cls = cls.substring(end+1);
8635 }
8636 if (!matcher.match(r, comp)) {
8637 continue;
8638 }
8639 pw.print(" * "); pw.print(cls); pw.print(" (");
8640 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008641 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008642 pw.println();
8643 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008644 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008645 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008646 if (r.app != null) {
8647 pw.println(":");
8648 pw.print(" "); pw.println(r.app);
8649 } else {
8650 pw.println();
8651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008653 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008654 needSep = true;
8655 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008656
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008657 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008658 if (mProvidersByName.size() > 0) {
8659 pw.println(" ");
8660 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008661 Iterator<Map.Entry<String, ContentProviderRecord>> it
8662 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008663 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008664 Map.Entry<String, ContentProviderRecord> e = it.next();
8665 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008666 if (!matcher.match(r, r.name)) {
8667 continue;
8668 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008669 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8670 pw.println(r);
8671 }
8672 needSep = true;
8673 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008675
8676 if (mLaunchingProviders.size() > 0) {
8677 if (needSep) pw.println(" ");
8678 pw.println(" Launching content providers:");
8679 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8680 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8681 pw.println(mLaunchingProviders.get(i));
8682 }
8683 needSep = true;
8684 }
8685
8686 if (mGrantedUriPermissions.size() > 0) {
8687 pw.println();
8688 pw.println("Granted Uri Permissions:");
8689 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8690 int uid = mGrantedUriPermissions.keyAt(i);
8691 HashMap<Uri, UriPermission> perms
8692 = mGrantedUriPermissions.valueAt(i);
8693 pw.print(" * UID "); pw.print(uid);
8694 pw.println(" holds:");
8695 for (UriPermission perm : perms.values()) {
8696 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008697 if (dumpAll) {
8698 perm.dump(pw, " ");
8699 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008700 }
8701 }
8702 needSep = true;
8703 }
8704
8705 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 }
8707
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008708 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8709 int opti, boolean dumpAll) {
8710 boolean needSep = false;
8711
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008712 if (this.mIntentSenderRecords.size() > 0) {
8713 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8714 Iterator<WeakReference<PendingIntentRecord>> it
8715 = mIntentSenderRecords.values().iterator();
8716 while (it.hasNext()) {
8717 WeakReference<PendingIntentRecord> ref = it.next();
8718 PendingIntentRecord rec = ref != null ? ref.get(): null;
8719 needSep = true;
8720 if (rec != null) {
8721 pw.print(" * "); pw.println(rec);
8722 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008723 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008724 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008725 } else {
8726 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008727 }
8728 }
8729 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008730
8731 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008732 }
8733
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008734 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8735 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008736 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008737 boolean needNL = false;
8738 final String innerPrefix = prefix + " ";
8739 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008740 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008741 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008742 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008743 if (needNL) {
8744 pw.println(" ");
8745 needNL = false;
8746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008747 if (lastTask != r.task) {
8748 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008749 pw.print(prefix);
8750 pw.print(full ? "* " : " ");
8751 pw.println(lastTask);
8752 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008753 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008754 } else if (complete) {
8755 // Complete + brief == give a summary. Isn't that obvious?!?
8756 if (lastTask.intent != null) {
8757 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8758 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008760 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008761 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8762 pw.print(" #"); pw.print(i); pw.print(": ");
8763 pw.println(r);
8764 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008765 r.dump(pw, innerPrefix);
8766 } else if (complete) {
8767 // Complete + brief == give a summary. Isn't that obvious?!?
8768 pw.print(innerPrefix); pw.println(r.intent);
8769 if (r.app != null) {
8770 pw.print(innerPrefix); pw.println(r.app);
8771 }
8772 }
8773 if (client && r.app != null && r.app.thread != null) {
8774 // flush anything that is already in the PrintWriter since the thread is going
8775 // to write to the file descriptor directly
8776 pw.flush();
8777 try {
8778 TransferPipe tp = new TransferPipe();
8779 try {
8780 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8781 innerPrefix, args);
8782 // Short timeout, since blocking here can
8783 // deadlock with the application.
8784 tp.go(fd, 2000);
8785 } finally {
8786 tp.kill();
8787 }
8788 } catch (IOException e) {
8789 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8790 } catch (RemoteException e) {
8791 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8792 }
8793 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008795 }
8796 }
8797
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008798 private static String buildOomTag(String prefix, String space, int val, int base) {
8799 if (val == base) {
8800 if (space == null) return prefix;
8801 return prefix + " ";
8802 }
8803 return prefix + "+" + Integer.toString(val-base);
8804 }
8805
8806 private static final int dumpProcessList(PrintWriter pw,
8807 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008808 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008809 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008810 final int N = list.size()-1;
8811 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008812 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008813 pw.println(String.format("%s%s #%2d: %s",
8814 prefix, (r.persistent ? persistentLabel : normalLabel),
8815 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008816 if (r.persistent) {
8817 numPers++;
8818 }
8819 }
8820 return numPers;
8821 }
8822
Dianne Hackborn287952c2010-09-22 22:34:31 -07008823 private static final void dumpProcessOomList(PrintWriter pw,
8824 ActivityManagerService service, List<ProcessRecord> list,
8825 String prefix, String normalLabel, String persistentLabel,
8826 boolean inclDetails) {
8827
8828 final long curRealtime = SystemClock.elapsedRealtime();
8829 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8830 final long curUptime = SystemClock.uptimeMillis();
8831 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8832
8833 final int N = list.size()-1;
8834 for (int i=N; i>=0; i--) {
8835 ProcessRecord r = list.get(i);
8836 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008837 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8838 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8839 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8840 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8841 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8842 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8843 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8844 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8845 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8846 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8847 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8848 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8849 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8850 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8851 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8852 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8853 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8854 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8855 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8856 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8857 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8858 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008859 } else {
8860 oomAdj = Integer.toString(r.setAdj);
8861 }
8862 String schedGroup;
8863 switch (r.setSchedGroup) {
8864 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8865 schedGroup = "B";
8866 break;
8867 case Process.THREAD_GROUP_DEFAULT:
8868 schedGroup = "F";
8869 break;
8870 default:
8871 schedGroup = Integer.toString(r.setSchedGroup);
8872 break;
8873 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008874 String foreground;
8875 if (r.foregroundActivities) {
8876 foreground = "A";
8877 } else if (r.foregroundServices) {
8878 foreground = "S";
8879 } else {
8880 foreground = " ";
8881 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008882 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008883 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008884 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8885 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008886 if (r.adjSource != null || r.adjTarget != null) {
8887 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008889 if (r.adjTarget instanceof ComponentName) {
8890 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8891 } else if (r.adjTarget != null) {
8892 pw.print(r.adjTarget.toString());
8893 } else {
8894 pw.print("{null}");
8895 }
8896 pw.print("<=");
8897 if (r.adjSource instanceof ProcessRecord) {
8898 pw.print("Proc{");
8899 pw.print(((ProcessRecord)r.adjSource).toShortString());
8900 pw.println("}");
8901 } else if (r.adjSource != null) {
8902 pw.println(r.adjSource.toString());
8903 } else {
8904 pw.println("{null}");
8905 }
8906 }
8907 if (inclDetails) {
8908 pw.print(prefix);
8909 pw.print(" ");
8910 pw.print("oom: max="); pw.print(r.maxAdj);
8911 pw.print(" hidden="); pw.print(r.hiddenAdj);
8912 pw.print(" curRaw="); pw.print(r.curRawAdj);
8913 pw.print(" setRaw="); pw.print(r.setRawAdj);
8914 pw.print(" cur="); pw.print(r.curAdj);
8915 pw.print(" set="); pw.println(r.setAdj);
8916 pw.print(prefix);
8917 pw.print(" ");
8918 pw.print("keeping="); pw.print(r.keeping);
8919 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008920 pw.print(" empty="); pw.print(r.empty);
8921 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008922
8923 if (!r.keeping) {
8924 if (r.lastWakeTime != 0) {
8925 long wtime;
8926 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8927 synchronized (stats) {
8928 wtime = stats.getProcessWakeTime(r.info.uid,
8929 r.pid, curRealtime);
8930 }
8931 long timeUsed = wtime - r.lastWakeTime;
8932 pw.print(prefix);
8933 pw.print(" ");
8934 pw.print("keep awake over ");
8935 TimeUtils.formatDuration(realtimeSince, pw);
8936 pw.print(" used ");
8937 TimeUtils.formatDuration(timeUsed, pw);
8938 pw.print(" (");
8939 pw.print((timeUsed*100)/realtimeSince);
8940 pw.println("%)");
8941 }
8942 if (r.lastCpuTime != 0) {
8943 long timeUsed = r.curCpuTime - r.lastCpuTime;
8944 pw.print(prefix);
8945 pw.print(" ");
8946 pw.print("run cpu over ");
8947 TimeUtils.formatDuration(uptimeSince, pw);
8948 pw.print(" used ");
8949 TimeUtils.formatDuration(timeUsed, pw);
8950 pw.print(" (");
8951 pw.print((timeUsed*100)/uptimeSince);
8952 pw.println("%)");
8953 }
8954 }
8955 }
8956 }
8957 }
8958
Dianne Hackbornb437e092011-08-05 17:50:29 -07008959 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008960 ArrayList<ProcessRecord> procs;
8961 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008962 if (args != null && args.length > start
8963 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008964 procs = new ArrayList<ProcessRecord>();
8965 int pid = -1;
8966 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008967 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008968 } catch (NumberFormatException e) {
8969
8970 }
8971 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8972 ProcessRecord proc = mLruProcesses.get(i);
8973 if (proc.pid == pid) {
8974 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07008975 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008976 procs.add(proc);
8977 }
8978 }
8979 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008980 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008981 return null;
8982 }
8983 } else {
8984 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8985 }
8986 }
8987 return procs;
8988 }
8989
8990 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8991 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008992 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008993 if (procs == null) {
8994 return;
8995 }
8996
8997 long uptime = SystemClock.uptimeMillis();
8998 long realtime = SystemClock.elapsedRealtime();
8999 pw.println("Applications Graphics Acceleration Info:");
9000 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9001
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009002 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9003 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009004 if (r.thread != null) {
9005 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9006 pw.flush();
9007 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009008 TransferPipe tp = new TransferPipe();
9009 try {
9010 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9011 tp.go(fd);
9012 } finally {
9013 tp.kill();
9014 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009015 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009016 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009017 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009018 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009019 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009020 pw.flush();
9021 }
9022 }
9023 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009024 }
9025
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009026 final static class MemItem {
9027 final String label;
9028 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009029 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009030
9031 public MemItem(String _label, long _pss) {
9032 label = _label;
9033 pss = _pss;
9034 }
9035 }
9036
Dianne Hackbornb437e092011-08-05 17:50:29 -07009037 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9038 boolean sort) {
9039 if (sort) {
9040 Collections.sort(items, new Comparator<MemItem>() {
9041 @Override
9042 public int compare(MemItem lhs, MemItem rhs) {
9043 if (lhs.pss < rhs.pss) {
9044 return 1;
9045 } else if (lhs.pss > rhs.pss) {
9046 return -1;
9047 }
9048 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009049 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009050 });
9051 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009052
9053 for (int i=0; i<items.size(); i++) {
9054 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009055 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9056 if (mi.subitems != null) {
9057 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9058 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009059 }
9060 }
9061
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009062 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9063 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009064 boolean dumpAll = false;
9065
9066 int opti = 0;
9067 while (opti < args.length) {
9068 String opt = args[opti];
9069 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9070 break;
9071 }
9072 opti++;
9073 if ("-a".equals(opt)) {
9074 dumpAll = true;
9075 } else if ("-h".equals(opt)) {
9076 pw.println("meminfo dump options: [-a] [process]");
9077 pw.println(" -a: include all available information for each process.");
9078 pw.println("If [process] is specified it can be the name or ");
9079 pw.println("pid of a specific process to dump.");
9080 return;
9081 } else {
9082 pw.println("Unknown argument: " + opt + "; use -h for help");
9083 }
9084 }
9085
9086 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009087 if (procs == null) {
9088 return;
9089 }
9090
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009091 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009092 long uptime = SystemClock.uptimeMillis();
9093 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009094
9095 if (procs.size() == 1 || isCheckinRequest) {
9096 dumpAll = true;
9097 }
9098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009099 if (isCheckinRequest) {
9100 // short checkin version
9101 pw.println(uptime + "," + realtime);
9102 pw.flush();
9103 } else {
9104 pw.println("Applications Memory Usage (kB):");
9105 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9106 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009107
Dianne Hackbornb437e092011-08-05 17:50:29 -07009108 String[] innerArgs = new String[args.length-opti];
9109 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9110
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009111 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9112 long nativePss=0, dalvikPss=0, otherPss=0;
9113 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9114
Dianne Hackbornb437e092011-08-05 17:50:29 -07009115 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009116 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9117 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9118 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009119 };
9120 final String[] oomLabel = new String[] {
9121 "System", "Persistent", "Foreground",
9122 "Visible", "Perceptible", "Heavy Weight",
9123 "Backup", "Services", "Home", "Background"
9124 };
9125 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009126 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009127
9128 long totalPss = 0;
9129
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009130 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9131 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009132 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009133 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009134 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9135 pw.flush();
9136 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009137 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009138 if (dumpAll) {
9139 try {
9140 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9141 } catch (RemoteException e) {
9142 if (!isCheckinRequest) {
9143 pw.println("Got RemoteException!");
9144 pw.flush();
9145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009147 } else {
9148 mi = new Debug.MemoryInfo();
9149 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009150 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009151
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009152 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009153 long myTotalPss = mi.getTotalPss();
9154 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009155 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9156 myTotalPss);
9157 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009158
9159 nativePss += mi.nativePss;
9160 dalvikPss += mi.dalvikPss;
9161 otherPss += mi.otherPss;
9162 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9163 long mem = mi.getOtherPss(j);
9164 miscPss[j] += mem;
9165 otherPss -= mem;
9166 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009167
9168 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9169 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9170 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009171 if (oomProcs[oomIndex] == null) {
9172 oomProcs[oomIndex] = new ArrayList<MemItem>();
9173 }
9174 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009175 break;
9176 }
9177 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009179 }
9180 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009181
9182 if (!isCheckinRequest && procs.size() > 1) {
9183 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9184
9185 catMems.add(new MemItem("Native", nativePss));
9186 catMems.add(new MemItem("Dalvik", dalvikPss));
9187 catMems.add(new MemItem("Unknown", otherPss));
9188 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9189 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9190 }
9191
Dianne Hackbornb437e092011-08-05 17:50:29 -07009192 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9193 for (int j=0; j<oomPss.length; j++) {
9194 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009195 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9196 item.subitems = oomProcs[j];
9197 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009198 }
9199 }
9200
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009201 pw.println();
9202 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009203 dumpMemItems(pw, " ", procMems, true);
9204 pw.println();
9205 pw.println("Total PSS by OOM adjustment:");
9206 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009207 pw.println();
9208 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009209 dumpMemItems(pw, " ", catMems, true);
9210 pw.println();
9211 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009213 }
9214
9215 /**
9216 * Searches array of arguments for the specified string
9217 * @param args array of argument strings
9218 * @param value value to search for
9219 * @return true if the value is contained in the array
9220 */
9221 private static boolean scanArgs(String[] args, String value) {
9222 if (args != null) {
9223 for (String arg : args) {
9224 if (value.equals(arg)) {
9225 return true;
9226 }
9227 }
9228 }
9229 return false;
9230 }
9231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009232 private final void killServicesLocked(ProcessRecord app,
9233 boolean allowRestart) {
9234 // Report disconnected services.
9235 if (false) {
9236 // XXX we are letting the client link to the service for
9237 // death notifications.
9238 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009239 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009240 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009241 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009242 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009243 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 = r.connections.values().iterator();
9245 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009246 ArrayList<ConnectionRecord> cl = jt.next();
9247 for (int i=0; i<cl.size(); i++) {
9248 ConnectionRecord c = cl.get(i);
9249 if (c.binding.client != app) {
9250 try {
9251 //c.conn.connected(r.className, null);
9252 } catch (Exception e) {
9253 // todo: this should be asynchronous!
9254 Slog.w(TAG, "Exception thrown disconnected servce "
9255 + r.shortName
9256 + " from app " + app.processName, e);
9257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009258 }
9259 }
9260 }
9261 }
9262 }
9263 }
9264 }
9265
9266 // Clean up any connections this application has to other services.
9267 if (app.connections.size() > 0) {
9268 Iterator<ConnectionRecord> it = app.connections.iterator();
9269 while (it.hasNext()) {
9270 ConnectionRecord r = it.next();
9271 removeConnectionLocked(r, app, null);
9272 }
9273 }
9274 app.connections.clear();
9275
9276 if (app.services.size() != 0) {
9277 // Any services running in the application need to be placed
9278 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009279 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009281 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 synchronized (sr.stats.getBatteryStats()) {
9283 sr.stats.stopLaunchedLocked();
9284 }
9285 sr.app = null;
9286 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009287 if (mStoppingServices.remove(sr)) {
9288 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9289 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009290
9291 boolean hasClients = sr.bindings.size() > 0;
9292 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009293 Iterator<IntentBindRecord> bindings
9294 = sr.bindings.values().iterator();
9295 while (bindings.hasNext()) {
9296 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009297 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009298 + ": shouldUnbind=" + b.hasBound);
9299 b.binder = null;
9300 b.requested = b.received = b.hasBound = false;
9301 }
9302 }
9303
Dianne Hackborn070783f2010-12-29 16:46:28 -08009304 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9305 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009306 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009308 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309 sr.crashCount, sr.shortName, app.pid);
9310 bringDownServiceLocked(sr, true);
9311 } else if (!allowRestart) {
9312 bringDownServiceLocked(sr, true);
9313 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009314 boolean canceled = scheduleServiceRestartLocked(sr, true);
9315
9316 // Should the service remain running? Note that in the
9317 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009318 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009319 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9320 if (sr.pendingStarts.size() == 0) {
9321 sr.startRequested = false;
9322 if (!hasClients) {
9323 // Whoops, no reason to restart!
9324 bringDownServiceLocked(sr, true);
9325 }
9326 }
9327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009328 }
9329 }
9330
9331 if (!allowRestart) {
9332 app.services.clear();
9333 }
9334 }
9335
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009336 // Make sure we have no more records on the stopping list.
9337 int i = mStoppingServices.size();
9338 while (i > 0) {
9339 i--;
9340 ServiceRecord sr = mStoppingServices.get(i);
9341 if (sr.app == app) {
9342 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009343 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009344 }
9345 }
9346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 app.executingServices.clear();
9348 }
9349
9350 private final void removeDyingProviderLocked(ProcessRecord proc,
9351 ContentProviderRecord cpr) {
9352 synchronized (cpr) {
9353 cpr.launchingApp = null;
9354 cpr.notifyAll();
9355 }
9356
9357 mProvidersByClass.remove(cpr.info.name);
9358 String names[] = cpr.info.authority.split(";");
9359 for (int j = 0; j < names.length; j++) {
9360 mProvidersByName.remove(names[j]);
9361 }
9362
9363 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9364 while (cit.hasNext()) {
9365 ProcessRecord capp = cit.next();
9366 if (!capp.persistent && capp.thread != null
9367 && capp.pid != 0
9368 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009369 Slog.i(TAG, "Kill " + capp.processName
9370 + " (pid " + capp.pid + "): provider " + cpr.info.name
9371 + " in dying process " + proc.processName);
9372 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9373 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009374 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009375 }
9376 }
9377
9378 mLaunchingProviders.remove(cpr);
9379 }
9380
9381 /**
9382 * Main code for cleaning up a process when it has gone away. This is
9383 * called both as a result of the process dying, or directly when stopping
9384 * a process when running in single process mode.
9385 */
9386 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009387 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009389 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009390 }
9391
Dianne Hackborn36124872009-10-08 16:22:03 -07009392 mProcessesToGc.remove(app);
9393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 // Dismiss any open dialogs.
9395 if (app.crashDialog != null) {
9396 app.crashDialog.dismiss();
9397 app.crashDialog = null;
9398 }
9399 if (app.anrDialog != null) {
9400 app.anrDialog.dismiss();
9401 app.anrDialog = null;
9402 }
9403 if (app.waitDialog != null) {
9404 app.waitDialog.dismiss();
9405 app.waitDialog = null;
9406 }
9407
9408 app.crashing = false;
9409 app.notResponding = false;
9410
9411 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009412 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 app.thread = null;
9414 app.forcingToForeground = null;
9415 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009416 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009417 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009418 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009419
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009420 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421
9422 boolean restart = false;
9423
9424 int NL = mLaunchingProviders.size();
9425
9426 // Remove published content providers.
9427 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009428 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009430 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 cpr.provider = null;
9432 cpr.app = null;
9433
9434 // See if someone is waiting for this provider... in which
9435 // case we don't remove it, but just let it restart.
9436 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009437 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009438 for (; i<NL; i++) {
9439 if (mLaunchingProviders.get(i) == cpr) {
9440 restart = true;
9441 break;
9442 }
9443 }
9444 } else {
9445 i = NL;
9446 }
9447
9448 if (i >= NL) {
9449 removeDyingProviderLocked(app, cpr);
9450 NL = mLaunchingProviders.size();
9451 }
9452 }
9453 app.pubProviders.clear();
9454 }
9455
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009456 // Take care of any launching providers waiting for this process.
9457 if (checkAppInLaunchingProvidersLocked(app, false)) {
9458 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009461 // Unregister from connected content providers.
9462 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009463 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009464 while (it.hasNext()) {
9465 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9466 cpr.clients.remove(app);
9467 }
9468 app.conProviders.clear();
9469 }
9470
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009471 // At this point there may be remaining entries in mLaunchingProviders
9472 // where we were the only one waiting, so they are no longer of use.
9473 // Look for these and clean up if found.
9474 // XXX Commented out for now. Trying to figure out a way to reproduce
9475 // the actual situation to identify what is actually going on.
9476 if (false) {
9477 for (int i=0; i<NL; i++) {
9478 ContentProviderRecord cpr = (ContentProviderRecord)
9479 mLaunchingProviders.get(i);
9480 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9481 synchronized (cpr) {
9482 cpr.launchingApp = null;
9483 cpr.notifyAll();
9484 }
9485 }
9486 }
9487 }
9488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009489 skipCurrentReceiverLocked(app);
9490
9491 // Unregister any receivers.
9492 if (app.receivers.size() > 0) {
9493 Iterator<ReceiverList> it = app.receivers.iterator();
9494 while (it.hasNext()) {
9495 removeReceiverLocked(it.next());
9496 }
9497 app.receivers.clear();
9498 }
9499
Christopher Tate181fafa2009-05-14 11:12:14 -07009500 // If the app is undergoing backup, tell the backup manager about it
9501 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009502 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009503 try {
9504 IBackupManager bm = IBackupManager.Stub.asInterface(
9505 ServiceManager.getService(Context.BACKUP_SERVICE));
9506 bm.agentDisconnected(app.info.packageName);
9507 } catch (RemoteException e) {
9508 // can't happen; backup manager is local
9509 }
9510 }
9511
Jeff Sharkey287bd832011-05-28 19:36:26 -07009512 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009514 // If the caller is restarting this app, then leave it in its
9515 // current lists and let the caller take care of it.
9516 if (restarting) {
9517 return;
9518 }
9519
9520 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009521 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522 "Removing non-persistent process during cleanup: " + app);
9523 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009524 if (mHeavyWeightProcess == app) {
9525 mHeavyWeightProcess = null;
9526 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009528 } else if (!app.removed) {
9529 // This app is persistent, so we need to keep its record around.
9530 // If it is not already on the pending app list, add it there
9531 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009532 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9533 mPersistentStartingProcesses.add(app);
9534 restart = true;
9535 }
9536 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009537 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9538 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009539 mProcessesOnHold.remove(app);
9540
The Android Open Source Project4df24232009-03-05 14:34:35 -08009541 if (app == mHomeProcess) {
9542 mHomeProcess = null;
9543 }
9544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009545 if (restart) {
9546 // We have components that still need to be running in the
9547 // process, so re-launch it.
9548 mProcessNames.put(app.processName, app.info.uid, app);
9549 startProcessLocked(app, "restart", app.processName);
9550 } else if (app.pid > 0 && app.pid != MY_PID) {
9551 // Goodbye!
9552 synchronized (mPidsSelfLocked) {
9553 mPidsSelfLocked.remove(app.pid);
9554 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9555 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009556 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009557 }
9558 }
9559
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009560 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9561 // Look through the content providers we are waiting to have launched,
9562 // and if any run in this process then either schedule a restart of
9563 // the process or kill the client waiting for it if this process has
9564 // gone bad.
9565 int NL = mLaunchingProviders.size();
9566 boolean restart = false;
9567 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009568 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009569 if (cpr.launchingApp == app) {
9570 if (!alwaysBad && !app.bad) {
9571 restart = true;
9572 } else {
9573 removeDyingProviderLocked(app, cpr);
9574 NL = mLaunchingProviders.size();
9575 }
9576 }
9577 }
9578 return restart;
9579 }
9580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009581 // =========================================================
9582 // SERVICES
9583 // =========================================================
9584
9585 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9586 ActivityManager.RunningServiceInfo info =
9587 new ActivityManager.RunningServiceInfo();
9588 info.service = r.name;
9589 if (r.app != null) {
9590 info.pid = r.app.pid;
9591 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009592 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009593 info.process = r.processName;
9594 info.foreground = r.isForeground;
9595 info.activeSince = r.createTime;
9596 info.started = r.startRequested;
9597 info.clientCount = r.connections.size();
9598 info.crashCount = r.crashCount;
9599 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009600 if (r.isForeground) {
9601 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9602 }
9603 if (r.startRequested) {
9604 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9605 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009606 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009607 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9608 }
9609 if (r.app != null && r.app.persistent) {
9610 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9611 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009612
9613 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9614 for (int i=0; i<connl.size(); i++) {
9615 ConnectionRecord conn = connl.get(i);
9616 if (conn.clientLabel != 0) {
9617 info.clientPackage = conn.binding.client.info.packageName;
9618 info.clientLabel = conn.clientLabel;
9619 return info;
9620 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009621 }
9622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009623 return info;
9624 }
9625
9626 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9627 int flags) {
9628 synchronized (this) {
9629 ArrayList<ActivityManager.RunningServiceInfo> res
9630 = new ArrayList<ActivityManager.RunningServiceInfo>();
9631
9632 if (mServices.size() > 0) {
9633 Iterator<ServiceRecord> it = mServices.values().iterator();
9634 while (it.hasNext() && res.size() < maxNum) {
9635 res.add(makeRunningServiceInfoLocked(it.next()));
9636 }
9637 }
9638
9639 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9640 ServiceRecord r = mRestartingServices.get(i);
9641 ActivityManager.RunningServiceInfo info =
9642 makeRunningServiceInfoLocked(r);
9643 info.restarting = r.nextRestartTime;
9644 res.add(info);
9645 }
9646
9647 return res;
9648 }
9649 }
9650
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009651 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9652 synchronized (this) {
9653 ServiceRecord r = mServices.get(name);
9654 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009655 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9656 for (int i=0; i<conn.size(); i++) {
9657 if (conn.get(i).clientIntent != null) {
9658 return conn.get(i).clientIntent;
9659 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009660 }
9661 }
9662 }
9663 }
9664 return null;
9665 }
9666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 private final ServiceRecord findServiceLocked(ComponentName name,
9668 IBinder token) {
9669 ServiceRecord r = mServices.get(name);
9670 return r == token ? r : null;
9671 }
9672
9673 private final class ServiceLookupResult {
9674 final ServiceRecord record;
9675 final String permission;
9676
9677 ServiceLookupResult(ServiceRecord _record, String _permission) {
9678 record = _record;
9679 permission = _permission;
9680 }
9681 };
9682
9683 private ServiceLookupResult findServiceLocked(Intent service,
9684 String resolvedType) {
9685 ServiceRecord r = null;
9686 if (service.getComponent() != null) {
9687 r = mServices.get(service.getComponent());
9688 }
9689 if (r == null) {
9690 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9691 r = mServicesByIntent.get(filter);
9692 }
9693
9694 if (r == null) {
9695 try {
9696 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009697 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 service, resolvedType, 0);
9699 ServiceInfo sInfo =
9700 rInfo != null ? rInfo.serviceInfo : null;
9701 if (sInfo == null) {
9702 return null;
9703 }
9704
9705 ComponentName name = new ComponentName(
9706 sInfo.applicationInfo.packageName, sInfo.name);
9707 r = mServices.get(name);
9708 } catch (RemoteException ex) {
9709 // pm is in same process, this will never happen.
9710 }
9711 }
9712 if (r != null) {
9713 int callingPid = Binder.getCallingPid();
9714 int callingUid = Binder.getCallingUid();
9715 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009716 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009717 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009718 if (!r.exported) {
9719 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9720 + " from pid=" + callingPid
9721 + ", uid=" + callingUid
9722 + " that is not exported from uid " + r.appInfo.uid);
9723 return new ServiceLookupResult(null, "not exported from uid "
9724 + r.appInfo.uid);
9725 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009726 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009727 + " from pid=" + callingPid
9728 + ", uid=" + callingUid
9729 + " requires " + r.permission);
9730 return new ServiceLookupResult(null, r.permission);
9731 }
9732 return new ServiceLookupResult(r, null);
9733 }
9734 return null;
9735 }
9736
9737 private class ServiceRestarter implements Runnable {
9738 private ServiceRecord mService;
9739
9740 void setService(ServiceRecord service) {
9741 mService = service;
9742 }
9743
9744 public void run() {
9745 synchronized(ActivityManagerService.this) {
9746 performServiceRestartLocked(mService);
9747 }
9748 }
9749 }
9750
9751 private ServiceLookupResult retrieveServiceLocked(Intent service,
9752 String resolvedType, int callingPid, int callingUid) {
9753 ServiceRecord r = null;
9754 if (service.getComponent() != null) {
9755 r = mServices.get(service.getComponent());
9756 }
9757 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9758 r = mServicesByIntent.get(filter);
9759 if (r == null) {
9760 try {
9761 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009762 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009763 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764 ServiceInfo sInfo =
9765 rInfo != null ? rInfo.serviceInfo : null;
9766 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009767 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009768 ": not found");
9769 return null;
9770 }
9771
9772 ComponentName name = new ComponentName(
9773 sInfo.applicationInfo.packageName, sInfo.name);
9774 r = mServices.get(name);
9775 if (r == null) {
9776 filter = new Intent.FilterComparison(service.cloneFilter());
9777 ServiceRestarter res = new ServiceRestarter();
9778 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9779 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9780 synchronized (stats) {
9781 ss = stats.getServiceStatsLocked(
9782 sInfo.applicationInfo.uid, sInfo.packageName,
9783 sInfo.name);
9784 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009785 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009786 res.setService(r);
9787 mServices.put(name, r);
9788 mServicesByIntent.put(filter, r);
9789
9790 // Make sure this component isn't in the pending list.
9791 int N = mPendingServices.size();
9792 for (int i=0; i<N; i++) {
9793 ServiceRecord pr = mPendingServices.get(i);
9794 if (pr.name.equals(name)) {
9795 mPendingServices.remove(i);
9796 i--;
9797 N--;
9798 }
9799 }
9800 }
9801 } catch (RemoteException ex) {
9802 // pm is in same process, this will never happen.
9803 }
9804 }
9805 if (r != null) {
9806 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009807 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009808 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009809 if (!r.exported) {
9810 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9811 + " from pid=" + callingPid
9812 + ", uid=" + callingUid
9813 + " that is not exported from uid " + r.appInfo.uid);
9814 return new ServiceLookupResult(null, "not exported from uid "
9815 + r.appInfo.uid);
9816 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009817 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009818 + " from pid=" + callingPid
9819 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009820 + " requires " + r.permission);
9821 return new ServiceLookupResult(null, r.permission);
9822 }
9823 return new ServiceLookupResult(r, null);
9824 }
9825 return null;
9826 }
9827
Dianne Hackborn287952c2010-09-22 22:34:31 -07009828 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9829 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9830 + why + " of " + r + " in app " + r.app);
9831 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9832 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009833 long now = SystemClock.uptimeMillis();
9834 if (r.executeNesting == 0 && r.app != null) {
9835 if (r.app.executingServices.size() == 0) {
9836 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9837 msg.obj = r.app;
9838 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9839 }
9840 r.app.executingServices.add(r);
9841 }
9842 r.executeNesting++;
9843 r.executingStart = now;
9844 }
9845
9846 private final void sendServiceArgsLocked(ServiceRecord r,
9847 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009848 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009849 if (N == 0) {
9850 return;
9851 }
9852
Dianne Hackborn39792d22010-08-19 18:01:52 -07009853 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009855 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009856 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9857 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009858 if (si.intent == null && N > 1) {
9859 // If somehow we got a dummy null intent in the middle,
9860 // then skip it. DO NOT skip a null intent when it is
9861 // the only one in the list -- this is to support the
9862 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009863 continue;
9864 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009865 si.deliveredTime = SystemClock.uptimeMillis();
9866 r.deliveredStarts.add(si);
9867 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009868 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009869 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009870 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009871 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009872 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009873 if (!oomAdjusted) {
9874 oomAdjusted = true;
9875 updateOomAdjLocked(r.app);
9876 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009877 int flags = 0;
9878 if (si.deliveryCount > 0) {
9879 flags |= Service.START_FLAG_RETRY;
9880 }
9881 if (si.doneExecutingCount > 0) {
9882 flags |= Service.START_FLAG_REDELIVERY;
9883 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009884 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009885 } catch (RemoteException e) {
9886 // Remote process gone... we'll let the normal cleanup take
9887 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009888 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009889 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009890 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009891 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009892 break;
9893 }
9894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009895 }
9896
9897 private final boolean requestServiceBindingLocked(ServiceRecord r,
9898 IntentBindRecord i, boolean rebind) {
9899 if (r.app == null || r.app.thread == null) {
9900 // If service is not currently running, can't yet bind.
9901 return false;
9902 }
9903 if ((!i.requested || rebind) && i.apps.size() > 0) {
9904 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009905 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9907 if (!rebind) {
9908 i.requested = true;
9909 }
9910 i.hasBound = true;
9911 i.doRebind = false;
9912 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009913 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009914 return false;
9915 }
9916 }
9917 return true;
9918 }
9919
9920 private final void requestServiceBindingsLocked(ServiceRecord r) {
9921 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9922 while (bindings.hasNext()) {
9923 IntentBindRecord i = bindings.next();
9924 if (!requestServiceBindingLocked(r, i, false)) {
9925 break;
9926 }
9927 }
9928 }
9929
9930 private final void realStartServiceLocked(ServiceRecord r,
9931 ProcessRecord app) throws RemoteException {
9932 if (app.thread == null) {
9933 throw new RemoteException();
9934 }
9935
9936 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009937 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938
9939 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009940 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009941 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009942
9943 boolean created = false;
9944 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009945 mStringBuilder.setLength(0);
9946 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009947 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009949 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009950 synchronized (r.stats.getBatteryStats()) {
9951 r.stats.startLaunchedLocked();
9952 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009953 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009954 app.thread.scheduleCreateService(r, r.serviceInfo,
9955 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009956 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009957 created = true;
9958 } finally {
9959 if (!created) {
9960 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009961 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009962 }
9963 }
9964
9965 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009966
9967 // If the service is in the started state, and there are no
9968 // pending arguments, then fake up one so its onStartCommand() will
9969 // be called.
9970 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009971 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9972 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009973 }
9974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009975 sendServiceArgsLocked(r, true);
9976 }
9977
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009978 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9979 boolean allowCancel) {
9980 boolean canceled = false;
9981
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009982 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009983 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009984 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009985
Dianne Hackborn070783f2010-12-29 16:46:28 -08009986 if ((r.serviceInfo.applicationInfo.flags
9987 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9988 minDuration /= 4;
9989 }
9990
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009991 // Any delivered but not yet finished starts should be put back
9992 // on the pending list.
9993 final int N = r.deliveredStarts.size();
9994 if (N > 0) {
9995 for (int i=N-1; i>=0; i--) {
9996 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009997 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009998 if (si.intent == null) {
9999 // We'll generate this again if needed.
10000 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10001 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10002 r.pendingStarts.add(0, si);
10003 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10004 dur *= 2;
10005 if (minDuration < dur) minDuration = dur;
10006 if (resetTime < dur) resetTime = dur;
10007 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010008 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010009 + r.name);
10010 canceled = true;
10011 }
10012 }
10013 r.deliveredStarts.clear();
10014 }
10015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016 r.totalRestartCount++;
10017 if (r.restartDelay == 0) {
10018 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010019 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020 } else {
10021 // If it has been a "reasonably long time" since the service
10022 // was started, then reset our restart duration back to
10023 // the beginning, so we don't infinitely increase the duration
10024 // on a service that just occasionally gets killed (which is
10025 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010026 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010027 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010028 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010030 if ((r.serviceInfo.applicationInfo.flags
10031 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10032 // Services in peristent processes will restart much more
10033 // quickly, since they are pretty important. (Think SystemUI).
10034 r.restartDelay += minDuration/2;
10035 } else {
10036 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10037 if (r.restartDelay < minDuration) {
10038 r.restartDelay = minDuration;
10039 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010041 }
10042 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010043
10044 r.nextRestartTime = now + r.restartDelay;
10045
10046 // Make sure that we don't end up restarting a bunch of services
10047 // all at the same time.
10048 boolean repeat;
10049 do {
10050 repeat = false;
10051 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10052 ServiceRecord r2 = mRestartingServices.get(i);
10053 if (r2 != r && r.nextRestartTime
10054 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10055 && r.nextRestartTime
10056 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10057 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10058 r.restartDelay = r.nextRestartTime - now;
10059 repeat = true;
10060 break;
10061 }
10062 }
10063 } while (repeat);
10064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 if (!mRestartingServices.contains(r)) {
10066 mRestartingServices.add(r);
10067 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010068
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010069 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010071 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010072 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010074 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010075 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010076 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 r.shortName, r.restartDelay);
10078
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010079 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010080 }
10081
10082 final void performServiceRestartLocked(ServiceRecord r) {
10083 if (!mRestartingServices.contains(r)) {
10084 return;
10085 }
10086 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10087 }
10088
10089 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10090 if (r.restartDelay == 0) {
10091 return false;
10092 }
10093 r.resetRestartCounter();
10094 mRestartingServices.remove(r);
10095 mHandler.removeCallbacks(r.restarter);
10096 return true;
10097 }
10098
10099 private final boolean bringUpServiceLocked(ServiceRecord r,
10100 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010101 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010102 //r.dump(" ");
10103
Dianne Hackborn36124872009-10-08 16:22:03 -070010104 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 sendServiceArgsLocked(r, false);
10106 return true;
10107 }
10108
10109 if (!whileRestarting && r.restartDelay > 0) {
10110 // If waiting for a restart, then do nothing.
10111 return true;
10112 }
10113
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010114 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010115
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010116 // We are now bringing the service up, so no longer in the
10117 // restarting state.
10118 mRestartingServices.remove(r);
10119
Dianne Hackborne7f97212011-02-24 14:40:20 -080010120 // Service is now being launched, its package can't be stopped.
10121 try {
10122 AppGlobals.getPackageManager().setPackageStoppedState(
10123 r.packageName, false);
10124 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010125 } catch (IllegalArgumentException e) {
10126 Slog.w(TAG, "Failed trying to unstop package "
10127 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010128 }
10129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010130 final String appName = r.processName;
10131 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10132 if (app != null && app.thread != null) {
10133 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010134 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 realStartServiceLocked(r, app);
10136 return true;
10137 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010138 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010139 }
10140
10141 // If a dead object exception was thrown -- fall through to
10142 // restart the application.
10143 }
10144
Dianne Hackborn36124872009-10-08 16:22:03 -070010145 // Not running -- get it started, and enqueue this service record
10146 // to be executed when the app comes up.
10147 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10148 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010149 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010150 + r.appInfo.packageName + "/"
10151 + r.appInfo.uid + " for service "
10152 + r.intent.getIntent() + ": process is bad");
10153 bringDownServiceLocked(r, true);
10154 return false;
10155 }
10156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010157 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158 mPendingServices.add(r);
10159 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010161 return true;
10162 }
10163
10164 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010165 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010166 //r.dump(" ");
10167
10168 // Does it still need to run?
10169 if (!force && r.startRequested) {
10170 return;
10171 }
10172 if (r.connections.size() > 0) {
10173 if (!force) {
10174 // XXX should probably keep a count of the number of auto-create
10175 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010176 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010178 ArrayList<ConnectionRecord> cr = it.next();
10179 for (int i=0; i<cr.size(); i++) {
10180 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10181 return;
10182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010183 }
10184 }
10185 }
10186
10187 // Report to all of the connections that the service is no longer
10188 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010189 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010190 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010191 ArrayList<ConnectionRecord> c = it.next();
10192 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010193 ConnectionRecord cr = c.get(i);
10194 // There is still a connection to the service that is
10195 // being brought down. Mark it as dead.
10196 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010197 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010198 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010199 } catch (Exception e) {
10200 Slog.w(TAG, "Failure disconnecting service " + r.name +
10201 " to connection " + c.get(i).conn.asBinder() +
10202 " (in " + c.get(i).binding.client.processName + ")", e);
10203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010204 }
10205 }
10206 }
10207
10208 // Tell the service that it has been unbound.
10209 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10210 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10211 while (it.hasNext()) {
10212 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010213 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010214 + ": hasBound=" + ibr.hasBound);
10215 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10216 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010217 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010218 updateOomAdjLocked(r.app);
10219 ibr.hasBound = false;
10220 r.app.thread.scheduleUnbindService(r,
10221 ibr.intent.getIntent());
10222 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010223 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010224 + r.shortName, e);
10225 serviceDoneExecutingLocked(r, true);
10226 }
10227 }
10228 }
10229 }
10230
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010231 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010232 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010233 System.identityHashCode(r), r.shortName,
10234 (r.app != null) ? r.app.pid : -1);
10235
10236 mServices.remove(r.name);
10237 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010238 r.totalRestartCount = 0;
10239 unscheduleServiceRestartLocked(r);
10240
10241 // Also make sure it is not on the pending list.
10242 int N = mPendingServices.size();
10243 for (int i=0; i<N; i++) {
10244 if (mPendingServices.get(i) == r) {
10245 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010246 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 i--;
10248 N--;
10249 }
10250 }
10251
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010252 r.cancelNotification();
10253 r.isForeground = false;
10254 r.foregroundId = 0;
10255 r.foregroundNoti = null;
10256
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010257 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010258 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010259 r.pendingStarts.clear();
10260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 if (r.app != null) {
10262 synchronized (r.stats.getBatteryStats()) {
10263 r.stats.stopLaunchedLocked();
10264 }
10265 r.app.services.remove(r);
10266 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010267 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010268 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010269 mStoppingServices.add(r);
10270 updateOomAdjLocked(r.app);
10271 r.app.thread.scheduleStopService(r);
10272 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010273 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 + r.shortName, e);
10275 serviceDoneExecutingLocked(r, true);
10276 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010277 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010278 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010279 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010280 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010281 }
10282 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010283 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010284 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010286
10287 if (r.bindings.size() > 0) {
10288 r.bindings.clear();
10289 }
10290
10291 if (r.restarter instanceof ServiceRestarter) {
10292 ((ServiceRestarter)r.restarter).setService(null);
10293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 }
10295
10296 ComponentName startServiceLocked(IApplicationThread caller,
10297 Intent service, String resolvedType,
10298 int callingPid, int callingUid) {
10299 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010300 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301 + " type=" + resolvedType + " args=" + service.getExtras());
10302
10303 if (caller != null) {
10304 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10305 if (callerApp == null) {
10306 throw new SecurityException(
10307 "Unable to find app for caller " + caller
10308 + " (pid=" + Binder.getCallingPid()
10309 + ") when starting service " + service);
10310 }
10311 }
10312
10313 ServiceLookupResult res =
10314 retrieveServiceLocked(service, resolvedType,
10315 callingPid, callingUid);
10316 if (res == null) {
10317 return null;
10318 }
10319 if (res.record == null) {
10320 return new ComponentName("!", res.permission != null
10321 ? res.permission : "private to package");
10322 }
10323 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010324 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10325 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010326 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010327 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 }
10329 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010330 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010331 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010332 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010333 r.lastActivity = SystemClock.uptimeMillis();
10334 synchronized (r.stats.getBatteryStats()) {
10335 r.stats.startRunningLocked();
10336 }
10337 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10338 return new ComponentName("!", "Service process is bad");
10339 }
10340 return r.name;
10341 }
10342 }
10343
10344 public ComponentName startService(IApplicationThread caller, Intent service,
10345 String resolvedType) {
10346 // Refuse possible leaked file descriptors
10347 if (service != null && service.hasFileDescriptors() == true) {
10348 throw new IllegalArgumentException("File descriptors passed in Intent");
10349 }
10350
10351 synchronized(this) {
10352 final int callingPid = Binder.getCallingPid();
10353 final int callingUid = Binder.getCallingUid();
10354 final long origId = Binder.clearCallingIdentity();
10355 ComponentName res = startServiceLocked(caller, service,
10356 resolvedType, callingPid, callingUid);
10357 Binder.restoreCallingIdentity(origId);
10358 return res;
10359 }
10360 }
10361
10362 ComponentName startServiceInPackage(int uid,
10363 Intent service, String resolvedType) {
10364 synchronized(this) {
10365 final long origId = Binder.clearCallingIdentity();
10366 ComponentName res = startServiceLocked(null, service,
10367 resolvedType, -1, uid);
10368 Binder.restoreCallingIdentity(origId);
10369 return res;
10370 }
10371 }
10372
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010373 private void stopServiceLocked(ServiceRecord service) {
10374 synchronized (service.stats.getBatteryStats()) {
10375 service.stats.stopRunningLocked();
10376 }
10377 service.startRequested = false;
10378 service.callStart = false;
10379 bringDownServiceLocked(service, false);
10380 }
10381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010382 public int stopService(IApplicationThread caller, Intent service,
10383 String resolvedType) {
10384 // Refuse possible leaked file descriptors
10385 if (service != null && service.hasFileDescriptors() == true) {
10386 throw new IllegalArgumentException("File descriptors passed in Intent");
10387 }
10388
10389 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010390 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010391 + " type=" + resolvedType);
10392
10393 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10394 if (caller != null && callerApp == null) {
10395 throw new SecurityException(
10396 "Unable to find app for caller " + caller
10397 + " (pid=" + Binder.getCallingPid()
10398 + ") when stopping service " + service);
10399 }
10400
10401 // If this service is active, make sure it is stopped.
10402 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10403 if (r != null) {
10404 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010405 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010406 try {
10407 stopServiceLocked(r.record);
10408 } finally {
10409 Binder.restoreCallingIdentity(origId);
10410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 return 1;
10412 }
10413 return -1;
10414 }
10415 }
10416
10417 return 0;
10418 }
10419
10420 public IBinder peekService(Intent service, String resolvedType) {
10421 // Refuse possible leaked file descriptors
10422 if (service != null && service.hasFileDescriptors() == true) {
10423 throw new IllegalArgumentException("File descriptors passed in Intent");
10424 }
10425
10426 IBinder ret = null;
10427
10428 synchronized(this) {
10429 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10430
10431 if (r != null) {
10432 // r.record is null if findServiceLocked() failed the caller permission check
10433 if (r.record == null) {
10434 throw new SecurityException(
10435 "Permission Denial: Accessing service " + r.record.name
10436 + " from pid=" + Binder.getCallingPid()
10437 + ", uid=" + Binder.getCallingUid()
10438 + " requires " + r.permission);
10439 }
10440 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10441 if (ib != null) {
10442 ret = ib.binder;
10443 }
10444 }
10445 }
10446
10447 return ret;
10448 }
10449
10450 public boolean stopServiceToken(ComponentName className, IBinder token,
10451 int startId) {
10452 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010453 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010454 + " " + token + " startId=" + startId);
10455 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010456 if (r != null) {
10457 if (startId >= 0) {
10458 // Asked to only stop if done with all work. Note that
10459 // to avoid leaks, we will take this as dropping all
10460 // start items up to and including this one.
10461 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10462 if (si != null) {
10463 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010464 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10465 cur.removeUriPermissionsLocked();
10466 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010467 break;
10468 }
10469 }
10470 }
10471
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010472 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010473 return false;
10474 }
10475
10476 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010477 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010478 + " is last, but have " + r.deliveredStarts.size()
10479 + " remaining args");
10480 }
10481 }
10482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010483 synchronized (r.stats.getBatteryStats()) {
10484 r.stats.stopRunningLocked();
10485 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010486 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010487 }
10488 final long origId = Binder.clearCallingIdentity();
10489 bringDownServiceLocked(r, false);
10490 Binder.restoreCallingIdentity(origId);
10491 return true;
10492 }
10493 }
10494 return false;
10495 }
10496
10497 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010498 int id, Notification notification, boolean removeNotification) {
10499 final long origId = Binder.clearCallingIdentity();
10500 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010501 synchronized(this) {
10502 ServiceRecord r = findServiceLocked(className, token);
10503 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010504 if (id != 0) {
10505 if (notification == null) {
10506 throw new IllegalArgumentException("null notification");
10507 }
10508 if (r.foregroundId != id) {
10509 r.cancelNotification();
10510 r.foregroundId = id;
10511 }
10512 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10513 r.foregroundNoti = notification;
10514 r.isForeground = true;
10515 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010516 if (r.app != null) {
10517 updateServiceForegroundLocked(r.app, true);
10518 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010519 } else {
10520 if (r.isForeground) {
10521 r.isForeground = false;
10522 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010523 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010524 updateServiceForegroundLocked(r.app, true);
10525 }
10526 }
10527 if (removeNotification) {
10528 r.cancelNotification();
10529 r.foregroundId = 0;
10530 r.foregroundNoti = null;
10531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010532 }
10533 }
10534 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010535 } finally {
10536 Binder.restoreCallingIdentity(origId);
10537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010538 }
10539
10540 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10541 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010542 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010543 if (sr.isForeground) {
10544 anyForeground = true;
10545 break;
10546 }
10547 }
10548 if (anyForeground != proc.foregroundServices) {
10549 proc.foregroundServices = anyForeground;
10550 if (oomAdj) {
10551 updateOomAdjLocked();
10552 }
10553 }
10554 }
10555
10556 public int bindService(IApplicationThread caller, IBinder token,
10557 Intent service, String resolvedType,
10558 IServiceConnection connection, int flags) {
10559 // Refuse possible leaked file descriptors
10560 if (service != null && service.hasFileDescriptors() == true) {
10561 throw new IllegalArgumentException("File descriptors passed in Intent");
10562 }
10563
10564 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010565 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 + " type=" + resolvedType + " conn=" + connection.asBinder()
10567 + " flags=0x" + Integer.toHexString(flags));
10568 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10569 if (callerApp == null) {
10570 throw new SecurityException(
10571 "Unable to find app for caller " + caller
10572 + " (pid=" + Binder.getCallingPid()
10573 + ") when binding service " + service);
10574 }
10575
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010576 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010578 activity = mMainStack.isInStackLocked(token);
10579 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010580 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010581 return 0;
10582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010583 }
10584
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010585 int clientLabel = 0;
10586 PendingIntent clientIntent = null;
10587
10588 if (callerApp.info.uid == Process.SYSTEM_UID) {
10589 // Hacky kind of thing -- allow system stuff to tell us
10590 // what they are, so we can report this elsewhere for
10591 // others to know why certain services are running.
10592 try {
10593 clientIntent = (PendingIntent)service.getParcelableExtra(
10594 Intent.EXTRA_CLIENT_INTENT);
10595 } catch (RuntimeException e) {
10596 }
10597 if (clientIntent != null) {
10598 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10599 if (clientLabel != 0) {
10600 // There are no useful extras in the intent, trash them.
10601 // System code calling with this stuff just needs to know
10602 // this will happen.
10603 service = service.cloneFilter();
10604 }
10605 }
10606 }
10607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010608 ServiceLookupResult res =
10609 retrieveServiceLocked(service, resolvedType,
10610 Binder.getCallingPid(), Binder.getCallingUid());
10611 if (res == null) {
10612 return 0;
10613 }
10614 if (res.record == null) {
10615 return -1;
10616 }
10617 ServiceRecord s = res.record;
10618
10619 final long origId = Binder.clearCallingIdentity();
10620
10621 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010622 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010623 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010624 }
10625
10626 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10627 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010628 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010629
10630 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010631 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10632 if (clist == null) {
10633 clist = new ArrayList<ConnectionRecord>();
10634 s.connections.put(binder, clist);
10635 }
10636 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010637 b.connections.add(c);
10638 if (activity != null) {
10639 if (activity.connections == null) {
10640 activity.connections = new HashSet<ConnectionRecord>();
10641 }
10642 activity.connections.add(c);
10643 }
10644 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010645 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10646 b.client.hasAboveClient = true;
10647 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010648 clist = mServiceConnections.get(binder);
10649 if (clist == null) {
10650 clist = new ArrayList<ConnectionRecord>();
10651 mServiceConnections.put(binder, clist);
10652 }
10653 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010654
10655 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10656 s.lastActivity = SystemClock.uptimeMillis();
10657 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10658 return 0;
10659 }
10660 }
10661
10662 if (s.app != null) {
10663 // This could have made the service more important.
10664 updateOomAdjLocked(s.app);
10665 }
10666
Joe Onorato8a9b2202010-02-26 18:56:32 -080010667 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010668 + ": received=" + b.intent.received
10669 + " apps=" + b.intent.apps.size()
10670 + " doRebind=" + b.intent.doRebind);
10671
10672 if (s.app != null && b.intent.received) {
10673 // Service is already running, so we can immediately
10674 // publish the connection.
10675 try {
10676 c.conn.connected(s.name, b.intent.binder);
10677 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010678 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010679 + " to connection " + c.conn.asBinder()
10680 + " (in " + c.binding.client.processName + ")", e);
10681 }
10682
10683 // If this is the first app connected back to this binding,
10684 // and the service had previously asked to be told when
10685 // rebound, then do so.
10686 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10687 requestServiceBindingLocked(s, b.intent, true);
10688 }
10689 } else if (!b.intent.requested) {
10690 requestServiceBindingLocked(s, b.intent, false);
10691 }
10692
10693 Binder.restoreCallingIdentity(origId);
10694 }
10695
10696 return 1;
10697 }
10698
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010699 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010700 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010701 IBinder binder = c.conn.asBinder();
10702 AppBindRecord b = c.binding;
10703 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010704 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10705 if (clist != null) {
10706 clist.remove(c);
10707 if (clist.size() == 0) {
10708 s.connections.remove(binder);
10709 }
10710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010711 b.connections.remove(c);
10712 if (c.activity != null && c.activity != skipAct) {
10713 if (c.activity.connections != null) {
10714 c.activity.connections.remove(c);
10715 }
10716 }
10717 if (b.client != skipApp) {
10718 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010719 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10720 b.client.updateHasAboveClientLocked();
10721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010722 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010723 clist = mServiceConnections.get(binder);
10724 if (clist != null) {
10725 clist.remove(c);
10726 if (clist.size() == 0) {
10727 mServiceConnections.remove(binder);
10728 }
10729 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010730
10731 if (b.connections.size() == 0) {
10732 b.intent.apps.remove(b.client);
10733 }
10734
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010735 if (!c.serviceDead) {
10736 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10737 + ": shouldUnbind=" + b.intent.hasBound);
10738 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10739 && b.intent.hasBound) {
10740 try {
10741 bumpServiceExecutingLocked(s, "unbind");
10742 updateOomAdjLocked(s.app);
10743 b.intent.hasBound = false;
10744 // Assume the client doesn't want to know about a rebind;
10745 // we will deal with that later if it asks for one.
10746 b.intent.doRebind = false;
10747 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10748 } catch (Exception e) {
10749 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10750 serviceDoneExecutingLocked(s, true);
10751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010752 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010753
10754 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10755 bringDownServiceLocked(s, false);
10756 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010757 }
10758 }
10759
10760 public boolean unbindService(IServiceConnection connection) {
10761 synchronized (this) {
10762 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010763 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010764 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10765 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010766 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 + connection.asBinder());
10768 return false;
10769 }
10770
10771 final long origId = Binder.clearCallingIdentity();
10772
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010773 while (clist.size() > 0) {
10774 ConnectionRecord r = clist.get(0);
10775 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010776
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010777 if (r.binding.service.app != null) {
10778 // This could have made the service less important.
10779 updateOomAdjLocked(r.binding.service.app);
10780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 }
10782
10783 Binder.restoreCallingIdentity(origId);
10784 }
10785
10786 return true;
10787 }
10788
10789 public void publishService(IBinder token, Intent intent, IBinder service) {
10790 // Refuse possible leaked file descriptors
10791 if (intent != null && intent.hasFileDescriptors() == true) {
10792 throw new IllegalArgumentException("File descriptors passed in Intent");
10793 }
10794
10795 synchronized(this) {
10796 if (!(token instanceof ServiceRecord)) {
10797 throw new IllegalArgumentException("Invalid service token");
10798 }
10799 ServiceRecord r = (ServiceRecord)token;
10800
10801 final long origId = Binder.clearCallingIdentity();
10802
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010803 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010804 + " " + intent + ": " + service);
10805 if (r != null) {
10806 Intent.FilterComparison filter
10807 = new Intent.FilterComparison(intent);
10808 IntentBindRecord b = r.bindings.get(filter);
10809 if (b != null && !b.received) {
10810 b.binder = service;
10811 b.requested = true;
10812 b.received = true;
10813 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010814 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010815 = r.connections.values().iterator();
10816 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010817 ArrayList<ConnectionRecord> clist = it.next();
10818 for (int i=0; i<clist.size(); i++) {
10819 ConnectionRecord c = clist.get(i);
10820 if (!filter.equals(c.binding.intent.intent)) {
10821 if (DEBUG_SERVICE) Slog.v(
10822 TAG, "Not publishing to: " + c);
10823 if (DEBUG_SERVICE) Slog.v(
10824 TAG, "Bound intent: " + c.binding.intent.intent);
10825 if (DEBUG_SERVICE) Slog.v(
10826 TAG, "Published intent: " + intent);
10827 continue;
10828 }
10829 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10830 try {
10831 c.conn.connected(r.name, service);
10832 } catch (Exception e) {
10833 Slog.w(TAG, "Failure sending service " + r.name +
10834 " to connection " + c.conn.asBinder() +
10835 " (in " + c.binding.client.processName + ")", e);
10836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010837 }
10838 }
10839 }
10840 }
10841
10842 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10843
10844 Binder.restoreCallingIdentity(origId);
10845 }
10846 }
10847 }
10848
10849 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10850 // Refuse possible leaked file descriptors
10851 if (intent != null && intent.hasFileDescriptors() == true) {
10852 throw new IllegalArgumentException("File descriptors passed in Intent");
10853 }
10854
10855 synchronized(this) {
10856 if (!(token instanceof ServiceRecord)) {
10857 throw new IllegalArgumentException("Invalid service token");
10858 }
10859 ServiceRecord r = (ServiceRecord)token;
10860
10861 final long origId = Binder.clearCallingIdentity();
10862
10863 if (r != null) {
10864 Intent.FilterComparison filter
10865 = new Intent.FilterComparison(intent);
10866 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010867 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010868 + " at " + b + ": apps="
10869 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010870
10871 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010872 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010873 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010874 // Applications have already bound since the last
10875 // unbind, so just rebind right here.
10876 requestServiceBindingLocked(r, b, true);
10877 } else {
10878 // Note to tell the service the next time there is
10879 // a new client.
10880 b.doRebind = true;
10881 }
10882 }
10883
Per Edelberg78f9fff2010-08-30 20:01:35 +020010884 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010885
10886 Binder.restoreCallingIdentity(origId);
10887 }
10888 }
10889 }
10890
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010891 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010892 synchronized(this) {
10893 if (!(token instanceof ServiceRecord)) {
10894 throw new IllegalArgumentException("Invalid service token");
10895 }
10896 ServiceRecord r = (ServiceRecord)token;
10897 boolean inStopping = mStoppingServices.contains(token);
10898 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010900 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010901 + " with incorrect token: given " + token
10902 + ", expected " + r);
10903 return;
10904 }
10905
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010906 if (type == 1) {
10907 // This is a call from a service start... take care of
10908 // book-keeping.
10909 r.callStart = true;
10910 switch (res) {
10911 case Service.START_STICKY_COMPATIBILITY:
10912 case Service.START_STICKY: {
10913 // We are done with the associated start arguments.
10914 r.findDeliveredStart(startId, true);
10915 // Don't stop if killed.
10916 r.stopIfKilled = false;
10917 break;
10918 }
10919 case Service.START_NOT_STICKY: {
10920 // We are done with the associated start arguments.
10921 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010922 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010923 // There is no more work, and this service
10924 // doesn't want to hang around if killed.
10925 r.stopIfKilled = true;
10926 }
10927 break;
10928 }
10929 case Service.START_REDELIVER_INTENT: {
10930 // We'll keep this item until they explicitly
10931 // call stop for it, but keep track of the fact
10932 // that it was delivered.
10933 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10934 if (si != null) {
10935 si.deliveryCount = 0;
10936 si.doneExecutingCount++;
10937 // Don't stop if killed.
10938 r.stopIfKilled = true;
10939 }
10940 break;
10941 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010942 case Service.START_TASK_REMOVED_COMPLETE: {
10943 // Special processing for onTaskRemoved(). Don't
10944 // impact normal onStartCommand() processing.
10945 r.findDeliveredStart(startId, true);
10946 break;
10947 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010948 default:
10949 throw new IllegalArgumentException(
10950 "Unknown service start result: " + res);
10951 }
10952 if (res == Service.START_STICKY_COMPATIBILITY) {
10953 r.callStart = false;
10954 }
10955 }
10956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010957 final long origId = Binder.clearCallingIdentity();
10958 serviceDoneExecutingLocked(r, inStopping);
10959 Binder.restoreCallingIdentity(origId);
10960 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010961 Slog.w(TAG, "Done executing unknown service from pid "
10962 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 }
10964 }
10965 }
10966
10967 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010968 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10969 + ": nesting=" + r.executeNesting
10970 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010971 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 r.executeNesting--;
10973 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010974 if (DEBUG_SERVICE) Slog.v(TAG,
10975 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 r.app.executingServices.remove(r);
10977 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010978 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10979 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010980 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10981 }
10982 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010983 if (DEBUG_SERVICE) Slog.v(TAG,
10984 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010985 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010986 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010987 }
10988 updateOomAdjLocked(r.app);
10989 }
10990 }
10991
10992 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010993 String anrMessage = null;
10994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995 synchronized(this) {
10996 if (proc.executingServices.size() == 0 || proc.thread == null) {
10997 return;
10998 }
10999 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11000 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11001 ServiceRecord timeout = null;
11002 long nextTime = 0;
11003 while (it.hasNext()) {
11004 ServiceRecord sr = it.next();
11005 if (sr.executingStart < maxTime) {
11006 timeout = sr;
11007 break;
11008 }
11009 if (sr.executingStart > nextTime) {
11010 nextTime = sr.executingStart;
11011 }
11012 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011013 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011014 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011015 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011016 } else {
11017 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11018 msg.obj = proc;
11019 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11020 }
11021 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011022
11023 if (anrMessage != null) {
11024 appNotResponding(proc, null, null, anrMessage);
11025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 }
11027
11028 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011029 // BACKUP AND RESTORE
11030 // =========================================================
11031
11032 // Cause the target app to be launched if necessary and its backup agent
11033 // instantiated. The backup agent will invoke backupAgentCreated() on the
11034 // activity manager to announce its creation.
11035 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011036 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011037 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11038
11039 synchronized(this) {
11040 // !!! TODO: currently no check here that we're already bound
11041 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11042 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11043 synchronized (stats) {
11044 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11045 }
11046
Dianne Hackborne7f97212011-02-24 14:40:20 -080011047 // Backup agent is now in use, its package can't be stopped.
11048 try {
11049 AppGlobals.getPackageManager().setPackageStoppedState(
11050 app.packageName, false);
11051 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011052 } catch (IllegalArgumentException e) {
11053 Slog.w(TAG, "Failed trying to unstop package "
11054 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011055 }
11056
Christopher Tate181fafa2009-05-14 11:12:14 -070011057 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011058 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11059 ? new ComponentName(app.packageName, app.backupAgentName)
11060 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011061 // startProcessLocked() returns existing proc's record if it's already running
11062 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011063 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011064 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011065 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011066 return false;
11067 }
11068
11069 r.app = proc;
11070 mBackupTarget = r;
11071 mBackupAppName = app.packageName;
11072
Christopher Tate6fa95972009-06-05 18:43:55 -070011073 // Try not to kill the process during backup
11074 updateOomAdjLocked(proc);
11075
Christopher Tate181fafa2009-05-14 11:12:14 -070011076 // If the process is already attached, schedule the creation of the backup agent now.
11077 // If it is not yet live, this will be done when it attaches to the framework.
11078 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011079 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011080 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011081 proc.thread.scheduleCreateBackupAgent(app,
11082 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011083 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011084 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011085 }
11086 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011087 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011088 }
11089 // Invariants: at this point, the target app process exists and the application
11090 // is either already running or in the process of coming up. mBackupTarget and
11091 // mBackupAppName describe the app, so that when it binds back to the AM we
11092 // know that it's scheduled for a backup-agent operation.
11093 }
11094
11095 return true;
11096 }
11097
11098 // A backup agent has just come up
11099 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011100 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011101 + " = " + agent);
11102
11103 synchronized(this) {
11104 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011105 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011106 return;
11107 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011108 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011109
Dianne Hackborn06740692010-09-22 22:46:21 -070011110 long oldIdent = Binder.clearCallingIdentity();
11111 try {
11112 IBackupManager bm = IBackupManager.Stub.asInterface(
11113 ServiceManager.getService(Context.BACKUP_SERVICE));
11114 bm.agentConnected(agentPackageName, agent);
11115 } catch (RemoteException e) {
11116 // can't happen; the backup manager service is local
11117 } catch (Exception e) {
11118 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11119 e.printStackTrace();
11120 } finally {
11121 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011122 }
11123 }
11124
11125 // done with this agent
11126 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011127 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011128 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011129 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011130 return;
11131 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011132
11133 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011134 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011135 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011136 return;
11137 }
11138
Christopher Tate181fafa2009-05-14 11:12:14 -070011139 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011140 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011141 return;
11142 }
11143
Christopher Tate6fa95972009-06-05 18:43:55 -070011144 ProcessRecord proc = mBackupTarget.app;
11145 mBackupTarget = null;
11146 mBackupAppName = null;
11147
11148 // Not backing this app up any more; reset its OOM adjustment
11149 updateOomAdjLocked(proc);
11150
Christopher Tatec7b31e32009-06-10 15:49:30 -070011151 // If the app crashed during backup, 'thread' will be null here
11152 if (proc.thread != null) {
11153 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011154 proc.thread.scheduleDestroyBackupAgent(appInfo,
11155 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011156 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011157 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011158 e.printStackTrace();
11159 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011160 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011161 }
11162 }
11163 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011164 // BROADCASTS
11165 // =========================================================
11166
Josh Bartel7f208742010-02-25 11:01:44 -060011167 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 List cur) {
11169 final ContentResolver resolver = mContext.getContentResolver();
11170 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11171 if (list == null) {
11172 return cur;
11173 }
11174 int N = list.size();
11175 for (int i=0; i<N; i++) {
11176 Intent intent = list.get(i);
11177 if (filter.match(resolver, intent, true, TAG) >= 0) {
11178 if (cur == null) {
11179 cur = new ArrayList<Intent>();
11180 }
11181 cur.add(intent);
11182 }
11183 }
11184 return cur;
11185 }
11186
11187 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011188 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011189 + mBroadcastsScheduled);
11190
11191 if (mBroadcastsScheduled) {
11192 return;
11193 }
11194 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11195 mBroadcastsScheduled = true;
11196 }
11197
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011198 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011199 IIntentReceiver receiver, IntentFilter filter, String permission) {
11200 synchronized(this) {
11201 ProcessRecord callerApp = null;
11202 if (caller != null) {
11203 callerApp = getRecordForAppLocked(caller);
11204 if (callerApp == null) {
11205 throw new SecurityException(
11206 "Unable to find app for caller " + caller
11207 + " (pid=" + Binder.getCallingPid()
11208 + ") when registering receiver " + receiver);
11209 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011210 if (callerApp.info.uid != Process.SYSTEM_UID &&
11211 !callerApp.pkgList.contains(callerPackage)) {
11212 throw new SecurityException("Given caller package " + callerPackage
11213 + " is not running in process " + callerApp);
11214 }
11215 } else {
11216 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011217 }
11218
11219 List allSticky = null;
11220
11221 // Look for any matching sticky broadcasts...
11222 Iterator actions = filter.actionsIterator();
11223 if (actions != null) {
11224 while (actions.hasNext()) {
11225 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011226 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011227 }
11228 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011229 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011230 }
11231
11232 // The first sticky in the list is returned directly back to
11233 // the client.
11234 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11235
Joe Onorato8a9b2202010-02-26 18:56:32 -080011236 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011237 + ": " + sticky);
11238
11239 if (receiver == null) {
11240 return sticky;
11241 }
11242
11243 ReceiverList rl
11244 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11245 if (rl == null) {
11246 rl = new ReceiverList(this, callerApp,
11247 Binder.getCallingPid(),
11248 Binder.getCallingUid(), receiver);
11249 if (rl.app != null) {
11250 rl.app.receivers.add(rl);
11251 } else {
11252 try {
11253 receiver.asBinder().linkToDeath(rl, 0);
11254 } catch (RemoteException e) {
11255 return sticky;
11256 }
11257 rl.linkedToDeath = true;
11258 }
11259 mRegisteredReceivers.put(receiver.asBinder(), rl);
11260 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011261 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011262 rl.add(bf);
11263 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011264 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011265 }
11266 mReceiverResolver.addFilter(bf);
11267
11268 // Enqueue broadcasts for all existing stickies that match
11269 // this filter.
11270 if (allSticky != null) {
11271 ArrayList receivers = new ArrayList();
11272 receivers.add(bf);
11273
11274 int N = allSticky.size();
11275 for (int i=0; i<N; i++) {
11276 Intent intent = (Intent)allSticky.get(i);
11277 BroadcastRecord r = new BroadcastRecord(intent, null,
11278 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011279 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011280 if (mParallelBroadcasts.size() == 0) {
11281 scheduleBroadcastsLocked();
11282 }
11283 mParallelBroadcasts.add(r);
11284 }
11285 }
11286
11287 return sticky;
11288 }
11289 }
11290
11291 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011292 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011293
11294 boolean doNext = false;
11295
11296 synchronized(this) {
11297 ReceiverList rl
11298 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11299 if (rl != null) {
11300 if (rl.curBroadcast != null) {
11301 BroadcastRecord r = rl.curBroadcast;
11302 doNext = finishReceiverLocked(
11303 receiver.asBinder(), r.resultCode, r.resultData,
11304 r.resultExtras, r.resultAbort, true);
11305 }
11306
11307 if (rl.app != null) {
11308 rl.app.receivers.remove(rl);
11309 }
11310 removeReceiverLocked(rl);
11311 if (rl.linkedToDeath) {
11312 rl.linkedToDeath = false;
11313 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11314 }
11315 }
11316 }
11317
11318 if (!doNext) {
11319 return;
11320 }
11321
11322 final long origId = Binder.clearCallingIdentity();
11323 processNextBroadcast(false);
11324 trimApplications();
11325 Binder.restoreCallingIdentity(origId);
11326 }
11327
11328 void removeReceiverLocked(ReceiverList rl) {
11329 mRegisteredReceivers.remove(rl.receiver.asBinder());
11330 int N = rl.size();
11331 for (int i=0; i<N; i++) {
11332 mReceiverResolver.removeFilter(rl.get(i));
11333 }
11334 }
11335
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011336 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11337 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11338 ProcessRecord r = mLruProcesses.get(i);
11339 if (r.thread != null) {
11340 try {
11341 r.thread.dispatchPackageBroadcast(cmd, packages);
11342 } catch (RemoteException ex) {
11343 }
11344 }
11345 }
11346 }
11347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011348 private final int broadcastIntentLocked(ProcessRecord callerApp,
11349 String callerPackage, Intent intent, String resolvedType,
11350 IIntentReceiver resultTo, int resultCode, String resultData,
11351 Bundle map, String requiredPermission,
11352 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11353 intent = new Intent(intent);
11354
Dianne Hackborne7f97212011-02-24 14:40:20 -080011355 // By default broadcasts do not go to stopped apps.
11356 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11357
Joe Onorato8a9b2202010-02-26 18:56:32 -080011358 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011359 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11360 + " ordered=" + ordered);
11361 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011362 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011363 }
11364
11365 // Handle special intents: if this broadcast is from the package
11366 // manager about a package being removed, we need to remove all of
11367 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011368 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011369 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011370 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11371 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011372 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011373 || uidRemoved) {
11374 if (checkComponentPermission(
11375 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011376 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011377 == PackageManager.PERMISSION_GRANTED) {
11378 if (uidRemoved) {
11379 final Bundle intentExtras = intent.getExtras();
11380 final int uid = intentExtras != null
11381 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11382 if (uid >= 0) {
11383 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11384 synchronized (bs) {
11385 bs.removeUidStatsLocked(uid);
11386 }
11387 }
11388 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011389 // If resources are unvailble just force stop all
11390 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011391 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011392 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11393 if (list != null && (list.length > 0)) {
11394 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011395 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011396 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011397 sendPackageBroadcastLocked(
11398 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011399 }
11400 } else {
11401 Uri data = intent.getData();
11402 String ssp;
11403 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11404 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11405 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011406 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011407 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011408 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011409 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11410 new String[] {ssp});
11411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412 }
11413 }
11414 }
11415 } else {
11416 String msg = "Permission Denial: " + intent.getAction()
11417 + " broadcast from " + callerPackage + " (pid=" + callingPid
11418 + ", uid=" + callingUid + ")"
11419 + " requires "
11420 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011421 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011422 throw new SecurityException(msg);
11423 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011424
11425 // Special case for adding a package: by default turn on compatibility
11426 // mode.
11427 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011428 Uri data = intent.getData();
11429 String ssp;
11430 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11431 mCompatModePackages.handlePackageAddedLocked(ssp,
11432 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011434 }
11435
11436 /*
11437 * If this is the time zone changed action, queue up a message that will reset the timezone
11438 * of all currently running processes. This message will get queued up before the broadcast
11439 * happens.
11440 */
11441 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11442 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11443 }
11444
Robert Greenwalt03595d02010-11-02 14:08:23 -070011445 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11446 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11447 }
11448
Robert Greenwalt434203a2010-10-11 16:00:27 -070011449 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11450 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11451 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11452 }
11453
Dianne Hackborn854060af2009-07-09 18:14:31 -070011454 /*
11455 * Prevent non-system code (defined here to be non-persistent
11456 * processes) from sending protected broadcasts.
11457 */
11458 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11459 || callingUid == Process.SHELL_UID || callingUid == 0) {
11460 // Always okay.
11461 } else if (callerApp == null || !callerApp.persistent) {
11462 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011463 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011464 intent.getAction())) {
11465 String msg = "Permission Denial: not allowed to send broadcast "
11466 + intent.getAction() + " from pid="
11467 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011468 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011469 throw new SecurityException(msg);
11470 }
11471 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011472 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011473 return BROADCAST_SUCCESS;
11474 }
11475 }
11476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011477 // Add to the sticky list if requested.
11478 if (sticky) {
11479 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11480 callingPid, callingUid)
11481 != PackageManager.PERMISSION_GRANTED) {
11482 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11483 + callingPid + ", uid=" + callingUid
11484 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011485 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011486 throw new SecurityException(msg);
11487 }
11488 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011489 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011490 + " and enforce permission " + requiredPermission);
11491 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11492 }
11493 if (intent.getComponent() != null) {
11494 throw new SecurityException(
11495 "Sticky broadcasts can't target a specific component");
11496 }
11497 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11498 if (list == null) {
11499 list = new ArrayList<Intent>();
11500 mStickyBroadcasts.put(intent.getAction(), list);
11501 }
11502 int N = list.size();
11503 int i;
11504 for (i=0; i<N; i++) {
11505 if (intent.filterEquals(list.get(i))) {
11506 // This sticky already exists, replace it.
11507 list.set(i, new Intent(intent));
11508 break;
11509 }
11510 }
11511 if (i >= N) {
11512 list.add(new Intent(intent));
11513 }
11514 }
11515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011516 // Figure out who all will receive this broadcast.
11517 List receivers = null;
11518 List<BroadcastFilter> registeredReceivers = null;
11519 try {
11520 if (intent.getComponent() != null) {
11521 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011522 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011523 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524 if (ai != null) {
11525 receivers = new ArrayList();
11526 ResolveInfo ri = new ResolveInfo();
11527 ri.activityInfo = ai;
11528 receivers.add(ri);
11529 }
11530 } else {
11531 // Need to resolve the intent to interested receivers...
11532 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11533 == 0) {
11534 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011535 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011536 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011537 }
Mihai Preda074edef2009-05-18 17:13:31 +020011538 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011539 }
11540 } catch (RemoteException ex) {
11541 // pm is in same process, this will never happen.
11542 }
11543
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011544 final boolean replacePending =
11545 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11546
Joe Onorato8a9b2202010-02-26 18:56:32 -080011547 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011548 + " replacePending=" + replacePending);
11549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11551 if (!ordered && NR > 0) {
11552 // If we are not serializing this broadcast, then send the
11553 // registered receivers separately so they don't wait for the
11554 // components to be launched.
11555 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11556 callerPackage, callingPid, callingUid, requiredPermission,
11557 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011558 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011559 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 TAG, "Enqueueing parallel broadcast " + r
11561 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011562 boolean replaced = false;
11563 if (replacePending) {
11564 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11565 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011566 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011567 "***** DROPPING PARALLEL: " + intent);
11568 mParallelBroadcasts.set(i, r);
11569 replaced = true;
11570 break;
11571 }
11572 }
11573 }
11574 if (!replaced) {
11575 mParallelBroadcasts.add(r);
11576 scheduleBroadcastsLocked();
11577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011578 registeredReceivers = null;
11579 NR = 0;
11580 }
11581
11582 // Merge into one list.
11583 int ir = 0;
11584 if (receivers != null) {
11585 // A special case for PACKAGE_ADDED: do not allow the package
11586 // being added to see this broadcast. This prevents them from
11587 // using this as a back door to get run as soon as they are
11588 // installed. Maybe in the future we want to have a special install
11589 // broadcast or such for apps, but we'd like to deliberately make
11590 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011591 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011592 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11593 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11594 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011595 Uri data = intent.getData();
11596 if (data != null) {
11597 String pkgName = data.getSchemeSpecificPart();
11598 if (pkgName != null) {
11599 skipPackages = new String[] { pkgName };
11600 }
11601 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011602 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011603 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011604 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011605 if (skipPackages != null && (skipPackages.length > 0)) {
11606 for (String skipPackage : skipPackages) {
11607 if (skipPackage != null) {
11608 int NT = receivers.size();
11609 for (int it=0; it<NT; it++) {
11610 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11611 if (curt.activityInfo.packageName.equals(skipPackage)) {
11612 receivers.remove(it);
11613 it--;
11614 NT--;
11615 }
11616 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011617 }
11618 }
11619 }
11620
11621 int NT = receivers != null ? receivers.size() : 0;
11622 int it = 0;
11623 ResolveInfo curt = null;
11624 BroadcastFilter curr = null;
11625 while (it < NT && ir < NR) {
11626 if (curt == null) {
11627 curt = (ResolveInfo)receivers.get(it);
11628 }
11629 if (curr == null) {
11630 curr = registeredReceivers.get(ir);
11631 }
11632 if (curr.getPriority() >= curt.priority) {
11633 // Insert this broadcast record into the final list.
11634 receivers.add(it, curr);
11635 ir++;
11636 curr = null;
11637 it++;
11638 NT++;
11639 } else {
11640 // Skip to the next ResolveInfo in the final list.
11641 it++;
11642 curt = null;
11643 }
11644 }
11645 }
11646 while (ir < NR) {
11647 if (receivers == null) {
11648 receivers = new ArrayList();
11649 }
11650 receivers.add(registeredReceivers.get(ir));
11651 ir++;
11652 }
11653
11654 if ((receivers != null && receivers.size() > 0)
11655 || resultTo != null) {
11656 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11657 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011658 receivers, resultTo, resultCode, resultData, map, ordered,
11659 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011660 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 TAG, "Enqueueing ordered broadcast " + r
11662 + ": prev had " + mOrderedBroadcasts.size());
11663 if (DEBUG_BROADCAST) {
11664 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011665 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011666 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011667 boolean replaced = false;
11668 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011669 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011670 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011671 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011672 "***** DROPPING ORDERED: " + intent);
11673 mOrderedBroadcasts.set(i, r);
11674 replaced = true;
11675 break;
11676 }
11677 }
11678 }
11679 if (!replaced) {
11680 mOrderedBroadcasts.add(r);
11681 scheduleBroadcastsLocked();
11682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011683 }
11684
11685 return BROADCAST_SUCCESS;
11686 }
11687
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011688 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011689 // Refuse possible leaked file descriptors
11690 if (intent != null && intent.hasFileDescriptors() == true) {
11691 throw new IllegalArgumentException("File descriptors passed in Intent");
11692 }
11693
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011694 int flags = intent.getFlags();
11695
11696 if (!mProcessesReady) {
11697 // if the caller really truly claims to know what they're doing, go
11698 // ahead and allow the broadcast without launching any receivers
11699 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11700 intent = new Intent(intent);
11701 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11702 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11703 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11704 + " before boot completion");
11705 throw new IllegalStateException("Cannot broadcast before boot completed");
11706 }
11707 }
11708
11709 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11710 throw new IllegalArgumentException(
11711 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11712 }
11713
11714 return intent;
11715 }
11716
11717 public final int broadcastIntent(IApplicationThread caller,
11718 Intent intent, String resolvedType, IIntentReceiver resultTo,
11719 int resultCode, String resultData, Bundle map,
11720 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011722 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011724 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11725 final int callingPid = Binder.getCallingPid();
11726 final int callingUid = Binder.getCallingUid();
11727 final long origId = Binder.clearCallingIdentity();
11728 int res = broadcastIntentLocked(callerApp,
11729 callerApp != null ? callerApp.info.packageName : null,
11730 intent, resolvedType, resultTo,
11731 resultCode, resultData, map, requiredPermission, serialized,
11732 sticky, callingPid, callingUid);
11733 Binder.restoreCallingIdentity(origId);
11734 return res;
11735 }
11736 }
11737
11738 int broadcastIntentInPackage(String packageName, int uid,
11739 Intent intent, String resolvedType, IIntentReceiver resultTo,
11740 int resultCode, String resultData, Bundle map,
11741 String requiredPermission, boolean serialized, boolean sticky) {
11742 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011743 intent = verifyBroadcastLocked(intent);
11744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011745 final long origId = Binder.clearCallingIdentity();
11746 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11747 resultTo, resultCode, resultData, map, requiredPermission,
11748 serialized, sticky, -1, uid);
11749 Binder.restoreCallingIdentity(origId);
11750 return res;
11751 }
11752 }
11753
11754 public final void unbroadcastIntent(IApplicationThread caller,
11755 Intent intent) {
11756 // Refuse possible leaked file descriptors
11757 if (intent != null && intent.hasFileDescriptors() == true) {
11758 throw new IllegalArgumentException("File descriptors passed in Intent");
11759 }
11760
11761 synchronized(this) {
11762 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11763 != PackageManager.PERMISSION_GRANTED) {
11764 String msg = "Permission Denial: unbroadcastIntent() from pid="
11765 + Binder.getCallingPid()
11766 + ", uid=" + Binder.getCallingUid()
11767 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011768 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011769 throw new SecurityException(msg);
11770 }
11771 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11772 if (list != null) {
11773 int N = list.size();
11774 int i;
11775 for (i=0; i<N; i++) {
11776 if (intent.filterEquals(list.get(i))) {
11777 list.remove(i);
11778 break;
11779 }
11780 }
11781 }
11782 }
11783 }
11784
11785 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11786 String resultData, Bundle resultExtras, boolean resultAbort,
11787 boolean explicit) {
11788 if (mOrderedBroadcasts.size() == 0) {
11789 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011790 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011791 }
11792 return false;
11793 }
11794 BroadcastRecord r = mOrderedBroadcasts.get(0);
11795 if (r.receiver == null) {
11796 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011797 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011798 }
11799 return false;
11800 }
11801 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011802 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011803 return false;
11804 }
11805 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011806 r.state = BroadcastRecord.IDLE;
11807 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011808 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011809 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011810 }
11811 }
11812 r.receiver = null;
11813 r.intent.setComponent(null);
11814 if (r.curApp != null) {
11815 r.curApp.curReceiver = null;
11816 }
11817 if (r.curFilter != null) {
11818 r.curFilter.receiverList.curBroadcast = null;
11819 }
11820 r.curFilter = null;
11821 r.curApp = null;
11822 r.curComponent = null;
11823 r.curReceiver = null;
11824 mPendingBroadcast = null;
11825
11826 r.resultCode = resultCode;
11827 r.resultData = resultData;
11828 r.resultExtras = resultExtras;
11829 r.resultAbort = resultAbort;
11830
11831 // We will process the next receiver right now if this is finishing
11832 // an app receiver (which is always asynchronous) or after we have
11833 // come back from calling a receiver.
11834 return state == BroadcastRecord.APP_RECEIVE
11835 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11836 }
11837
11838 public void finishReceiver(IBinder who, int resultCode, String resultData,
11839 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011840 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841
11842 // Refuse possible leaked file descriptors
11843 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11844 throw new IllegalArgumentException("File descriptors passed in Bundle");
11845 }
11846
11847 boolean doNext;
11848
11849 final long origId = Binder.clearCallingIdentity();
11850
11851 synchronized(this) {
11852 doNext = finishReceiverLocked(
11853 who, resultCode, resultData, resultExtras, resultAbort, true);
11854 }
11855
11856 if (doNext) {
11857 processNextBroadcast(false);
11858 }
11859 trimApplications();
11860
11861 Binder.restoreCallingIdentity(origId);
11862 }
11863
Jeff Brown4d94a762010-09-23 11:33:28 -070011864 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011865 if (r.nextReceiver > 0) {
11866 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11867 if (curReceiver instanceof BroadcastFilter) {
11868 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011869 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011870 System.identityHashCode(r),
11871 r.intent.getAction(),
11872 r.nextReceiver - 1,
11873 System.identityHashCode(bf));
11874 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011875 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011876 System.identityHashCode(r),
11877 r.intent.getAction(),
11878 r.nextReceiver - 1,
11879 ((ResolveInfo)curReceiver).toString());
11880 }
11881 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011882 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011884 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011885 System.identityHashCode(r),
11886 r.intent.getAction(),
11887 r.nextReceiver,
11888 "NONE");
11889 }
11890 }
11891
Jeff Brown4d94a762010-09-23 11:33:28 -070011892 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11893 if (! mPendingBroadcastTimeoutMessage) {
11894 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11895 mHandler.sendMessageAtTime(msg, timeoutTime);
11896 mPendingBroadcastTimeoutMessage = true;
11897 }
11898 }
11899
11900 private final void cancelBroadcastTimeoutLocked() {
11901 if (mPendingBroadcastTimeoutMessage) {
11902 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11903 mPendingBroadcastTimeoutMessage = false;
11904 }
11905 }
11906
11907 private final void broadcastTimeoutLocked(boolean fromMsg) {
11908 if (fromMsg) {
11909 mPendingBroadcastTimeoutMessage = false;
11910 }
11911
11912 if (mOrderedBroadcasts.size() == 0) {
11913 return;
11914 }
11915
11916 long now = SystemClock.uptimeMillis();
11917 BroadcastRecord r = mOrderedBroadcasts.get(0);
11918 if (fromMsg) {
11919 if (mDidDexOpt) {
11920 // Delay timeouts until dexopt finishes.
11921 mDidDexOpt = false;
11922 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11923 setBroadcastTimeoutLocked(timeoutTime);
11924 return;
11925 }
11926 if (! mProcessesReady) {
11927 // Only process broadcast timeouts if the system is ready. That way
11928 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11929 // to do heavy lifting for system up.
11930 return;
11931 }
11932
11933 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11934 if (timeoutTime > now) {
11935 // We can observe premature timeouts because we do not cancel and reset the
11936 // broadcast timeout message after each receiver finishes. Instead, we set up
11937 // an initial timeout then kick it down the road a little further as needed
11938 // when it expires.
11939 if (DEBUG_BROADCAST) Slog.v(TAG,
11940 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11941 + timeoutTime);
11942 setBroadcastTimeoutLocked(timeoutTime);
11943 return;
11944 }
11945 }
11946
11947 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11948 + ", started " + (now - r.receiverTime) + "ms ago");
11949 r.receiverTime = now;
11950 r.anrCount++;
11951
11952 // Current receiver has passed its expiration date.
11953 if (r.nextReceiver <= 0) {
11954 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11955 return;
11956 }
11957
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011958 ProcessRecord app = null;
11959 String anrMessage = null;
11960
Jeff Brown4d94a762010-09-23 11:33:28 -070011961 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11962 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11963 logBroadcastReceiverDiscardLocked(r);
11964 if (curReceiver instanceof BroadcastFilter) {
11965 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11966 if (bf.receiverList.pid != 0
11967 && bf.receiverList.pid != MY_PID) {
11968 synchronized (this.mPidsSelfLocked) {
11969 app = this.mPidsSelfLocked.get(
11970 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011972 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011973 } else {
11974 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011975 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011976
Jeff Brown4d94a762010-09-23 11:33:28 -070011977 if (app != null) {
11978 anrMessage = "Broadcast of " + r.intent.toString();
11979 }
11980
11981 if (mPendingBroadcast == r) {
11982 mPendingBroadcast = null;
11983 }
11984
11985 // Move on to the next receiver.
11986 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11987 r.resultExtras, r.resultAbort, true);
11988 scheduleBroadcastsLocked();
11989
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011990 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011991 // Post the ANR to the handler since we do not want to process ANRs while
11992 // potentially holding our lock.
11993 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 }
11996
11997 private final void processCurBroadcastLocked(BroadcastRecord r,
11998 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011999 if (DEBUG_BROADCAST) Slog.v(TAG,
12000 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012001 if (app.thread == null) {
12002 throw new RemoteException();
12003 }
12004 r.receiver = app.thread.asBinder();
12005 r.curApp = app;
12006 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012007 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008
12009 // Tell the application to launch this receiver.
12010 r.intent.setComponent(r.curComponent);
12011
12012 boolean started = false;
12013 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012014 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 "Delivering to component " + r.curComponent
12016 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012017 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012018 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012019 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012021 if (DEBUG_BROADCAST) Slog.v(TAG,
12022 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 started = true;
12024 } finally {
12025 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012026 if (DEBUG_BROADCAST) Slog.v(TAG,
12027 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 r.receiver = null;
12029 r.curApp = null;
12030 app.curReceiver = null;
12031 }
12032 }
12033
12034 }
12035
Jeff Brown4d94a762010-09-23 11:33:28 -070012036 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012037 Intent intent, int resultCode, String data, Bundle extras,
12038 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012039 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012040 if (app != null && app.thread != null) {
12041 // If we have an app thread, do the call through that so it is
12042 // correctly ordered with other one-way calls.
12043 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012044 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012045 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012046 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012047 }
12048 }
12049
Jeff Brown4d94a762010-09-23 11:33:28 -070012050 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012051 BroadcastFilter filter, boolean ordered) {
12052 boolean skip = false;
12053 if (filter.requiredPermission != null) {
12054 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012055 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012056 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012057 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 + r.intent.toString()
12059 + " from " + r.callerPackage + " (pid="
12060 + r.callingPid + ", uid=" + r.callingUid + ")"
12061 + " requires " + filter.requiredPermission
12062 + " due to registered receiver " + filter);
12063 skip = true;
12064 }
12065 }
12066 if (r.requiredPermission != null) {
12067 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012068 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012069 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012070 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 + r.intent.toString()
12072 + " to " + filter.receiverList.app
12073 + " (pid=" + filter.receiverList.pid
12074 + ", uid=" + filter.receiverList.uid + ")"
12075 + " requires " + r.requiredPermission
12076 + " due to sender " + r.callerPackage
12077 + " (uid " + r.callingUid + ")");
12078 skip = true;
12079 }
12080 }
12081
12082 if (!skip) {
12083 // If this is not being sent as an ordered broadcast, then we
12084 // don't want to touch the fields that keep track of the current
12085 // state of ordered broadcasts.
12086 if (ordered) {
12087 r.receiver = filter.receiverList.receiver.asBinder();
12088 r.curFilter = filter;
12089 filter.receiverList.curBroadcast = r;
12090 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012091 if (filter.receiverList.app != null) {
12092 // Bump hosting application to no longer be in background
12093 // scheduling class. Note that we can't do that if there
12094 // isn't an app... but we can only be in that case for
12095 // things that directly call the IActivityManager API, which
12096 // are already core system stuff so don't matter for this.
12097 r.curApp = filter.receiverList.app;
12098 filter.receiverList.app.curReceiver = r;
12099 updateOomAdjLocked();
12100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012101 }
12102 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012103 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012104 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012105 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012106 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012107 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012108 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012109 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012110 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012111 if (ordered) {
12112 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12113 }
12114 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012115 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 if (ordered) {
12117 r.receiver = null;
12118 r.curFilter = null;
12119 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012120 if (filter.receiverList.app != null) {
12121 filter.receiverList.app.curReceiver = null;
12122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012123 }
12124 }
12125 }
12126 }
12127
Dianne Hackborn12527f92009-11-11 17:39:50 -080012128 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12129 if (r.callingUid < 0) {
12130 // This was from a registerReceiver() call; ignore it.
12131 return;
12132 }
12133 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12134 MAX_BROADCAST_HISTORY-1);
12135 r.finishTime = SystemClock.uptimeMillis();
12136 mBroadcastHistory[0] = r;
12137 }
12138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 private final void processNextBroadcast(boolean fromMsg) {
12140 synchronized(this) {
12141 BroadcastRecord r;
12142
Joe Onorato8a9b2202010-02-26 18:56:32 -080012143 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012144 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012145 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146
12147 updateCpuStats();
12148
12149 if (fromMsg) {
12150 mBroadcastsScheduled = false;
12151 }
12152
12153 // First, deliver any non-serialized broadcasts right away.
12154 while (mParallelBroadcasts.size() > 0) {
12155 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012156 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012157 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012158 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012159 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012160 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012161 for (int i=0; i<N; i++) {
12162 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012163 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012164 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012166 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012167 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012168 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012169 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012170 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012171 }
12172
12173 // Now take care of the next serialized one...
12174
12175 // If we are waiting for a process to come up to handle the next
12176 // broadcast, then do nothing at this point. Just in case, we
12177 // check that the process we're waiting for still exists.
12178 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012179 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012180 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012181 + mPendingBroadcast.curApp);
12182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012183
12184 boolean isDead;
12185 synchronized (mPidsSelfLocked) {
12186 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12187 }
12188 if (!isDead) {
12189 // It's still alive, so keep waiting
12190 return;
12191 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012192 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012193 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012194 mPendingBroadcast.state = BroadcastRecord.IDLE;
12195 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 mPendingBroadcast = null;
12197 }
12198 }
12199
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012200 boolean looped = false;
12201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 do {
12203 if (mOrderedBroadcasts.size() == 0) {
12204 // No more broadcasts pending, so all done!
12205 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012206 if (looped) {
12207 // If we had finished the last ordered broadcast, then
12208 // make sure all processes have correct oom and sched
12209 // adjustments.
12210 updateOomAdjLocked();
12211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012212 return;
12213 }
12214 r = mOrderedBroadcasts.get(0);
12215 boolean forceReceive = false;
12216
12217 // Ensure that even if something goes awry with the timeout
12218 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012219 // and continue to make progress.
12220 //
12221 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012222 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012223 // one time heavy lifting after system upgrades and can take
12224 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012225 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012226 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012227 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012228 if ((numReceivers > 0) &&
12229 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012230 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012231 + " now=" + now
12232 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012233 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012234 + " intent=" + r.intent
12235 + " numReceivers=" + numReceivers
12236 + " nextReceiver=" + r.nextReceiver
12237 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012238 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012239 forceReceive = true;
12240 r.state = BroadcastRecord.IDLE;
12241 }
12242 }
12243
12244 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012245 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 "processNextBroadcast() called when not idle (state="
12247 + r.state + ")");
12248 return;
12249 }
12250
12251 if (r.receivers == null || r.nextReceiver >= numReceivers
12252 || r.resultAbort || forceReceive) {
12253 // No more receivers for this broadcast! Send the final
12254 // result if requested...
12255 if (r.resultTo != null) {
12256 try {
12257 if (DEBUG_BROADCAST) {
12258 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012259 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012260 + " seq=" + seq + " app=" + r.callerApp);
12261 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012262 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012263 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012264 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012265 // Set this to null so that the reference
12266 // (local and remote) isnt kept in the mBroadcastHistory.
12267 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012269 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012270 }
12271 }
12272
Joe Onorato8a9b2202010-02-26 18:56:32 -080012273 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012274 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275
Joe Onorato8a9b2202010-02-26 18:56:32 -080012276 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012277 + r);
12278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012279 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012280 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012281 mOrderedBroadcasts.remove(0);
12282 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012283 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 continue;
12285 }
12286 } while (r == null);
12287
12288 // Get the next receiver...
12289 int recIdx = r.nextReceiver++;
12290
12291 // Keep track of when this receiver started, and make sure there
12292 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012293 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012294 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012295 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012296 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012297 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012298 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012299 }
12300 if (! mPendingBroadcastTimeoutMessage) {
12301 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012302 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012303 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12304 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012305 }
12306
12307 Object nextReceiver = r.receivers.get(recIdx);
12308 if (nextReceiver instanceof BroadcastFilter) {
12309 // Simple case: this is a registered receiver who gets
12310 // a direct call.
12311 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012312 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012313 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012314 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012315 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012316 if (r.receiver == null || !r.ordered) {
12317 // The receiver has already finished, so schedule to
12318 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012319 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12320 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012321 r.state = BroadcastRecord.IDLE;
12322 scheduleBroadcastsLocked();
12323 }
12324 return;
12325 }
12326
12327 // Hard case: need to instantiate the receiver, possibly
12328 // starting its application process to host it.
12329
12330 ResolveInfo info =
12331 (ResolveInfo)nextReceiver;
12332
12333 boolean skip = false;
12334 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012335 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12336 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012337 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012338 if (!info.activityInfo.exported) {
12339 Slog.w(TAG, "Permission Denial: broadcasting "
12340 + r.intent.toString()
12341 + " from " + r.callerPackage + " (pid=" + r.callingPid
12342 + ", uid=" + r.callingUid + ")"
12343 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12344 + " due to receiver " + info.activityInfo.packageName
12345 + "/" + info.activityInfo.name);
12346 } else {
12347 Slog.w(TAG, "Permission Denial: broadcasting "
12348 + r.intent.toString()
12349 + " from " + r.callerPackage + " (pid=" + r.callingPid
12350 + ", uid=" + r.callingUid + ")"
12351 + " requires " + info.activityInfo.permission
12352 + " due to receiver " + info.activityInfo.packageName
12353 + "/" + info.activityInfo.name);
12354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 skip = true;
12356 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012357 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012358 r.requiredPermission != null) {
12359 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012360 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012361 checkPermission(r.requiredPermission,
12362 info.activityInfo.applicationInfo.packageName);
12363 } catch (RemoteException e) {
12364 perm = PackageManager.PERMISSION_DENIED;
12365 }
12366 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012367 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012368 + r.intent + " to "
12369 + info.activityInfo.applicationInfo.packageName
12370 + " requires " + r.requiredPermission
12371 + " due to sender " + r.callerPackage
12372 + " (uid " + r.callingUid + ")");
12373 skip = true;
12374 }
12375 }
12376 if (r.curApp != null && r.curApp.crashing) {
12377 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012378 if (DEBUG_BROADCAST) Slog.v(TAG,
12379 "Skipping deliver ordered " + r + " to " + r.curApp
12380 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012381 skip = true;
12382 }
12383
12384 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012385 if (DEBUG_BROADCAST) Slog.v(TAG,
12386 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012387 r.receiver = null;
12388 r.curFilter = null;
12389 r.state = BroadcastRecord.IDLE;
12390 scheduleBroadcastsLocked();
12391 return;
12392 }
12393
12394 r.state = BroadcastRecord.APP_RECEIVE;
12395 String targetProcess = info.activityInfo.processName;
12396 r.curComponent = new ComponentName(
12397 info.activityInfo.applicationInfo.packageName,
12398 info.activityInfo.name);
12399 r.curReceiver = info.activityInfo;
12400
Dianne Hackborne7f97212011-02-24 14:40:20 -080012401 // Broadcast is being executed, its package can't be stopped.
12402 try {
12403 AppGlobals.getPackageManager().setPackageStoppedState(
12404 r.curComponent.getPackageName(), false);
12405 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012406 } catch (IllegalArgumentException e) {
12407 Slog.w(TAG, "Failed trying to unstop package "
12408 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012409 }
12410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012411 // Is this receiver's application already running?
12412 ProcessRecord app = getProcessRecordLocked(targetProcess,
12413 info.activityInfo.applicationInfo.uid);
12414 if (app != null && app.thread != null) {
12415 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012416 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012417 processCurBroadcastLocked(r, app);
12418 return;
12419 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012420 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012421 + r.curComponent, e);
12422 }
12423
12424 // If a dead object exception was thrown -- fall through to
12425 // restart the application.
12426 }
12427
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012428 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012429 if (DEBUG_BROADCAST) Slog.v(TAG,
12430 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012431 if ((r.curApp=startProcessLocked(targetProcess,
12432 info.activityInfo.applicationInfo, true,
12433 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012434 "broadcast", r.curComponent,
12435 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12436 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012437 // Ah, this recipient is unavailable. Finish it if necessary,
12438 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012439 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 + info.activityInfo.applicationInfo.packageName + "/"
12441 + info.activityInfo.applicationInfo.uid + " for broadcast "
12442 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012443 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012444 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12445 r.resultExtras, r.resultAbort, true);
12446 scheduleBroadcastsLocked();
12447 r.state = BroadcastRecord.IDLE;
12448 return;
12449 }
12450
12451 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012452 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012453 }
12454 }
12455
12456 // =========================================================
12457 // INSTRUMENTATION
12458 // =========================================================
12459
12460 public boolean startInstrumentation(ComponentName className,
12461 String profileFile, int flags, Bundle arguments,
12462 IInstrumentationWatcher watcher) {
12463 // Refuse possible leaked file descriptors
12464 if (arguments != null && arguments.hasFileDescriptors()) {
12465 throw new IllegalArgumentException("File descriptors passed in Bundle");
12466 }
12467
12468 synchronized(this) {
12469 InstrumentationInfo ii = null;
12470 ApplicationInfo ai = null;
12471 try {
12472 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012473 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012474 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012475 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012476 } catch (PackageManager.NameNotFoundException e) {
12477 }
12478 if (ii == null) {
12479 reportStartInstrumentationFailure(watcher, className,
12480 "Unable to find instrumentation info for: " + className);
12481 return false;
12482 }
12483 if (ai == null) {
12484 reportStartInstrumentationFailure(watcher, className,
12485 "Unable to find instrumentation target package: " + ii.targetPackage);
12486 return false;
12487 }
12488
12489 int match = mContext.getPackageManager().checkSignatures(
12490 ii.targetPackage, ii.packageName);
12491 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12492 String msg = "Permission Denial: starting instrumentation "
12493 + className + " from pid="
12494 + Binder.getCallingPid()
12495 + ", uid=" + Binder.getCallingPid()
12496 + " not allowed because package " + ii.packageName
12497 + " does not have a signature matching the target "
12498 + ii.targetPackage;
12499 reportStartInstrumentationFailure(watcher, className, msg);
12500 throw new SecurityException(msg);
12501 }
12502
12503 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012504 // Instrumentation can kill and relaunch even persistent processes
12505 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012506 ProcessRecord app = addAppLocked(ai);
12507 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012508 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 app.instrumentationProfileFile = profileFile;
12510 app.instrumentationArguments = arguments;
12511 app.instrumentationWatcher = watcher;
12512 app.instrumentationResultClass = className;
12513 Binder.restoreCallingIdentity(origId);
12514 }
12515
12516 return true;
12517 }
12518
12519 /**
12520 * Report errors that occur while attempting to start Instrumentation. Always writes the
12521 * error to the logs, but if somebody is watching, send the report there too. This enables
12522 * the "am" command to report errors with more information.
12523 *
12524 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12525 * @param cn The component name of the instrumentation.
12526 * @param report The error report.
12527 */
12528 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12529 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012530 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012531 try {
12532 if (watcher != null) {
12533 Bundle results = new Bundle();
12534 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12535 results.putString("Error", report);
12536 watcher.instrumentationStatus(cn, -1, results);
12537 }
12538 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012539 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012540 }
12541 }
12542
12543 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12544 if (app.instrumentationWatcher != null) {
12545 try {
12546 // NOTE: IInstrumentationWatcher *must* be oneway here
12547 app.instrumentationWatcher.instrumentationFinished(
12548 app.instrumentationClass,
12549 resultCode,
12550 results);
12551 } catch (RemoteException e) {
12552 }
12553 }
12554 app.instrumentationWatcher = null;
12555 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012556 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012557 app.instrumentationProfileFile = null;
12558 app.instrumentationArguments = null;
12559
Christopher Tate3dacd842011-08-19 14:56:15 -070012560 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012561 }
12562
12563 public void finishInstrumentation(IApplicationThread target,
12564 int resultCode, Bundle results) {
12565 // Refuse possible leaked file descriptors
12566 if (results != null && results.hasFileDescriptors()) {
12567 throw new IllegalArgumentException("File descriptors passed in Intent");
12568 }
12569
12570 synchronized(this) {
12571 ProcessRecord app = getRecordForAppLocked(target);
12572 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012573 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574 return;
12575 }
12576 final long origId = Binder.clearCallingIdentity();
12577 finishInstrumentationLocked(app, resultCode, results);
12578 Binder.restoreCallingIdentity(origId);
12579 }
12580 }
12581
12582 // =========================================================
12583 // CONFIGURATION
12584 // =========================================================
12585
12586 public ConfigurationInfo getDeviceConfigurationInfo() {
12587 ConfigurationInfo config = new ConfigurationInfo();
12588 synchronized (this) {
12589 config.reqTouchScreen = mConfiguration.touchscreen;
12590 config.reqKeyboardType = mConfiguration.keyboard;
12591 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012592 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12593 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012594 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12595 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012596 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12597 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012598 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12599 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012600 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012601 }
12602 return config;
12603 }
12604
12605 public Configuration getConfiguration() {
12606 Configuration ci;
12607 synchronized(this) {
12608 ci = new Configuration(mConfiguration);
12609 }
12610 return ci;
12611 }
12612
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012613 public void updatePersistentConfiguration(Configuration values) {
12614 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12615 "updateConfiguration()");
12616 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12617 "updateConfiguration()");
12618 if (values == null) {
12619 throw new NullPointerException("Configuration must not be null");
12620 }
12621
12622 synchronized(this) {
12623 final long origId = Binder.clearCallingIdentity();
12624 updateConfigurationLocked(values, null, true);
12625 Binder.restoreCallingIdentity(origId);
12626 }
12627 }
12628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012629 public void updateConfiguration(Configuration values) {
12630 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12631 "updateConfiguration()");
12632
12633 synchronized(this) {
12634 if (values == null && mWindowManager != null) {
12635 // sentinel: fetch the current configuration from the window manager
12636 values = mWindowManager.computeNewConfiguration();
12637 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012638
12639 if (mWindowManager != null) {
12640 mProcessList.applyDisplaySize(mWindowManager);
12641 }
12642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012643 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012644 if (values != null) {
12645 Settings.System.clearConfiguration(values);
12646 }
12647 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012648 Binder.restoreCallingIdentity(origId);
12649 }
12650 }
12651
12652 /**
12653 * Do either or both things: (1) change the current configuration, and (2)
12654 * make sure the given activity is running with the (now) current
12655 * configuration. Returns true if the activity has been left running, or
12656 * false if <var>starting</var> is being destroyed to match the new
12657 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012658 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012659 */
12660 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012661 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012662 int changes = 0;
12663
12664 boolean kept = true;
12665
12666 if (values != null) {
12667 Configuration newConfig = new Configuration(mConfiguration);
12668 changes = newConfig.updateFrom(values);
12669 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012670 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012671 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012672 }
12673
Doug Zongker2bec3d42009-12-04 12:52:44 -080012674 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012675
12676 if (values.locale != null) {
12677 saveLocaleLocked(values.locale,
12678 !values.locale.equals(mConfiguration.locale),
12679 values.userSetLocale);
12680 }
12681
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012682 mConfigurationSeq++;
12683 if (mConfigurationSeq <= 0) {
12684 mConfigurationSeq = 1;
12685 }
12686 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012687 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012688 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012689
12690 AttributeCache ac = AttributeCache.instance();
12691 if (ac != null) {
12692 ac.updateConfiguration(mConfiguration);
12693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012695 // Make sure all resources in our process are updated
12696 // right now, so that anyone who is going to retrieve
12697 // resource values after we return will be sure to get
12698 // the new ones. This is especially important during
12699 // boot, where the first config change needs to guarantee
12700 // all resources have that config before following boot
12701 // code is executed.
12702 mSystemThread.applyConfigurationToResources(newConfig);
12703
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012704 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012705 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12706 msg.obj = new Configuration(mConfiguration);
12707 mHandler.sendMessage(msg);
12708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012709
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012710 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12711 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012712 try {
12713 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012714 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012715 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012716 app.thread.scheduleConfigurationChanged(mConfiguration);
12717 }
12718 } catch (Exception e) {
12719 }
12720 }
12721 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012722 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12723 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012724 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12725 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012726 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12727 broadcastIntentLocked(null, null,
12728 new Intent(Intent.ACTION_LOCALE_CHANGED),
12729 null, null, 0, null, null,
12730 null, false, false, MY_PID, Process.SYSTEM_UID);
12731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012732 }
12733 }
12734
12735 if (changes != 0 && starting == null) {
12736 // If the configuration changed, and the caller is not already
12737 // in the process of starting an activity, then find the top
12738 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012739 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012740 }
12741
12742 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012743 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012744 // And we need to make sure at this point that all other activities
12745 // are made visible with the correct configuration.
12746 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012747 }
12748
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012749 if (values != null && mWindowManager != null) {
12750 mWindowManager.setNewConfiguration(mConfiguration);
12751 }
12752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 return kept;
12754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012755
12756 /**
12757 * Save the locale. You must be inside a synchronized (this) block.
12758 */
12759 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12760 if(isDiff) {
12761 SystemProperties.set("user.language", l.getLanguage());
12762 SystemProperties.set("user.region", l.getCountry());
12763 }
12764
12765 if(isPersist) {
12766 SystemProperties.set("persist.sys.language", l.getLanguage());
12767 SystemProperties.set("persist.sys.country", l.getCountry());
12768 SystemProperties.set("persist.sys.localevar", l.getVariant());
12769 }
12770 }
12771
12772 // =========================================================
12773 // LIFETIME MANAGEMENT
12774 // =========================================================
12775
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012776 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12777 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012779 // This adjustment has already been computed. If we are calling
12780 // from the top, we may have already computed our adjustment with
12781 // an earlier hidden adjustment that isn't really for us... if
12782 // so, use the new hidden adjustment.
12783 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012784 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012785 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012786 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012787 }
12788
12789 if (app.thread == null) {
12790 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012791 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012792 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012793 }
12794
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012795 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12796 app.adjSource = null;
12797 app.adjTarget = null;
12798 app.empty = false;
12799 app.hidden = false;
12800
12801 final int activitiesSize = app.activities.size();
12802
Dianne Hackborn7d608422011-08-07 16:24:18 -070012803 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012804 // The max adjustment doesn't allow this app to be anything
12805 // below foreground, so it is not worth doing work for it.
12806 app.adjType = "fixed";
12807 app.adjSeq = mAdjSeq;
12808 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012809 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012810 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012811 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012812 // System process can do UI, and when they do we want to have
12813 // them trim their memory after the user leaves the UI. To
12814 // facilitate this, here we need to determine whether or not it
12815 // is currently showing UI.
12816 app.systemNoUi = true;
12817 if (app == TOP_APP) {
12818 app.systemNoUi = false;
12819 } else if (activitiesSize > 0) {
12820 for (int j = 0; j < activitiesSize; j++) {
12821 final ActivityRecord r = app.activities.get(j);
12822 if (r.visible) {
12823 app.systemNoUi = false;
12824 break;
12825 }
12826 }
12827 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012828 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012829 }
12830
12831 final boolean hadForegroundActivities = app.foregroundActivities;
12832
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012833 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012834 app.keeping = false;
12835 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012836
The Android Open Source Project4df24232009-03-05 14:34:35 -080012837 // Determine the importance of the process, starting with most
12838 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012840 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012841 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012842 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012843 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012844 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012845 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012846 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012847 } else if (app.instrumentationClass != null) {
12848 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012849 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012850 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012851 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012852 } else if (app.curReceiver != null ||
12853 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12854 // An app that is currently receiving a broadcast also
12855 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012856 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012857 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012858 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 } else if (app.executingServices.size() > 0) {
12860 // An app that is currently executing a service callback also
12861 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012862 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012863 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012864 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012865 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012866 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012867 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012868 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012869 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012870 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012871 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012872 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012873 // A very not-needed process. If this is lower in the lru list,
12874 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012875 adj = hiddenAdj;
12876 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012877 app.hidden = true;
12878 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012879 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012880 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012881
12882 // Examine all activities if not already foreground.
12883 if (!app.foregroundActivities && activitiesSize > 0) {
12884 for (int j = 0; j < activitiesSize; j++) {
12885 final ActivityRecord r = app.activities.get(j);
12886 if (r.visible) {
12887 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012888 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12889 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012890 app.adjType = "visible";
12891 }
12892 schedGroup = Process.THREAD_GROUP_DEFAULT;
12893 app.hidden = false;
12894 app.foregroundActivities = true;
12895 break;
12896 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12897 || r.state == ActivityState.STOPPING) {
12898 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012899 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12900 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012901 app.adjType = "stopping";
12902 }
12903 app.foregroundActivities = true;
12904 }
12905 }
12906 }
12907
Dianne Hackborn7d608422011-08-07 16:24:18 -070012908 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012909 if (app.foregroundServices) {
12910 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012911 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012912 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012913 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012914 } else if (app.forcingToForeground != null) {
12915 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012916 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012917 app.adjType = "force-foreground";
12918 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012919 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012920 }
12921 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012922
Dianne Hackborn7d608422011-08-07 16:24:18 -070012923 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012924 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012925 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012926 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12927 app.adjType = "heavy";
12928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012929
Dianne Hackborn7d608422011-08-07 16:24:18 -070012930 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012931 // This process is hosting what we currently consider to be the
12932 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012933 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012934 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12935 app.adjType = "home";
12936 }
12937
Joe Onorato8a9b2202010-02-26 18:56:32 -080012938 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012939
The Android Open Source Project4df24232009-03-05 14:34:35 -080012940 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 // there are applications dependent on our services or providers, but
12942 // this gives us a baseline and makes sure we don't get into an
12943 // infinite recursion.
12944 app.adjSeq = mAdjSeq;
12945 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012946
Christopher Tate6fa95972009-06-05 18:43:55 -070012947 if (mBackupTarget != null && app == mBackupTarget.app) {
12948 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012949 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012950 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012951 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012952 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012953 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012954 }
12955 }
12956
Dianne Hackborn7d608422011-08-07 16:24:18 -070012957 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012958 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012959 final long now = SystemClock.uptimeMillis();
12960 // This process is more important if the top activity is
12961 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012962 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012963 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012964 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012965 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012966 if (app.hasShownUi) {
12967 // If this process has shown some UI, let it immediately
12968 // go to the LRU list because it may be pretty heavy with
12969 // UI stuff. We'll tag it with a label just to help
12970 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012971 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012972 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012974 } else {
12975 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12976 // This service has seen some activity within
12977 // recent memory, so we will keep its process ahead
12978 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012979 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
12980 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012981 app.adjType = "started-services";
12982 app.hidden = false;
12983 }
12984 }
12985 // If we have let the service slide into the background
12986 // state, still have some text describing what it is doing
12987 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012988 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012989 app.adjType = "started-bg-services";
12990 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012991 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012992 // Don't kill this process because it is doing work; it
12993 // has said it is doing work.
12994 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012996 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012997 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012998 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013000 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013001 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013002 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013003 // XXX should compute this based on the max of
13004 // all connected clients.
13005 ConnectionRecord cr = clist.get(i);
13006 if (cr.binding.client == app) {
13007 // Binding to ourself is not interesting.
13008 continue;
13009 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013010 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013011 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013012 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013013 int myHiddenAdj = hiddenAdj;
13014 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013015 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013016 myHiddenAdj = client.hiddenAdj;
13017 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013018 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013019 }
13020 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013021 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013022 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013023 String adjType = null;
13024 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13025 // Not doing bind OOM management, so treat
13026 // this guy more like a started service.
13027 if (app.hasShownUi) {
13028 // If this process has shown some UI, let it immediately
13029 // go to the LRU list because it may be pretty heavy with
13030 // UI stuff. We'll tag it with a label just to help
13031 // debug and understand what is going on.
13032 if (adj > clientAdj) {
13033 adjType = "bound-bg-ui-services";
13034 }
13035 clientAdj = adj;
13036 } else {
13037 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13038 // This service has not seen activity within
13039 // recent memory, so allow it to drop to the
13040 // LRU list if there is no other reason to keep
13041 // it around. We'll also tag it with a label just
13042 // to help debug and undertand what is going on.
13043 if (adj > clientAdj) {
13044 adjType = "bound-bg-services";
13045 }
13046 clientAdj = adj;
13047 }
13048 }
13049 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013050 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013051 // If this process has recently shown UI, and
13052 // the process that is binding to it is less
13053 // important than being visible, then we don't
13054 // care about the binding as much as we care
13055 // about letting this process get into the LRU
13056 // list to be killed and restarted if needed for
13057 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013058 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013059 adjType = "bound-bg-ui-services";
13060 } else {
13061 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13062 |Context.BIND_IMPORTANT)) != 0) {
13063 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013064 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013065 adj = clientAdj;
13066 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013067 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013068 }
13069 if (!client.hidden) {
13070 app.hidden = false;
13071 }
13072 if (client.keeping) {
13073 app.keeping = true;
13074 }
13075 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013076 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013077 }
13078 if (adjType != null) {
13079 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013080 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13081 .REASON_SERVICE_IN_USE;
13082 app.adjSource = cr.binding.client;
13083 app.adjTarget = s.name;
13084 }
13085 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13086 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13087 schedGroup = Process.THREAD_GROUP_DEFAULT;
13088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013089 }
13090 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013091 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13092 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013093 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013094 (a.visible || a.state == ActivityState.RESUMED
13095 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013096 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013097 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13098 schedGroup = Process.THREAD_GROUP_DEFAULT;
13099 }
13100 app.hidden = false;
13101 app.adjType = "service";
13102 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13103 .REASON_SERVICE_IN_USE;
13104 app.adjSource = a;
13105 app.adjTarget = s.name;
13106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013108 }
13109 }
13110 }
13111 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013112
Dianne Hackborn287952c2010-09-22 22:34:31 -070013113 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013114 // would like to avoid killing it unless it would prevent the current
13115 // application from running. By default we put the process in
13116 // with the rest of the background processes; as we scan through
13117 // its services we may bump it up from there.
13118 if (adj > hiddenAdj) {
13119 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013120 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013121 app.adjType = "bg-services";
13122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013123 }
13124
Dianne Hackborn7d608422011-08-07 16:24:18 -070013125 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013126 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013127 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013128 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013129 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013130 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013131 if (cpr.clients.size() != 0) {
13132 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013133 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013134 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013135 if (client == app) {
13136 // Being our own client is not interesting.
13137 continue;
13138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013139 int myHiddenAdj = hiddenAdj;
13140 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013141 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013142 myHiddenAdj = client.hiddenAdj;
13143 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013144 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 }
13146 }
13147 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013148 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013149 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013150 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013151 app.adjType = "bg-ui-provider";
13152 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013153 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13154 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013155 app.adjType = "provider";
13156 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013157 if (!client.hidden) {
13158 app.hidden = false;
13159 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013160 if (client.keeping) {
13161 app.keeping = true;
13162 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013163 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13164 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013165 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013166 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013167 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013168 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13169 schedGroup = Process.THREAD_GROUP_DEFAULT;
13170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013171 }
13172 }
13173 // If the provider has external (non-framework) process
13174 // dependencies, ensure that its adjustment is at least
13175 // FOREGROUND_APP_ADJ.
13176 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013177 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13178 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013179 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013180 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013181 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013182 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013183 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013184 }
13185 }
13186 }
13187 }
13188
13189 app.curRawAdj = adj;
13190
Joe Onorato8a9b2202010-02-26 18:56:32 -080013191 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013192 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13193 if (adj > app.maxAdj) {
13194 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013195 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013196 schedGroup = Process.THREAD_GROUP_DEFAULT;
13197 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013198 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013199 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013200 app.keeping = true;
13201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013202
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013203 if (app.hasAboveClient) {
13204 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13205 // then we need to drop its adjustment to be lower than the service's
13206 // in order to honor the request. We want to drop it by one adjustment
13207 // level... but there is special meaning applied to various levels so
13208 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013209 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013210 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013211 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13212 adj = ProcessList.VISIBLE_APP_ADJ;
13213 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13214 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13215 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13216 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13217 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013218 adj++;
13219 }
13220 }
13221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013222 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013223 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013224
13225 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013226 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13227 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013228 }
13229
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013230 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013231 }
13232
13233 /**
13234 * Ask a given process to GC right now.
13235 */
13236 final void performAppGcLocked(ProcessRecord app) {
13237 try {
13238 app.lastRequestedGc = SystemClock.uptimeMillis();
13239 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013240 if (app.reportLowMemory) {
13241 app.reportLowMemory = false;
13242 app.thread.scheduleLowMemory();
13243 } else {
13244 app.thread.processInBackground();
13245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013246 }
13247 } catch (Exception e) {
13248 // whatever.
13249 }
13250 }
13251
13252 /**
13253 * Returns true if things are idle enough to perform GCs.
13254 */
Josh Bartel7f208742010-02-25 11:01:44 -060013255 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013256 return mParallelBroadcasts.size() == 0
13257 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013258 && (mSleeping || (mMainStack.mResumedActivity != null &&
13259 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013260 }
13261
13262 /**
13263 * Perform GCs on all processes that are waiting for it, but only
13264 * if things are idle.
13265 */
13266 final void performAppGcsLocked() {
13267 final int N = mProcessesToGc.size();
13268 if (N <= 0) {
13269 return;
13270 }
Josh Bartel7f208742010-02-25 11:01:44 -060013271 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013272 while (mProcessesToGc.size() > 0) {
13273 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013274 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013275 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13276 <= SystemClock.uptimeMillis()) {
13277 // To avoid spamming the system, we will GC processes one
13278 // at a time, waiting a few seconds between each.
13279 performAppGcLocked(proc);
13280 scheduleAppGcsLocked();
13281 return;
13282 } else {
13283 // It hasn't been long enough since we last GCed this
13284 // process... put it in the list to wait for its time.
13285 addProcessToGcListLocked(proc);
13286 break;
13287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 }
13289 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013290
13291 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 }
13293 }
13294
13295 /**
13296 * If all looks good, perform GCs on all processes waiting for them.
13297 */
13298 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013299 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013300 performAppGcsLocked();
13301 return;
13302 }
13303 // Still not idle, wait some more.
13304 scheduleAppGcsLocked();
13305 }
13306
13307 /**
13308 * Schedule the execution of all pending app GCs.
13309 */
13310 final void scheduleAppGcsLocked() {
13311 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013312
13313 if (mProcessesToGc.size() > 0) {
13314 // Schedule a GC for the time to the next process.
13315 ProcessRecord proc = mProcessesToGc.get(0);
13316 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13317
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013318 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013319 long now = SystemClock.uptimeMillis();
13320 if (when < (now+GC_TIMEOUT)) {
13321 when = now + GC_TIMEOUT;
13322 }
13323 mHandler.sendMessageAtTime(msg, when);
13324 }
13325 }
13326
13327 /**
13328 * Add a process to the array of processes waiting to be GCed. Keeps the
13329 * list in sorted order by the last GC time. The process can't already be
13330 * on the list.
13331 */
13332 final void addProcessToGcListLocked(ProcessRecord proc) {
13333 boolean added = false;
13334 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13335 if (mProcessesToGc.get(i).lastRequestedGc <
13336 proc.lastRequestedGc) {
13337 added = true;
13338 mProcessesToGc.add(i+1, proc);
13339 break;
13340 }
13341 }
13342 if (!added) {
13343 mProcessesToGc.add(0, proc);
13344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013345 }
13346
13347 /**
13348 * Set up to ask a process to GC itself. This will either do it
13349 * immediately, or put it on the list of processes to gc the next
13350 * time things are idle.
13351 */
13352 final void scheduleAppGcLocked(ProcessRecord app) {
13353 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013354 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013355 return;
13356 }
13357 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013358 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013359 scheduleAppGcsLocked();
13360 }
13361 }
13362
Dianne Hackborn287952c2010-09-22 22:34:31 -070013363 final void checkExcessivePowerUsageLocked(boolean doKills) {
13364 updateCpuStatsNow();
13365
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013366 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013367 boolean doWakeKills = doKills;
13368 boolean doCpuKills = doKills;
13369 if (mLastPowerCheckRealtime == 0) {
13370 doWakeKills = false;
13371 }
13372 if (mLastPowerCheckUptime == 0) {
13373 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013374 }
13375 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013376 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013377 }
13378 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013379 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13380 final long curUptime = SystemClock.uptimeMillis();
13381 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13382 mLastPowerCheckRealtime = curRealtime;
13383 mLastPowerCheckUptime = curUptime;
13384 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13385 doWakeKills = false;
13386 }
13387 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13388 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013389 }
13390 int i = mLruProcesses.size();
13391 while (i > 0) {
13392 i--;
13393 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013394 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013395 long wtime;
13396 synchronized (stats) {
13397 wtime = stats.getProcessWakeTime(app.info.uid,
13398 app.pid, curRealtime);
13399 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013400 long wtimeUsed = wtime - app.lastWakeTime;
13401 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13402 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013403 StringBuilder sb = new StringBuilder(128);
13404 sb.append("Wake for ");
13405 app.toShortString(sb);
13406 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013407 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013408 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013409 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013410 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013411 sb.append((wtimeUsed*100)/realtimeSince);
13412 sb.append("%)");
13413 Slog.i(TAG, sb.toString());
13414 sb.setLength(0);
13415 sb.append("CPU for ");
13416 app.toShortString(sb);
13417 sb.append(": over ");
13418 TimeUtils.formatDuration(uptimeSince, sb);
13419 sb.append(" used ");
13420 TimeUtils.formatDuration(cputimeUsed, sb);
13421 sb.append(" (");
13422 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013423 sb.append("%)");
13424 Slog.i(TAG, sb.toString());
13425 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013426 // If a process has held a wake lock for more
13427 // than 50% of the time during this period,
13428 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013429 if (doWakeKills && realtimeSince > 0
13430 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13431 synchronized (stats) {
13432 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13433 realtimeSince, wtimeUsed);
13434 }
13435 Slog.w(TAG, "Excessive wake lock in " + app.processName
13436 + " (pid " + app.pid + "): held " + wtimeUsed
13437 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013438 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13439 app.processName, app.setAdj, "excessive wake lock");
13440 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013441 } else if (doCpuKills && uptimeSince > 0
13442 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13443 synchronized (stats) {
13444 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13445 uptimeSince, cputimeUsed);
13446 }
13447 Slog.w(TAG, "Excessive CPU in " + app.processName
13448 + " (pid " + app.pid + "): used " + cputimeUsed
13449 + " during " + uptimeSince);
13450 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13451 app.processName, app.setAdj, "excessive cpu");
13452 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013453 } else {
13454 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013455 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013456 }
13457 }
13458 }
13459 }
13460
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013461 private final void updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013462 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013463 app.hiddenAdj = hiddenAdj;
13464
13465 if (app.thread == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013466 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013467 }
13468
Dianne Hackborn287952c2010-09-22 22:34:31 -070013469 final boolean wasKeeping = app.keeping;
13470
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013471 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013472
Jeff Brown10e89712011-07-08 18:52:57 -070013473 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013474 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13475 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013476 // If this app is transitioning from foreground to
13477 // non-foreground, have it do a gc.
13478 scheduleAppGcLocked(app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013479 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13480 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013481 // Likewise do a gc when an app is moving in to the
13482 // background (such as a service stopping).
13483 scheduleAppGcLocked(app);
13484 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013485
Jeff Brown10e89712011-07-08 18:52:57 -070013486 if (wasKeeping && !app.keeping) {
13487 // This app is no longer something we want to keep. Note
13488 // its current wake lock time to later know to kill it if
13489 // it is not behaving well.
13490 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13491 synchronized (stats) {
13492 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13493 app.pid, SystemClock.elapsedRealtime());
13494 }
13495 app.lastCpuTime = app.curCpuTime;
13496 }
13497
13498 app.setRawAdj = app.curRawAdj;
13499 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013500 if (app.curAdj != app.setAdj) {
13501 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013502 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13503 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013504 " oom adj to " + app.curAdj + " because " + app.adjType);
13505 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013506 } else {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013507 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013508 }
13509 }
13510 if (app.setSchedGroup != app.curSchedGroup) {
13511 app.setSchedGroup = app.curSchedGroup;
13512 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13513 "Setting process group of " + app.processName
13514 + " to " + app.curSchedGroup);
13515 if (app.waitingToKill != null &&
13516 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13517 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13518 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13519 app.processName, app.setAdj, app.waitingToKill);
13520 Process.killProcessQuiet(app.pid);
13521 } else {
13522 if (true) {
13523 long oldId = Binder.clearCallingIdentity();
13524 try {
13525 Process.setProcessGroup(app.pid, app.curSchedGroup);
13526 } catch (Exception e) {
13527 Slog.w(TAG, "Failed setting process group of " + app.pid
13528 + " to " + app.curSchedGroup);
13529 e.printStackTrace();
13530 } finally {
13531 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013532 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013533 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013534 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013535 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013536 app.thread.setSchedulingGroup(app.curSchedGroup);
13537 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013538 }
13539 }
13540 }
13541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013543 }
13544
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013545 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013546 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013547 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013548 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013549 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013550 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013551 }
13552 }
13553 return resumedActivity;
13554 }
13555
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013556 private final void updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013557 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013558 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13559 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013560 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13561 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013562
13563 mAdjSeq++;
13564
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013565 updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013566 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13567 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013568 if (nowHidden != wasHidden) {
13569 // Changed to/from hidden state, so apps after it in the LRU
13570 // list may also be changed.
13571 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013573 }
13574
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013575 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013576 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013577 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13578
13579 if (false) {
13580 RuntimeException e = new RuntimeException();
13581 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013582 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013583 }
13584
13585 mAdjSeq++;
13586
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013587 // Let's determine how many processes we have running vs.
13588 // how many slots we have for background processes; we may want
13589 // to put multiple processes in a slot of there are enough of
13590 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013591 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013592 int factor = (mLruProcesses.size()-4)/numSlots;
13593 if (factor < 1) factor = 1;
13594 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013595 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013596
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013597 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013598 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013599 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013600 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013601 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013602 while (i > 0) {
13603 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013604 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013605 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013606 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013607 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013608 && app.curAdj == curHiddenAdj) {
13609 step++;
13610 if (step >= factor) {
13611 step = 0;
13612 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013613 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013614 }
13615 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013616 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013617 numHidden++;
13618 if (numHidden > mProcessLimit) {
13619 Slog.i(TAG, "No longer want " + app.processName
13620 + " (pid " + app.pid + "): hidden #" + numHidden);
13621 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13622 app.processName, app.setAdj, "too many background");
13623 app.killedBackground = true;
13624 Process.killProcessQuiet(app.pid);
13625 } else {
13626 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013627 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013628 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013629 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013631 }
13632 }
13633
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013634 // Now determine the memory trimming level of background processes.
13635 // Unfortunately we need to start at the back of the list to do this
13636 // properly. We only do this if the number of background apps we
13637 // are managing to keep around is less than half the maximum we desire;
13638 // if we are keeping a good number around, we'll let them use whatever
13639 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013640 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013641 final int N = mLruProcesses.size();
13642 factor = numBg/3;
13643 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013644 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013645 for (i=0; i<N; i++) {
13646 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013647 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013648 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13649 try {
13650 app.thread.scheduleTrimMemory(curLevel);
13651 } catch (RemoteException e) {
13652 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013653 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013654 // For these apps we will also finish their activities
13655 // to help them free memory.
13656 mMainStack.destroyActivitiesLocked(app, false);
13657 }
13658 }
13659 app.trimMemoryLevel = curLevel;
13660 step++;
13661 if (step >= factor) {
13662 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013663 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13664 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013665 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013666 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13667 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013668 break;
13669 }
13670 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013671 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013672 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013673 && app.thread != null) {
13674 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013675 app.thread.scheduleTrimMemory(
13676 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013677 } catch (RemoteException e) {
13678 }
13679 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013680 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013681 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013682 && app.pendingUiClean) {
13683 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13684 && app.thread != null) {
13685 try {
13686 app.thread.scheduleTrimMemory(
13687 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13688 } catch (RemoteException e) {
13689 }
13690 }
13691 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13692 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013693 } else {
13694 app.trimMemoryLevel = 0;
13695 }
13696 }
13697 } else {
13698 final int N = mLruProcesses.size();
13699 for (i=0; i<N; i++) {
13700 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013701 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013702 && app.pendingUiClean) {
13703 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13704 && app.thread != null) {
13705 try {
13706 app.thread.scheduleTrimMemory(
13707 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13708 } catch (RemoteException e) {
13709 }
13710 }
13711 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13712 app.pendingUiClean = false;
13713 } else {
13714 app.trimMemoryLevel = 0;
13715 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013716 }
13717 }
13718
13719 if (mAlwaysFinishActivities) {
13720 mMainStack.destroyActivitiesLocked(null, false);
13721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013722 }
13723
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013724 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013725 synchronized (this) {
13726 int i;
13727
13728 // First remove any unused application processes whose package
13729 // has been removed.
13730 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13731 final ProcessRecord app = mRemovedProcesses.get(i);
13732 if (app.activities.size() == 0
13733 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013734 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013735 TAG, "Exiting empty application process "
13736 + app.processName + " ("
13737 + (app.thread != null ? app.thread.asBinder() : null)
13738 + ")\n");
13739 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013740 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13741 app.processName, app.setAdj, "empty");
13742 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013743 } else {
13744 try {
13745 app.thread.scheduleExit();
13746 } catch (Exception e) {
13747 // Ignore exceptions.
13748 }
13749 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013750 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013751 mRemovedProcesses.remove(i);
13752
13753 if (app.persistent) {
13754 if (app.persistent) {
13755 addAppLocked(app.info);
13756 }
13757 }
13758 }
13759 }
13760
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013761 // Now update the oom adj for all processes.
13762 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013763 }
13764 }
13765
13766 /** This method sends the specified signal to each of the persistent apps */
13767 public void signalPersistentProcesses(int sig) throws RemoteException {
13768 if (sig != Process.SIGNAL_USR1) {
13769 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13770 }
13771
13772 synchronized (this) {
13773 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13774 != PackageManager.PERMISSION_GRANTED) {
13775 throw new SecurityException("Requires permission "
13776 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13777 }
13778
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013779 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13780 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013781 if (r.thread != null && r.persistent) {
13782 Process.sendSignal(r.pid, sig);
13783 }
13784 }
13785 }
13786 }
13787
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013788 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13789 if (proc == null || proc == mProfileProc) {
13790 proc = mProfileProc;
13791 path = mProfileFile;
13792 profileType = mProfileType;
13793 clearProfilerLocked();
13794 }
13795 if (proc == null) {
13796 return;
13797 }
13798 try {
13799 proc.thread.profilerControl(false, path, null, profileType);
13800 } catch (RemoteException e) {
13801 throw new IllegalStateException("Process disappeared");
13802 }
13803 }
13804
13805 private void clearProfilerLocked() {
13806 if (mProfileFd != null) {
13807 try {
13808 mProfileFd.close();
13809 } catch (IOException e) {
13810 }
13811 }
13812 mProfileApp = null;
13813 mProfileProc = null;
13814 mProfileFile = null;
13815 mProfileType = 0;
13816 mAutoStopProfiler = false;
13817 }
13818
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013819 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013820 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013821
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013822 try {
13823 synchronized (this) {
13824 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13825 // its own permission.
13826 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13827 != PackageManager.PERMISSION_GRANTED) {
13828 throw new SecurityException("Requires permission "
13829 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013830 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013831
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013832 if (start && fd == null) {
13833 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013834 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013835
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013836 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013837 if (process != null) {
13838 try {
13839 int pid = Integer.parseInt(process);
13840 synchronized (mPidsSelfLocked) {
13841 proc = mPidsSelfLocked.get(pid);
13842 }
13843 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013844 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013845
13846 if (proc == null) {
13847 HashMap<String, SparseArray<ProcessRecord>> all
13848 = mProcessNames.getMap();
13849 SparseArray<ProcessRecord> procs = all.get(process);
13850 if (procs != null && procs.size() > 0) {
13851 proc = procs.valueAt(0);
13852 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013853 }
13854 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013855
13856 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013857 throw new IllegalArgumentException("Unknown process: " + process);
13858 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013859
13860 if (start) {
13861 stopProfilerLocked(null, null, 0);
13862 setProfileApp(proc.info, proc.processName, path, fd, false);
13863 mProfileProc = proc;
13864 mProfileType = profileType;
13865 try {
13866 fd = fd.dup();
13867 } catch (IOException e) {
13868 fd = null;
13869 }
13870 proc.thread.profilerControl(start, path, fd, profileType);
13871 fd = null;
13872 mProfileFd = null;
13873 } else {
13874 stopProfilerLocked(proc, path, profileType);
13875 if (fd != null) {
13876 try {
13877 fd.close();
13878 } catch (IOException e) {
13879 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013880 }
13881 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013882
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013883 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013884 }
13885 } catch (RemoteException e) {
13886 throw new IllegalStateException("Process disappeared");
13887 } finally {
13888 if (fd != null) {
13889 try {
13890 fd.close();
13891 } catch (IOException e) {
13892 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013893 }
13894 }
13895 }
Andy McFadden824c5102010-07-09 16:26:57 -070013896
13897 public boolean dumpHeap(String process, boolean managed,
13898 String path, ParcelFileDescriptor fd) throws RemoteException {
13899
13900 try {
13901 synchronized (this) {
13902 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13903 // its own permission (same as profileControl).
13904 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13905 != PackageManager.PERMISSION_GRANTED) {
13906 throw new SecurityException("Requires permission "
13907 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13908 }
13909
13910 if (fd == null) {
13911 throw new IllegalArgumentException("null fd");
13912 }
13913
13914 ProcessRecord proc = null;
13915 try {
13916 int pid = Integer.parseInt(process);
13917 synchronized (mPidsSelfLocked) {
13918 proc = mPidsSelfLocked.get(pid);
13919 }
13920 } catch (NumberFormatException e) {
13921 }
13922
13923 if (proc == null) {
13924 HashMap<String, SparseArray<ProcessRecord>> all
13925 = mProcessNames.getMap();
13926 SparseArray<ProcessRecord> procs = all.get(process);
13927 if (procs != null && procs.size() > 0) {
13928 proc = procs.valueAt(0);
13929 }
13930 }
13931
13932 if (proc == null || proc.thread == null) {
13933 throw new IllegalArgumentException("Unknown process: " + process);
13934 }
13935
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013936 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13937 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013938 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13939 throw new SecurityException("Process not debuggable: " + proc);
13940 }
13941 }
13942
13943 proc.thread.dumpHeap(managed, path, fd);
13944 fd = null;
13945 return true;
13946 }
13947 } catch (RemoteException e) {
13948 throw new IllegalStateException("Process disappeared");
13949 } finally {
13950 if (fd != null) {
13951 try {
13952 fd.close();
13953 } catch (IOException e) {
13954 }
13955 }
13956 }
13957 }
13958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013959 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13960 public void monitor() {
13961 synchronized (this) { }
13962 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013963
13964 public void onCoreSettingsChange(Bundle settings) {
13965 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13966 ProcessRecord processRecord = mLruProcesses.get(i);
13967 try {
13968 if (processRecord.thread != null) {
13969 processRecord.thread.setCoreSettings(settings);
13970 }
13971 } catch (RemoteException re) {
13972 /* ignore */
13973 }
13974 }
13975 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013976
13977 // Multi-user methods
13978
13979 public boolean switchUser(int userid) {
13980 // TODO
13981 return true;
13982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013983}