blob: 24f477937d350479548db25d05530a382af8e87d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
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;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700168 static final boolean DEBUG_BACKUP = localLOGV || false;
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) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001321 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1322 != PackageManager.PERMISSION_GRANTED) {
1323 pw.println("Permission Denial: can't dump meminfo from from pid="
1324 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1325 + " without permission " + android.Manifest.permission.DUMP);
1326 return;
1327 }
1328
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001329 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 }
1331 }
1332
Chet Haase9c1e23b2011-03-24 10:51:31 -07001333 static class GraphicsBinder extends Binder {
1334 ActivityManagerService mActivityManagerService;
1335 GraphicsBinder(ActivityManagerService activityManagerService) {
1336 mActivityManagerService = activityManagerService;
1337 }
1338
1339 @Override
1340 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001341 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1342 != PackageManager.PERMISSION_GRANTED) {
1343 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1344 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1345 + " without permission " + android.Manifest.permission.DUMP);
1346 return;
1347 }
1348
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001349 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001350 }
1351 }
1352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 static class CpuBinder extends Binder {
1354 ActivityManagerService mActivityManagerService;
1355 CpuBinder(ActivityManagerService activityManagerService) {
1356 mActivityManagerService = activityManagerService;
1357 }
1358
1359 @Override
1360 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001361 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1362 != PackageManager.PERMISSION_GRANTED) {
1363 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1364 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1365 + " without permission " + android.Manifest.permission.DUMP);
1366 return;
1367 }
1368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001370 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1371 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1372 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 }
1374 }
1375 }
1376
1377 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001378 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 File dataDir = Environment.getDataDirectory();
1381 File systemDir = new File(dataDir, "system");
1382 systemDir.mkdirs();
1383 mBatteryStatsService = new BatteryStatsService(new File(
1384 systemDir, "batterystats.bin").toString());
1385 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001386 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001387 mOnBattery = DEBUG_POWER ? true
1388 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001389 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001391 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001392 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393
Jack Palevichb90d28c2009-07-22 15:35:24 -07001394 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1395 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1396
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001397 mConfiguration.setToDefaults();
1398 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 mProcessStats.init();
1400
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001401 mCompatModePackages = new CompatModePackages(this, systemDir);
1402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 // Add ourself to the Watchdog monitors.
1404 Watchdog.getInstance().addMonitor(this);
1405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 mProcessStatsThread = new Thread("ProcessStats") {
1407 public void run() {
1408 while (true) {
1409 try {
1410 try {
1411 synchronized(this) {
1412 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001413 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 // + ", write delay=" + nextWriteDelay);
1417 if (nextWriteDelay < nextCpuDelay) {
1418 nextCpuDelay = nextWriteDelay;
1419 }
1420 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001421 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 this.wait(nextCpuDelay);
1423 }
1424 }
1425 } catch (InterruptedException e) {
1426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 updateCpuStatsNow();
1428 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001429 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 }
1431 }
1432 }
1433 };
1434 mProcessStatsThread.start();
1435 }
1436
1437 @Override
1438 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1439 throws RemoteException {
1440 try {
1441 return super.onTransact(code, data, reply, flags);
1442 } catch (RuntimeException e) {
1443 // The activity manager only throws security exceptions, so let's
1444 // log all others.
1445 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001446 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 }
1448 throw e;
1449 }
1450 }
1451
1452 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001453 final long now = SystemClock.uptimeMillis();
1454 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1455 return;
1456 }
1457 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1458 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 mProcessStatsThread.notify();
1460 }
1461 }
1462 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 void updateCpuStatsNow() {
1465 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001466 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 final long now = SystemClock.uptimeMillis();
1468 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001471 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1472 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 haveNewCpuStats = true;
1474 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 //Slog.i(TAG, mProcessStats.printCurrentState());
1476 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 // + mProcessStats.getTotalCpuPercent() + "%");
1478
Joe Onorato8a9b2202010-02-26 18:56:32 -08001479 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if ("true".equals(SystemProperties.get("events.cpu"))) {
1481 int user = mProcessStats.getLastUserTime();
1482 int system = mProcessStats.getLastSystemTime();
1483 int iowait = mProcessStats.getLastIoWaitTime();
1484 int irq = mProcessStats.getLastIrqTime();
1485 int softIrq = mProcessStats.getLastSoftIrqTime();
1486 int idle = mProcessStats.getLastIdleTime();
1487
1488 int total = user + system + iowait + irq + softIrq + idle;
1489 if (total == 0) total = 1;
1490
Doug Zongker2bec3d42009-12-04 12:52:44 -08001491 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ((user+system+iowait+irq+softIrq) * 100) / total,
1493 (user * 100) / total,
1494 (system * 100) / total,
1495 (iowait * 100) / total,
1496 (irq * 100) / total,
1497 (softIrq * 100) / total);
1498 }
1499 }
1500
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001502 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 synchronized(mPidsSelfLocked) {
1505 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001506 if (mOnBattery) {
1507 int perc = bstats.startAddingCpuLocked();
1508 int totalUTime = 0;
1509 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001510 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001512 ProcessStats.Stats st = mProcessStats.getStats(i);
1513 if (!st.working) {
1514 continue;
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001517 int otherUTime = (st.rel_utime*perc)/100;
1518 int otherSTime = (st.rel_stime*perc)/100;
1519 totalUTime += otherUTime;
1520 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 if (pr != null) {
1522 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001523 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1524 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001525 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001526 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001527 } else {
1528 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001529 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001530 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001531 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1532 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001533 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 }
1536 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001537 bstats.finishAddingCpuLocked(perc, totalUTime,
1538 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 }
1540 }
1541 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1544 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001545 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547 }
1548 }
1549 }
1550
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001551 @Override
1552 public void batteryNeedsCpuUpdate() {
1553 updateCpuStatsNow();
1554 }
1555
1556 @Override
1557 public void batteryPowerChanged(boolean onBattery) {
1558 // When plugging in, update the CPU stats first before changing
1559 // the plug state.
1560 updateCpuStatsNow();
1561 synchronized (this) {
1562 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001563 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001564 }
1565 }
1566 }
1567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 /**
1569 * Initialize the application bind args. These are passed to each
1570 * process when the bindApplication() IPC is sent to the process. They're
1571 * lazily setup to make sure the services are running when they're asked for.
1572 */
1573 private HashMap<String, IBinder> getCommonServicesLocked() {
1574 if (mAppBindArgs == null) {
1575 mAppBindArgs = new HashMap<String, IBinder>();
1576
1577 // Setup the application init args
1578 mAppBindArgs.put("package", ServiceManager.getService("package"));
1579 mAppBindArgs.put("window", ServiceManager.getService("window"));
1580 mAppBindArgs.put(Context.ALARM_SERVICE,
1581 ServiceManager.getService(Context.ALARM_SERVICE));
1582 }
1583 return mAppBindArgs;
1584 }
1585
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001586 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 if (mFocusedActivity != r) {
1588 mFocusedActivity = r;
1589 mWindowManager.setFocusedApp(r, true);
1590 }
1591 }
1592
Dianne Hackborn906497c2010-05-10 15:57:38 -07001593 private final void updateLruProcessInternalLocked(ProcessRecord app,
1594 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001596 int lrui = mLruProcesses.indexOf(app);
1597 if (lrui >= 0) mLruProcesses.remove(lrui);
1598
1599 int i = mLruProcesses.size()-1;
1600 int skipTop = 0;
1601
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602 app.lruSeq = mLruSeq;
1603
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001604 // compute the new weight for this process.
1605 if (updateActivityTime) {
1606 app.lastActivityTime = SystemClock.uptimeMillis();
1607 }
1608 if (app.activities.size() > 0) {
1609 // If this process has activities, we more strongly want to keep
1610 // it around.
1611 app.lruWeight = app.lastActivityTime;
1612 } else if (app.pubProviders.size() > 0) {
1613 // If this process contains content providers, we want to keep
1614 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001615 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001616 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001617 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001618 } else {
1619 // If this process doesn't have activities, we less strongly
1620 // want to keep it around, and generally want to avoid getting
1621 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001622 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001623 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001624 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001625 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001626
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001627 while (i >= 0) {
1628 ProcessRecord p = mLruProcesses.get(i);
1629 // If this app shouldn't be in front of the first N background
1630 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001631 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001632 skipTop--;
1633 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001634 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001635 mLruProcesses.add(i+1, app);
1636 break;
1637 }
1638 i--;
1639 }
1640 if (i < 0) {
1641 mLruProcesses.add(0, app);
1642 }
1643
Dianne Hackborn906497c2010-05-10 15:57:38 -07001644 // If the app is currently using a content provider or service,
1645 // bump those processes as well.
1646 if (app.connections.size() > 0) {
1647 for (ConnectionRecord cr : app.connections) {
1648 if (cr.binding != null && cr.binding.service != null
1649 && cr.binding.service.app != null
1650 && cr.binding.service.app.lruSeq != mLruSeq) {
1651 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1652 updateActivityTime, i+1);
1653 }
1654 }
1655 }
1656 if (app.conProviders.size() > 0) {
1657 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1659 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001660 updateActivityTime, i+1);
1661 }
1662 }
1663 }
1664
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 if (oomAdj) {
1667 updateOomAdjLocked();
1668 }
1669 }
1670
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001671 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001672 boolean oomAdj, boolean updateActivityTime) {
1673 mLruSeq++;
1674 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1675 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 String processName, int uid) {
1679 if (uid == Process.SYSTEM_UID) {
1680 // The system gets to run in any process. If there are multiple
1681 // processes with the same uid, just pick the first (this
1682 // should never happen).
1683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1684 processName);
1685 return procs != null ? procs.valueAt(0) : null;
1686 }
1687 ProcessRecord proc = mProcessNames.get(processName, uid);
1688 return proc;
1689 }
1690
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001691 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001692 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001693 try {
1694 if (pm.performDexOpt(packageName)) {
1695 mDidDexOpt = true;
1696 }
1697 } catch (RemoteException e) {
1698 }
1699 }
1700
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001701 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 int transit = mWindowManager.getPendingAppTransition();
1703 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1704 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1705 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1706 }
1707
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001708 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001710 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1712 // We don't have to do anything more if:
1713 // (1) There is an existing application record; and
1714 // (2) The caller doesn't think it is dead, OR there is no thread
1715 // object attached to it so we know it couldn't have crashed; and
1716 // (3) There is a pid assigned to it, so it is either starting or
1717 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001718 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 + " app=" + app + " knownToBeDead=" + knownToBeDead
1720 + " thread=" + (app != null ? app.thread : null)
1721 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001722 if (app != null && app.pid > 0) {
1723 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001724 // We already have the app running, or are waiting for it to
1725 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001726 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001727 // If this is a new package in the process, add the package to the list
1728 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001729 return app;
1730 } else {
1731 // An application record is attached to a previous process,
1732 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001733 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001734 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001738 String hostingNameStr = hostingName != null
1739 ? hostingName.flattenToShortString() : null;
1740
1741 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1742 // If we are in the background, then check to see if this process
1743 // is bad. If so, we will just silently fail.
1744 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001745 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1746 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 return null;
1748 }
1749 } else {
1750 // When the user is explicitly starting a process, then clear its
1751 // crash count so that we won't make it bad until they see at
1752 // least one crash dialog again, and make the process good again
1753 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001754 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1755 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 mProcessCrashTimes.remove(info.processName, info.uid);
1757 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001758 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 info.processName);
1760 mBadProcesses.remove(info.processName, info.uid);
1761 if (app != null) {
1762 app.bad = false;
1763 }
1764 }
1765 }
1766
1767 if (app == null) {
1768 app = newProcessRecordLocked(null, info, processName);
1769 mProcessNames.put(processName, info.uid, app);
1770 } else {
1771 // If this is a new package in the process, add the package to the list
1772 app.addPackage(info.packageName);
1773 }
1774
1775 // If the system is not ready yet, then hold off on starting this
1776 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001777 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001778 && !isAllowedWhileBooting(info)
1779 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 if (!mProcessesOnHold.contains(app)) {
1781 mProcessesOnHold.add(app);
1782 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001783 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 return app;
1785 }
1786
1787 startProcessLocked(app, hostingType, hostingNameStr);
1788 return (app.pid != 0) ? app : null;
1789 }
1790
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001791 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1792 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1793 }
1794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 private final void startProcessLocked(ProcessRecord app,
1796 String hostingType, String hostingNameStr) {
1797 if (app.pid > 0 && app.pid != MY_PID) {
1798 synchronized (mPidsSelfLocked) {
1799 mPidsSelfLocked.remove(app.pid);
1800 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1801 }
1802 app.pid = 0;
1803 }
1804
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001805 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1806 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 mProcessesOnHold.remove(app);
1808
1809 updateCpuStats();
1810
1811 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1812 mProcDeaths[0] = 0;
1813
1814 try {
1815 int uid = app.info.uid;
1816 int[] gids = null;
1817 try {
1818 gids = mContext.getPackageManager().getPackageGids(
1819 app.info.packageName);
1820 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001821 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 }
1823 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1824 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1825 && mTopComponent != null
1826 && app.processName.equals(mTopComponent.getPackageName())) {
1827 uid = 0;
1828 }
1829 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1830 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1831 uid = 0;
1832 }
1833 }
1834 int debugFlags = 0;
1835 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1836 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001837 // Also turn on CheckJNI for debuggable apps. It's quite
1838 // awkward to turn on otherwise.
1839 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001841 // Run the app in safe mode if its manifest requests so or the
1842 // system is booted in safe mode.
1843 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1844 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001845 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1848 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1849 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001850 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1851 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 if ("1".equals(SystemProperties.get("debug.assert"))) {
1854 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1855 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001856
1857 // Start the process. It will either succeed and return a result containing
1858 // the PID of the new process, or else throw a RuntimeException.
1859 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001860 app.processName, uid, uid, gids, debugFlags,
1861 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1864 synchronized (bs) {
1865 if (bs.isOnBattery()) {
1866 app.batteryStats.incStartsLocked();
1867 }
1868 }
1869
Jeff Brown3f9dd282011-07-08 20:02:19 -07001870 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 app.processName, hostingType,
1872 hostingNameStr != null ? hostingNameStr : "");
1873
1874 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001875 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 }
1877
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001878 StringBuilder buf = mStringBuilder;
1879 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 buf.append("Start proc ");
1881 buf.append(app.processName);
1882 buf.append(" for ");
1883 buf.append(hostingType);
1884 if (hostingNameStr != null) {
1885 buf.append(" ");
1886 buf.append(hostingNameStr);
1887 }
1888 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001889 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 buf.append(" uid=");
1891 buf.append(uid);
1892 buf.append(" gids={");
1893 if (gids != null) {
1894 for (int gi=0; gi<gids.length; gi++) {
1895 if (gi != 0) buf.append(", ");
1896 buf.append(gids[gi]);
1897
1898 }
1899 }
1900 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001901 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001902 app.pid = startResult.pid;
1903 app.usingWrapper = startResult.usingWrapper;
1904 app.removed = false;
1905 synchronized (mPidsSelfLocked) {
1906 this.mPidsSelfLocked.put(startResult.pid, app);
1907 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1908 msg.obj = app;
1909 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1910 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 }
1912 } catch (RuntimeException e) {
1913 // XXX do better error recovery.
1914 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001915 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 }
1917 }
1918
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001919 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 if (resumed) {
1921 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1922 } else {
1923 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1924 }
1925 }
1926
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001927 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001928 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1929 && mTopAction == null) {
1930 // We are running in factory test mode, but unable to find
1931 // the factory test app, so just sit around displaying the
1932 // error message and don't try to start anything.
1933 return false;
1934 }
1935 Intent intent = new Intent(
1936 mTopAction,
1937 mTopData != null ? Uri.parse(mTopData) : null);
1938 intent.setComponent(mTopComponent);
1939 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1940 intent.addCategory(Intent.CATEGORY_HOME);
1941 }
1942 ActivityInfo aInfo =
1943 intent.resolveActivityInfo(mContext.getPackageManager(),
1944 STOCK_PM_FLAGS);
1945 if (aInfo != null) {
1946 intent.setComponent(new ComponentName(
1947 aInfo.applicationInfo.packageName, aInfo.name));
1948 // Don't do this if the home app is currently being
1949 // instrumented.
1950 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1951 aInfo.applicationInfo.uid);
1952 if (app == null || app.instrumentationClass == null) {
1953 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001954 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001955 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001956 }
1957 }
1958
1959
1960 return true;
1961 }
1962
1963 /**
1964 * Starts the "new version setup screen" if appropriate.
1965 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001966 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001967 // Only do this once per boot.
1968 if (mCheckedForSetup) {
1969 return;
1970 }
1971
1972 // We will show this screen if the current one is a different
1973 // version than the last one shown, and we are not running in
1974 // low-level factory test mode.
1975 final ContentResolver resolver = mContext.getContentResolver();
1976 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1977 Settings.Secure.getInt(resolver,
1978 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1979 mCheckedForSetup = true;
1980
1981 // See if we should be showing the platform update setup UI.
1982 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1983 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1984 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1985
1986 // We don't allow third party apps to replace this.
1987 ResolveInfo ri = null;
1988 for (int i=0; ris != null && i<ris.size(); i++) {
1989 if ((ris.get(i).activityInfo.applicationInfo.flags
1990 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1991 ri = ris.get(i);
1992 break;
1993 }
1994 }
1995
1996 if (ri != null) {
1997 String vers = ri.activityInfo.metaData != null
1998 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1999 : null;
2000 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2001 vers = ri.activityInfo.applicationInfo.metaData.getString(
2002 Intent.METADATA_SETUP_VERSION);
2003 }
2004 String lastVers = Settings.Secure.getString(
2005 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2006 if (vers != null && !vers.equals(lastVers)) {
2007 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2008 intent.setComponent(new ComponentName(
2009 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002010 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002011 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002012 }
2013 }
2014 }
2015 }
2016
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002017 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002018 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002019 }
2020
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002021 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002022 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002023 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2024 }
2025 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002026
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002027 public void setFrontActivityScreenCompatMode(int mode) {
2028 synchronized (this) {
2029 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2030 }
2031 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002032
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002033 public int getPackageScreenCompatMode(String packageName) {
2034 synchronized (this) {
2035 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2036 }
2037 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002038
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002039 public void setPackageScreenCompatMode(String packageName, int mode) {
2040 synchronized (this) {
2041 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002042 }
2043 }
2044
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002045 public boolean getPackageAskScreenCompat(String packageName) {
2046 synchronized (this) {
2047 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2048 }
2049 }
2050
2051 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2052 synchronized (this) {
2053 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2054 }
2055 }
2056
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002057 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002058 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002059
2060 final int identHash = System.identityHashCode(r);
2061 updateUsageStats(r, true);
2062
2063 int i = mWatchers.beginBroadcast();
2064 while (i > 0) {
2065 i--;
2066 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2067 if (w != null) {
2068 try {
2069 w.activityResuming(identHash);
2070 } catch (RemoteException e) {
2071 }
2072 }
2073 }
2074 mWatchers.finishBroadcast();
2075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076
Jeff Sharkeya4620792011-05-20 15:29:23 -07002077 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2078 int i = mProcessObservers.beginBroadcast();
2079 while (i > 0) {
2080 i--;
2081 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2082 if (observer != null) {
2083 try {
2084 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2085 } catch (RemoteException e) {
2086 }
2087 }
2088 }
2089 mProcessObservers.finishBroadcast();
2090 }
2091
2092 private void dispatchProcessDied(int pid, int uid) {
2093 int i = mProcessObservers.beginBroadcast();
2094 while (i > 0) {
2095 i--;
2096 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2097 if (observer != null) {
2098 try {
2099 observer.onProcessDied(pid, uid);
2100 } catch (RemoteException e) {
2101 }
2102 }
2103 }
2104 mProcessObservers.finishBroadcast();
2105 }
2106
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002107 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002108 final int N = mPendingActivityLaunches.size();
2109 if (N <= 0) {
2110 return;
2111 }
2112 for (int i=0; i<N; i++) {
2113 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002114 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002115 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2116 doResume && i == (N-1));
2117 }
2118 mPendingActivityLaunches.clear();
2119 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002120
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002121 public final int startActivity(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002124 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2125 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
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, profileFile, profileFd, autoStopProfiler,
2129 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002130 }
2131
2132 public final WaitResult startActivityAndWait(IApplicationThread caller,
2133 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2134 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002135 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2136 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002137 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002138 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002139 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002140 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2141 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002142 return res;
2143 }
2144
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002145 public final int startActivityWithConfig(IApplicationThread caller,
2146 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2147 int grantedMode, IBinder resultTo,
2148 String resultWho, int requestCode, boolean onlyIfNeeded,
2149 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002150 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002151 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002152 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002153 }
2154
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002155 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002156 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002157 IBinder resultTo, String resultWho, int requestCode,
2158 int flagsMask, int flagsValues) {
2159 // Refuse possible leaked file descriptors
2160 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2161 throw new IllegalArgumentException("File descriptors passed in Intent");
2162 }
2163
2164 IIntentSender sender = intent.getTarget();
2165 if (!(sender instanceof PendingIntentRecord)) {
2166 throw new IllegalArgumentException("Bad PendingIntent object");
2167 }
2168
2169 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002170
2171 synchronized (this) {
2172 // If this is coming from the currently resumed activity, it is
2173 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002174 if (mMainStack.mResumedActivity != null
2175 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002176 Binder.getCallingUid()) {
2177 mAppSwitchesAllowedTime = 0;
2178 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002179 }
2180
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002181 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002182 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2183 }
2184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 public boolean startNextMatchingActivity(IBinder callingActivity,
2186 Intent intent) {
2187 // Refuse possible leaked file descriptors
2188 if (intent != null && intent.hasFileDescriptors() == true) {
2189 throw new IllegalArgumentException("File descriptors passed in Intent");
2190 }
2191
2192 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002193 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2194 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195 return false;
2196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 if (r.app == null || r.app.thread == null) {
2198 // The caller is not running... d'oh!
2199 return false;
2200 }
2201 intent = new Intent(intent);
2202 // The caller is not allowed to change the data.
2203 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2204 // And we are resetting to find the next component...
2205 intent.setComponent(null);
2206
2207 ActivityInfo aInfo = null;
2208 try {
2209 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002210 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002212 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213
2214 // Look for the original activity in the list...
2215 final int N = resolves != null ? resolves.size() : 0;
2216 for (int i=0; i<N; i++) {
2217 ResolveInfo rInfo = resolves.get(i);
2218 if (rInfo.activityInfo.packageName.equals(r.packageName)
2219 && rInfo.activityInfo.name.equals(r.info.name)) {
2220 // We found the current one... the next matching is
2221 // after it.
2222 i++;
2223 if (i<N) {
2224 aInfo = resolves.get(i).activityInfo;
2225 }
2226 break;
2227 }
2228 }
2229 } catch (RemoteException e) {
2230 }
2231
2232 if (aInfo == null) {
2233 // Nobody who is next!
2234 return false;
2235 }
2236
2237 intent.setComponent(new ComponentName(
2238 aInfo.applicationInfo.packageName, aInfo.name));
2239 intent.setFlags(intent.getFlags()&~(
2240 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2241 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2242 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2243 Intent.FLAG_ACTIVITY_NEW_TASK));
2244
2245 // Okay now we need to start the new activity, replacing the
2246 // currently running activity. This is a little tricky because
2247 // we want to start the new one as if the current one is finished,
2248 // but not finish the current one first so that there is no flicker.
2249 // And thus...
2250 final boolean wasFinishing = r.finishing;
2251 r.finishing = true;
2252
2253 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002254 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 final String resultWho = r.resultWho;
2256 final int requestCode = r.requestCode;
2257 r.resultTo = null;
2258 if (resultTo != null) {
2259 resultTo.removeResultsLocked(r, resultWho, requestCode);
2260 }
2261
2262 final long origId = Binder.clearCallingIdentity();
2263 // XXX we are not dealing with propagating grantedUriPermissions...
2264 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002265 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002267 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 Binder.restoreCallingIdentity(origId);
2269
2270 r.finishing = wasFinishing;
2271 if (res != START_SUCCESS) {
2272 return false;
2273 }
2274 return true;
2275 }
2276 }
2277
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002278 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 Intent intent, String resolvedType, IBinder resultTo,
2280 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002281
2282 // This is so super not safe, that only the system (or okay root)
2283 // can do it.
2284 final int callingUid = Binder.getCallingUid();
2285 if (callingUid != 0 && callingUid != Process.myUid()) {
2286 throw new SecurityException(
2287 "startActivityInPackage only available to the system");
2288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002290 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002291 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2292 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002293 }
2294
2295 public final int startActivities(IApplicationThread caller,
2296 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2297 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2298 }
2299
2300 public final int startActivitiesInPackage(int uid,
2301 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2302
2303 // This is so super not safe, that only the system (or okay root)
2304 // can do it.
2305 final int callingUid = Binder.getCallingUid();
2306 if (callingUid != 0 && callingUid != Process.myUid()) {
2307 throw new SecurityException(
2308 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 }
2310
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002311 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 }
2313
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002314 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002316 // Quick case: check if the top-most recent task is the same.
2317 if (N > 0 && mRecentTasks.get(0) == task) {
2318 return;
2319 }
2320 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 for (int i=0; i<N; i++) {
2322 TaskRecord tr = mRecentTasks.get(i);
2323 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2324 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2325 mRecentTasks.remove(i);
2326 i--;
2327 N--;
2328 if (task.intent == null) {
2329 // If the new recent task we are adding is not fully
2330 // specified, then replace it with the existing recent task.
2331 task = tr;
2332 }
2333 }
2334 }
2335 if (N >= MAX_RECENT_TASKS) {
2336 mRecentTasks.remove(N-1);
2337 }
2338 mRecentTasks.add(0, task);
2339 }
2340
2341 public void setRequestedOrientation(IBinder token,
2342 int requestedOrientation) {
2343 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002344 ActivityRecord r = mMainStack.isInStackLocked(token);
2345 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 return;
2347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 final long origId = Binder.clearCallingIdentity();
2349 mWindowManager.setAppOrientation(r, requestedOrientation);
2350 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002351 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 r.mayFreezeScreenLocked(r.app) ? r : null);
2353 if (config != null) {
2354 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002355 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002356 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 }
2358 }
2359 Binder.restoreCallingIdentity(origId);
2360 }
2361 }
2362
2363 public int getRequestedOrientation(IBinder token) {
2364 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002365 ActivityRecord r = mMainStack.isInStackLocked(token);
2366 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 return mWindowManager.getAppOrientation(r);
2370 }
2371 }
2372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 /**
2374 * This is the internal entry point for handling Activity.finish().
2375 *
2376 * @param token The Binder token referencing the Activity we want to finish.
2377 * @param resultCode Result code, if any, from this Activity.
2378 * @param resultData Result data (Intent), if any, from this Activity.
2379 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002380 * @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 -08002381 */
2382 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2383 // Refuse possible leaked file descriptors
2384 if (resultData != null && resultData.hasFileDescriptors() == true) {
2385 throw new IllegalArgumentException("File descriptors passed in Intent");
2386 }
2387
2388 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002389 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002391 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 if (next != null) {
2393 // ask watcher if this is allowed
2394 boolean resumeOK = true;
2395 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002396 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002398 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 }
2400
2401 if (!resumeOK) {
2402 return false;
2403 }
2404 }
2405 }
2406 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002407 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 resultData, "app-request");
2409 Binder.restoreCallingIdentity(origId);
2410 return res;
2411 }
2412 }
2413
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 public final void finishHeavyWeightApp() {
2415 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2416 != PackageManager.PERMISSION_GRANTED) {
2417 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2418 + Binder.getCallingPid()
2419 + ", uid=" + Binder.getCallingUid()
2420 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2421 Slog.w(TAG, msg);
2422 throw new SecurityException(msg);
2423 }
2424
2425 synchronized(this) {
2426 if (mHeavyWeightProcess == null) {
2427 return;
2428 }
2429
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002430 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002431 mHeavyWeightProcess.activities);
2432 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002433 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002434 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002435 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002436 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002437 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002438 null, "finish-heavy");
2439 }
2440 }
2441 }
2442
2443 mHeavyWeightProcess = null;
2444 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2445 }
2446 }
2447
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002448 public void crashApplication(int uid, int initialPid, String packageName,
2449 String message) {
2450 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2451 != PackageManager.PERMISSION_GRANTED) {
2452 String msg = "Permission Denial: crashApplication() from pid="
2453 + Binder.getCallingPid()
2454 + ", uid=" + Binder.getCallingUid()
2455 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2456 Slog.w(TAG, msg);
2457 throw new SecurityException(msg);
2458 }
2459
2460 synchronized(this) {
2461 ProcessRecord proc = null;
2462
2463 // Figure out which process to kill. We don't trust that initialPid
2464 // still has any relation to current pids, so must scan through the
2465 // list.
2466 synchronized (mPidsSelfLocked) {
2467 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2468 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2469 if (p.info.uid != uid) {
2470 continue;
2471 }
2472 if (p.pid == initialPid) {
2473 proc = p;
2474 break;
2475 }
2476 for (String str : p.pkgList) {
2477 if (str.equals(packageName)) {
2478 proc = p;
2479 }
2480 }
2481 }
2482 }
2483
2484 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002485 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002486 + " initialPid=" + initialPid
2487 + " packageName=" + packageName);
2488 return;
2489 }
2490
2491 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002492 if (proc.pid == Process.myPid()) {
2493 Log.w(TAG, "crashApplication: trying to crash self!");
2494 return;
2495 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002496 long ident = Binder.clearCallingIdentity();
2497 try {
2498 proc.thread.scheduleCrash(message);
2499 } catch (RemoteException e) {
2500 }
2501 Binder.restoreCallingIdentity(ident);
2502 }
2503 }
2504 }
2505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 public final void finishSubActivity(IBinder token, String resultWho,
2507 int requestCode) {
2508 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002509 ActivityRecord self = mMainStack.isInStackLocked(token);
2510 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 return;
2512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513
2514 final long origId = Binder.clearCallingIdentity();
2515
2516 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002517 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2518 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 if (r.resultTo == self && r.requestCode == requestCode) {
2520 if ((r.resultWho == null && resultWho == null) ||
2521 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 Activity.RESULT_CANCELED, null, "request-sub");
2524 }
2525 }
2526 }
2527
2528 Binder.restoreCallingIdentity(origId);
2529 }
2530 }
2531
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002532 public boolean willActivityBeVisible(IBinder token) {
2533 synchronized(this) {
2534 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002535 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2536 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002537 if (r == token) {
2538 return true;
2539 }
2540 if (r.fullscreen && !r.finishing) {
2541 return false;
2542 }
2543 }
2544 return true;
2545 }
2546 }
2547
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002548 public void overridePendingTransition(IBinder token, String packageName,
2549 int enterAnim, int exitAnim) {
2550 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002551 ActivityRecord self = mMainStack.isInStackLocked(token);
2552 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002553 return;
2554 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002555
2556 final long origId = Binder.clearCallingIdentity();
2557
2558 if (self.state == ActivityState.RESUMED
2559 || self.state == ActivityState.PAUSING) {
2560 mWindowManager.overridePendingAppTransition(packageName,
2561 enterAnim, exitAnim);
2562 }
2563
2564 Binder.restoreCallingIdentity(origId);
2565 }
2566 }
2567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 * Main function for removing an existing process from the activity manager
2570 * as a result of that process going away. Clears out all connections
2571 * to the process.
2572 */
2573 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002574 boolean restarting, boolean allowRestart) {
2575 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002577 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 }
2579
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002580 if (mProfileProc == app) {
2581 clearProfilerLocked();
2582 }
2583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002585 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2586 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2587 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002588 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002589 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2590 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 }
2592
2593 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595
2596 boolean atTop = true;
2597 boolean hasVisibleActivities = false;
2598
2599 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002600 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Removing app " + app + " from history with " + i + " entries");
2603 while (i > 0) {
2604 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002606 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2608 if (r.app == app) {
2609 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002610 if (ActivityStack.DEBUG_ADD_REMOVE) {
2611 RuntimeException here = new RuntimeException("here");
2612 here.fillInStackTrace();
2613 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2614 + ": haveState=" + r.haveState
2615 + " stateNotNeeded=" + r.stateNotNeeded
2616 + " finishing=" + r.finishing
2617 + " state=" + r.state, here);
2618 }
2619 if (!r.finishing) {
2620 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2621 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002622 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002623 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002624 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 mWindowManager.removeAppToken(r);
2626 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002627 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630
2631 } else {
2632 // We have the current state for this activity, so
2633 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002634 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002635 TAG, "Keeping entry, setting app to null");
2636 if (r.visible) {
2637 hasVisibleActivities = true;
2638 }
2639 r.app = null;
2640 r.nowVisible = false;
2641 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002642 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2643 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 r.icicle = null;
2645 }
2646 }
2647
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002648 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 }
2650 atTop = false;
2651 }
2652
2653 app.activities.clear();
2654
2655 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002656 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 + " running instrumentation " + app.instrumentationClass);
2658 Bundle info = new Bundle();
2659 info.putString("shortMsg", "Process crashed.");
2660 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2661 }
2662
2663 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002664 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 // If there was nothing to resume, and we are not already
2666 // restarting this process, but there is a visible activity that
2667 // is hosted by the process... then make sure all visible
2668 // activities are running, taking care of restarting this
2669 // process.
2670 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002671 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 }
2673 }
2674 }
2675 }
2676
2677 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2678 IBinder threadBinder = thread.asBinder();
2679
2680 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002681 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2682 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2684 return i;
2685 }
2686 }
2687 return -1;
2688 }
2689
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002690 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 IApplicationThread thread) {
2692 if (thread == null) {
2693 return null;
2694 }
2695
2696 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002697 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 }
2699
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002700 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 IApplicationThread thread) {
2702
2703 mProcDeaths[0]++;
2704
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002705 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2706 synchronized (stats) {
2707 stats.noteProcessDiedLocked(app.info.uid, pid);
2708 }
2709
Magnus Edlund7bb25812010-02-24 15:45:06 +01002710 // Clean up already done if the process has been re-started.
2711 if (app.pid == pid && app.thread != null &&
2712 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002713 if (!app.killedBackground) {
2714 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2715 + ") has died.");
2716 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002717 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002718 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 TAG, "Dying app: " + app + ", pid: " + pid
2720 + ", thread: " + thread.asBinder());
2721 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002722 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723
2724 if (doLowMem) {
2725 // If there are no longer any background processes running,
2726 // and the app that died was not running instrumentation,
2727 // then tell everyone we are now low on memory.
2728 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002729 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2730 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002731 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 haveBg = true;
2733 break;
2734 }
2735 }
2736
2737 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002738 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002739 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002740 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2741 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002742 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002743 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2744 // The low memory report is overriding any current
2745 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002746 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002747 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002748 rec.lastRequestedGc = 0;
2749 } else {
2750 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002752 rec.reportLowMemory = true;
2753 rec.lastLowMemory = now;
2754 mProcessesToGc.remove(rec);
2755 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 }
2757 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002758 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 }
2760 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002761 } else if (app.pid != pid) {
2762 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002764 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002765 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002766 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002767 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002768 + thread.asBinder());
2769 }
2770 }
2771
Dan Egnor42471dd2010-01-07 17:25:22 -08002772 /**
2773 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002774 * @param clearTraces causes the dump file to be erased prior to the new
2775 * traces being written, if true; when false, the new traces will be
2776 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002777 * @param firstPids of dalvik VM processes to dump stack traces for first
2778 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002779 * @return file containing stack traces, or null if no dump file is configured
2780 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002781 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2782 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002783 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2784 if (tracesPath == null || tracesPath.length() == 0) {
2785 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002786 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002787
2788 File tracesFile = new File(tracesPath);
2789 try {
2790 File tracesDir = tracesFile.getParentFile();
2791 if (!tracesDir.exists()) tracesFile.mkdirs();
2792 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2793
Christopher Tate6ee412d2010-05-28 12:01:56 -07002794 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002795 tracesFile.createNewFile();
2796 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2797 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002798 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002799 return null;
2800 }
2801
2802 // Use a FileObserver to detect when traces finish writing.
2803 // The order of traces is considered important to maintain for legibility.
2804 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2805 public synchronized void onEvent(int event, String path) { notify(); }
2806 };
2807
2808 try {
2809 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002810
2811 // First collect all of the stacks of the most important pids.
2812 try {
2813 int num = firstPids.size();
2814 for (int i = 0; i < num; i++) {
2815 synchronized (observer) {
2816 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2817 observer.wait(200); // Wait for write-close, give up after 200msec
2818 }
2819 }
2820 } catch (InterruptedException e) {
2821 Log.wtf(TAG, e);
2822 }
2823
2824 // Next measure CPU usage.
2825 if (processStats != null) {
2826 processStats.init();
2827 System.gc();
2828 processStats.update();
2829 try {
2830 synchronized (processStats) {
2831 processStats.wait(500); // measure over 1/2 second.
2832 }
2833 } catch (InterruptedException e) {
2834 }
2835 processStats.update();
2836
2837 // We'll take the stack crawls of just the top apps using CPU.
2838 final int N = processStats.countWorkingStats();
2839 int numProcs = 0;
2840 for (int i=0; i<N && numProcs<5; i++) {
2841 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2842 if (lastPids.indexOfKey(stats.pid) >= 0) {
2843 numProcs++;
2844 try {
2845 synchronized (observer) {
2846 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2847 observer.wait(200); // Wait for write-close, give up after 200msec
2848 }
2849 } catch (InterruptedException e) {
2850 Log.wtf(TAG, e);
2851 }
2852
2853 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002854 }
2855 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002856
2857 return tracesFile;
2858
Dan Egnor42471dd2010-01-07 17:25:22 -08002859 } finally {
2860 observer.stopWatching();
2861 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 }
2863
Jeff Brown4d94a762010-09-23 11:33:28 -07002864 private final class AppNotResponding implements Runnable {
2865 private final ProcessRecord mApp;
2866 private final String mAnnotation;
2867
2868 public AppNotResponding(ProcessRecord app, String annotation) {
2869 mApp = app;
2870 mAnnotation = annotation;
2871 }
2872
2873 @Override
2874 public void run() {
2875 appNotResponding(mApp, null, null, mAnnotation);
2876 }
2877 }
2878
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002879 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2880 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002881 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2882 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2883
Dianne Hackborn287952c2010-09-22 22:34:31 -07002884 if (mController != null) {
2885 try {
2886 // 0 == continue, -1 = kill process immediately
2887 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2888 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2889 } catch (RemoteException e) {
2890 mController = null;
2891 }
2892 }
2893
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002894 long anrTime = SystemClock.uptimeMillis();
2895 if (MONITOR_CPU_USAGE) {
2896 updateCpuStatsNow();
2897 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002898
2899 synchronized (this) {
2900 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2901 if (mShuttingDown) {
2902 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2903 return;
2904 } else if (app.notResponding) {
2905 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2906 return;
2907 } else if (app.crashing) {
2908 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2909 return;
2910 }
2911
2912 // In case we come through here for the same app before completing
2913 // this one, mark as anring now so we will bail out.
2914 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002915
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002916 // Log the ANR to the event log.
2917 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2918 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002919
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002920 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002921 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002922
2923 int parentPid = app.pid;
2924 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002925 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002926
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002927 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002928
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002929 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2930 ProcessRecord r = mLruProcesses.get(i);
2931 if (r != null && r.thread != null) {
2932 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002933 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2934 if (r.persistent) {
2935 firstPids.add(pid);
2936 } else {
2937 lastPids.put(pid, Boolean.TRUE);
2938 }
2939 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 }
2942 }
2943
Dan Egnor42471dd2010-01-07 17:25:22 -08002944 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002945 StringBuilder info = mStringBuilder;
2946 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002947 info.append("ANR in ").append(app.processName);
2948 if (activity != null && activity.shortComponentName != null) {
2949 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002950 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002951 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002953 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002955 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002956 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958
Dianne Hackborn287952c2010-09-22 22:34:31 -07002959 final ProcessStats processStats = new ProcessStats(true);
2960
2961 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2962
Dan Egnor42471dd2010-01-07 17:25:22 -08002963 String cpuInfo = null;
2964 if (MONITOR_CPU_USAGE) {
2965 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002966 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002967 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002968 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002969 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002970 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 }
2972
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002973 info.append(processStats.printCurrentState(anrTime));
2974
Joe Onorato8a9b2202010-02-26 18:56:32 -08002975 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002976 if (tracesFile == null) {
2977 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2978 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2979 }
2980
Jeff Sharkeya353d262011-10-28 11:12:06 -07002981 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
2982 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08002983
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002984 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002986 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2987 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002989 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2990 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 }
2992 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002993 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002994 }
2995 }
2996
Dan Egnor42471dd2010-01-07 17:25:22 -08002997 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2998 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2999 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003000
3001 synchronized (this) {
3002 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003003 Slog.w(TAG, "Killing " + app + ": background ANR");
3004 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3005 app.processName, app.setAdj, "background ANR");
3006 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003007 return;
3008 }
3009
3010 // Set the app's notResponding state, and look up the errorReportReceiver
3011 makeAppNotRespondingLocked(app,
3012 activity != null ? activity.shortComponentName : null,
3013 annotation != null ? "ANR " + annotation : "ANR",
3014 info.toString());
3015
3016 // Bring up the infamous App Not Responding dialog
3017 Message msg = Message.obtain();
3018 HashMap map = new HashMap();
3019 msg.what = SHOW_NOT_RESPONDING_MSG;
3020 msg.obj = map;
3021 map.put("app", app);
3022 if (activity != null) {
3023 map.put("activity", activity);
3024 }
3025
3026 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 }
3029
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003030 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3031 if (!mLaunchWarningShown) {
3032 mLaunchWarningShown = true;
3033 mHandler.post(new Runnable() {
3034 @Override
3035 public void run() {
3036 synchronized (ActivityManagerService.this) {
3037 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3038 d.show();
3039 mHandler.postDelayed(new Runnable() {
3040 @Override
3041 public void run() {
3042 synchronized (ActivityManagerService.this) {
3043 d.dismiss();
3044 mLaunchWarningShown = false;
3045 }
3046 }
3047 }, 4000);
3048 }
3049 }
3050 });
3051 }
3052 }
3053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 public boolean clearApplicationUserData(final String packageName,
3055 final IPackageDataObserver observer) {
3056 int uid = Binder.getCallingUid();
3057 int pid = Binder.getCallingPid();
3058 long callingId = Binder.clearCallingIdentity();
3059 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003060 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 int pkgUid = -1;
3062 synchronized(this) {
3063 try {
3064 pkgUid = pm.getPackageUid(packageName);
3065 } catch (RemoteException e) {
3066 }
3067 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003068 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 return false;
3070 }
3071 if (uid == pkgUid || checkComponentPermission(
3072 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003073 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003075 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 } else {
3077 throw new SecurityException(pid+" does not have permission:"+
3078 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3079 "for process:"+packageName);
3080 }
3081 }
3082
3083 try {
3084 //clear application user data
3085 pm.clearApplicationUserData(packageName, observer);
3086 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3087 Uri.fromParts("package", packageName, null));
3088 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003089 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3090 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 } catch (RemoteException e) {
3092 }
3093 } finally {
3094 Binder.restoreCallingIdentity(callingId);
3095 }
3096 return true;
3097 }
3098
Dianne Hackborn03abb812010-01-04 18:43:19 -08003099 public void killBackgroundProcesses(final String packageName) {
3100 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3101 != PackageManager.PERMISSION_GRANTED &&
3102 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3103 != PackageManager.PERMISSION_GRANTED) {
3104 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105 + Binder.getCallingPid()
3106 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003107 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003108 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003109 throw new SecurityException(msg);
3110 }
3111
3112 long callingId = Binder.clearCallingIdentity();
3113 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003114 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003115 int pkgUid = -1;
3116 synchronized(this) {
3117 try {
3118 pkgUid = pm.getPackageUid(packageName);
3119 } catch (RemoteException e) {
3120 }
3121 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003122 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 return;
3124 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003125 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003126 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003127 }
3128 } finally {
3129 Binder.restoreCallingIdentity(callingId);
3130 }
3131 }
3132
3133 public void forceStopPackage(final String packageName) {
3134 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3135 != PackageManager.PERMISSION_GRANTED) {
3136 String msg = "Permission Denial: forceStopPackage() from pid="
3137 + Binder.getCallingPid()
3138 + ", uid=" + Binder.getCallingUid()
3139 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003140 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003141 throw new SecurityException(msg);
3142 }
3143
3144 long callingId = Binder.clearCallingIdentity();
3145 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003146 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003147 int pkgUid = -1;
3148 synchronized(this) {
3149 try {
3150 pkgUid = pm.getPackageUid(packageName);
3151 } catch (RemoteException e) {
3152 }
3153 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003154 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003155 return;
3156 }
3157 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003158 try {
3159 pm.setPackageStoppedState(packageName, true);
3160 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003161 } catch (IllegalArgumentException e) {
3162 Slog.w(TAG, "Failed trying to unstop package "
3163 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003165 }
3166 } finally {
3167 Binder.restoreCallingIdentity(callingId);
3168 }
3169 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003170
3171 /*
3172 * The pkg name and uid have to be specified.
3173 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3174 */
3175 public void killApplicationWithUid(String pkg, int uid) {
3176 if (pkg == null) {
3177 return;
3178 }
3179 // Make sure the uid is valid.
3180 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003181 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003182 return;
3183 }
3184 int callerUid = Binder.getCallingUid();
3185 // Only the system server can kill an application
3186 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003187 // Post an aysnc message to kill the application
3188 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3189 msg.arg1 = uid;
3190 msg.arg2 = 0;
3191 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003192 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003193 } else {
3194 throw new SecurityException(callerUid + " cannot kill pkg: " +
3195 pkg);
3196 }
3197 }
3198
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003199 public void closeSystemDialogs(String reason) {
3200 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003201 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003202 if (reason != null) {
3203 intent.putExtra("reason", reason);
3204 }
3205
3206 final int uid = Binder.getCallingUid();
3207 final long origId = Binder.clearCallingIdentity();
3208 synchronized (this) {
3209 int i = mWatchers.beginBroadcast();
3210 while (i > 0) {
3211 i--;
3212 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3213 if (w != null) {
3214 try {
3215 w.closingSystemDialogs(reason);
3216 } catch (RemoteException e) {
3217 }
3218 }
3219 }
3220 mWatchers.finishBroadcast();
3221
Dianne Hackbornffa42482009-09-23 22:20:11 -07003222 mWindowManager.closeSystemDialogs(reason);
3223
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003224 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3225 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003226 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003227 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003228 Activity.RESULT_CANCELED, null, "close-sys");
3229 }
3230 }
3231
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003232 broadcastIntentLocked(null, null, intent, null,
3233 null, 0, null, null, null, false, false, -1, uid);
3234 }
3235 Binder.restoreCallingIdentity(origId);
3236 }
3237
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003238 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003239 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003240 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3241 for (int i=pids.length-1; i>=0; i--) {
3242 infos[i] = new Debug.MemoryInfo();
3243 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003244 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003245 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003246 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003247
Dianne Hackbornb437e092011-08-05 17:50:29 -07003248 public long[] getProcessPss(int[] pids) throws RemoteException {
3249 long[] pss = new long[pids.length];
3250 for (int i=pids.length-1; i>=0; i--) {
3251 pss[i] = Debug.getPss(pids[i]);
3252 }
3253 return pss;
3254 }
3255
Christopher Tate5e1ab332009-09-01 20:32:49 -07003256 public void killApplicationProcess(String processName, int uid) {
3257 if (processName == null) {
3258 return;
3259 }
3260
3261 int callerUid = Binder.getCallingUid();
3262 // Only the system server can kill an application
3263 if (callerUid == Process.SYSTEM_UID) {
3264 synchronized (this) {
3265 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003266 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003267 try {
3268 app.thread.scheduleSuicide();
3269 } catch (RemoteException e) {
3270 // If the other end already died, then our work here is done.
3271 }
3272 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003273 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003274 + processName + " / " + uid);
3275 }
3276 }
3277 } else {
3278 throw new SecurityException(callerUid + " cannot kill app process: " +
3279 processName);
3280 }
3281 }
3282
Dianne Hackborn03abb812010-01-04 18:43:19 -08003283 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003284 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3286 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003287 if (!mProcessesReady) {
3288 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003290 intent.putExtra(Intent.EXTRA_UID, uid);
3291 broadcastIntentLocked(null, null, intent,
3292 null, null, 0, null, null, null,
3293 false, false, MY_PID, Process.SYSTEM_UID);
3294 }
3295
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003296 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003297 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3298 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003299 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003300
Dianne Hackborn03abb812010-01-04 18:43:19 -08003301 // Remove all processes this package may have touched: all with the
3302 // same UID (except for the system or root user), and all whose name
3303 // matches the package name.
3304 final String procNamePrefix = packageName + ":";
3305 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3306 final int NA = apps.size();
3307 for (int ia=0; ia<NA; ia++) {
3308 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003309 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003310 // we don't kill persistent processes
3311 continue;
3312 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003313 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003314 if (doit) {
3315 procs.add(app);
3316 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003317 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3318 || app.processName.equals(packageName)
3319 || app.processName.startsWith(procNamePrefix)) {
3320 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003321 if (!doit) {
3322 return true;
3323 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003324 app.removed = true;
3325 procs.add(app);
3326 }
3327 }
3328 }
3329 }
3330
3331 int N = procs.size();
3332 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003333 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003334 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003335 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003336 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003337
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003338 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003339 boolean callerWillRestart, boolean purgeCache, boolean doit,
3340 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003341 int i;
3342 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 if (uid < 0) {
3345 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003346 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003347 } catch (RemoteException e) {
3348 }
3349 }
3350
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003351 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003352 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003353
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003354 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3355 while (badApps.hasNext()) {
3356 SparseArray<Long> ba = badApps.next();
3357 if (ba.get(uid) != null) {
3358 badApps.remove();
3359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 }
3361 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003362
3363 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003364 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003366 TaskRecord lastTask = null;
3367 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003368 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003369 final boolean samePackage = r.packageName.equals(name);
3370 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003371 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003372 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003373 if (r.finishing) {
3374 // If this activity is just finishing, then it is not
3375 // interesting as far as something to stop.
3376 continue;
3377 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003378 return true;
3379 }
3380 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003381 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003382 if (samePackage) {
3383 if (r.app != null) {
3384 r.app.removed = true;
3385 }
3386 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003388 lastTask = r.task;
3389 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3390 null, "force-stop")) {
3391 i--;
3392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 }
3394 }
3395
3396 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3397 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003398 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003399 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003400 if (!doit) {
3401 return true;
3402 }
3403 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003404 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 if (service.app != null) {
3406 service.app.removed = true;
3407 }
3408 service.app = null;
3409 services.add(service);
3410 }
3411 }
3412
3413 N = services.size();
3414 for (i=0; i<N; i++) {
3415 bringDownServiceLocked(services.get(i), true);
3416 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003417
3418 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3419 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3420 if (provider.info.packageName.equals(name)
3421 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3422 if (!doit) {
3423 return true;
3424 }
3425 didSomething = true;
3426 providers.add(provider);
3427 }
3428 }
3429
3430 N = providers.size();
3431 for (i=0; i<N; i++) {
3432 removeDyingProviderLocked(null, providers.get(i));
3433 }
3434
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003435 if (doit) {
3436 if (purgeCache) {
3437 AttributeCache ac = AttributeCache.instance();
3438 if (ac != null) {
3439 ac.removePackage(name);
3440 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003441 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003442 if (mBooted) {
3443 mMainStack.resumeTopActivityLocked(null);
3444 mMainStack.scheduleIdleLocked();
3445 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003446 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003447
3448 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 }
3450
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003451 private final boolean removeProcessLocked(ProcessRecord app,
3452 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003453 final String name = app.processName;
3454 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003455 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 TAG, "Force removing process " + app + " (" + name
3457 + "/" + uid + ")");
3458
3459 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003460 if (mHeavyWeightProcess == app) {
3461 mHeavyWeightProcess = null;
3462 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 boolean needRestart = false;
3465 if (app.pid > 0 && app.pid != MY_PID) {
3466 int pid = app.pid;
3467 synchronized (mPidsSelfLocked) {
3468 mPidsSelfLocked.remove(pid);
3469 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3470 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003471 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003472 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 Process.killProcess(pid);
3474
3475 if (app.persistent) {
3476 if (!callerWillRestart) {
3477 addAppLocked(app.info);
3478 } else {
3479 needRestart = true;
3480 }
3481 }
3482 } else {
3483 mRemovedProcesses.add(app);
3484 }
3485
3486 return needRestart;
3487 }
3488
3489 private final void processStartTimedOutLocked(ProcessRecord app) {
3490 final int pid = app.pid;
3491 boolean gone = false;
3492 synchronized (mPidsSelfLocked) {
3493 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3494 if (knownApp != null && knownApp.thread == null) {
3495 mPidsSelfLocked.remove(pid);
3496 gone = true;
3497 }
3498 }
3499
3500 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003501 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003502 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003503 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003504 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003505 if (mHeavyWeightProcess == app) {
3506 mHeavyWeightProcess = null;
3507 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3508 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003509 // Take care of any launching providers waiting for this process.
3510 checkAppInLaunchingProvidersLocked(app, true);
3511 // Take care of any services that are waiting for the process.
3512 for (int i=0; i<mPendingServices.size(); i++) {
3513 ServiceRecord sr = mPendingServices.get(i);
3514 if (app.info.uid == sr.appInfo.uid
3515 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003516 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003517 mPendingServices.remove(i);
3518 i--;
3519 bringDownServiceLocked(sr, true);
3520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003521 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003522 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3523 app.processName, app.setAdj, "start timeout");
3524 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003525 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003526 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003527 try {
3528 IBackupManager bm = IBackupManager.Stub.asInterface(
3529 ServiceManager.getService(Context.BACKUP_SERVICE));
3530 bm.agentDisconnected(app.info.packageName);
3531 } catch (RemoteException e) {
3532 // Can't happen; the backup manager is local
3533 }
3534 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003535 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003536 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003537 mPendingBroadcast.state = BroadcastRecord.IDLE;
3538 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003539 mPendingBroadcast = null;
3540 scheduleBroadcastsLocked();
3541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003543 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 }
3545 }
3546
3547 private final boolean attachApplicationLocked(IApplicationThread thread,
3548 int pid) {
3549
3550 // Find the application record that is being attached... either via
3551 // the pid if we are running in multiple processes, or just pull the
3552 // next app record if we are emulating process with anonymous threads.
3553 ProcessRecord app;
3554 if (pid != MY_PID && pid >= 0) {
3555 synchronized (mPidsSelfLocked) {
3556 app = mPidsSelfLocked.get(pid);
3557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 } else {
3559 app = null;
3560 }
3561
3562 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003563 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003564 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003565 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003567 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 } else {
3569 try {
3570 thread.scheduleExit();
3571 } catch (Exception e) {
3572 // Ignore exceptions.
3573 }
3574 }
3575 return false;
3576 }
3577
3578 // If this application record is still attached to a previous
3579 // process, clean it up now.
3580 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003581 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003582 }
3583
3584 // Tell the process all about itself.
3585
Joe Onorato8a9b2202010-02-26 18:56:32 -08003586 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003587 TAG, "Binding process pid " + pid + " to record " + app);
3588
3589 String processName = app.processName;
3590 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003591 AppDeathRecipient adr = new AppDeathRecipient(
3592 app, pid, thread);
3593 thread.asBinder().linkToDeath(adr, 0);
3594 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 } catch (RemoteException e) {
3596 app.resetPackageList();
3597 startProcessLocked(app, "link fail", processName);
3598 return false;
3599 }
3600
Doug Zongker2bec3d42009-12-04 12:52:44 -08003601 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602
3603 app.thread = thread;
3604 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003605 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3606 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 app.forcingToForeground = null;
3608 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003609 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 app.debugging = false;
3611
3612 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3613
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003614 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003615 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003617 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003618 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003619 }
3620
Joe Onorato8a9b2202010-02-26 18:56:32 -08003621 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 TAG, "New app record " + app
3623 + " thread=" + thread.asBinder() + " pid=" + pid);
3624 try {
3625 int testMode = IApplicationThread.DEBUG_OFF;
3626 if (mDebugApp != null && mDebugApp.equals(processName)) {
3627 testMode = mWaitForDebugger
3628 ? IApplicationThread.DEBUG_WAIT
3629 : IApplicationThread.DEBUG_ON;
3630 app.debugging = true;
3631 if (mDebugTransient) {
3632 mDebugApp = mOrigDebugApp;
3633 mWaitForDebugger = mOrigWaitForDebugger;
3634 }
3635 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003636 String profileFile = app.instrumentationProfileFile;
3637 ParcelFileDescriptor profileFd = null;
3638 boolean profileAutoStop = false;
3639 if (mProfileApp != null && mProfileApp.equals(processName)) {
3640 mProfileProc = app;
3641 profileFile = mProfileFile;
3642 profileFd = mProfileFd;
3643 profileAutoStop = mAutoStopProfiler;
3644 }
3645
Christopher Tate181fafa2009-05-14 11:12:14 -07003646 // If the app is being launched for restore or full backup, set it up specially
3647 boolean isRestrictedBackupMode = false;
3648 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3649 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003650 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003651 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3652 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003653
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003654 ensurePackageDexOpt(app.instrumentationInfo != null
3655 ? app.instrumentationInfo.packageName
3656 : app.info.packageName);
3657 if (app.instrumentationClass != null) {
3658 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003659 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003660 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003661 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003662 ApplicationInfo appInfo = app.instrumentationInfo != null
3663 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003664 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003665 if (profileFd != null) {
3666 profileFd = profileFd.dup();
3667 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003668 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003669 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003671 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003672 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003673 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003674 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003675 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 } catch (Exception e) {
3677 // todo: Yikes! What should we do? For now we will try to
3678 // start another process, but that could easily get us in
3679 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003680 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681
3682 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003683 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 startProcessLocked(app, "bind fail", processName);
3685 return false;
3686 }
3687
3688 // Remove this record from the list of starting applications.
3689 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003690 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3691 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 mProcessesOnHold.remove(app);
3693
3694 boolean badApp = false;
3695 boolean didSomething = false;
3696
3697 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003698 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003699 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003700 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3701 && processName.equals(hr.processName)) {
3702 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003703 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 didSomething = true;
3705 }
3706 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003707 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 + hr.intent.getComponent().flattenToShortString(), e);
3709 badApp = true;
3710 }
3711 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003712 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 }
3714 }
3715
3716 // Find any services that should be running in this process...
3717 if (!badApp && mPendingServices.size() > 0) {
3718 ServiceRecord sr = null;
3719 try {
3720 for (int i=0; i<mPendingServices.size(); i++) {
3721 sr = mPendingServices.get(i);
3722 if (app.info.uid != sr.appInfo.uid
3723 || !processName.equals(sr.processName)) {
3724 continue;
3725 }
3726
3727 mPendingServices.remove(i);
3728 i--;
3729 realStartServiceLocked(sr, app);
3730 didSomething = true;
3731 }
3732 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003733 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003734 + sr.shortName, e);
3735 badApp = true;
3736 }
3737 }
3738
3739 // Check if the next broadcast receiver is in this process...
3740 BroadcastRecord br = mPendingBroadcast;
3741 if (!badApp && br != null && br.curApp == app) {
3742 try {
3743 mPendingBroadcast = null;
3744 processCurBroadcastLocked(br, app);
3745 didSomething = true;
3746 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003747 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 + br.curComponent.flattenToShortString(), e);
3749 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003750 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003751 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3752 br.resultExtras, br.resultAbort, true);
3753 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003754 // We need to reset the state if we fails to start the receiver.
3755 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 }
3757 }
3758
Christopher Tate181fafa2009-05-14 11:12:14 -07003759 // Check whether the next backup agent is in this process...
3760 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003761 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003762 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003763 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003764 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3765 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3766 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003767 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003768 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003769 e.printStackTrace();
3770 }
3771 }
3772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 if (badApp) {
3774 // todo: Also need to kill application to deal with all
3775 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003776 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003777 return false;
3778 }
3779
3780 if (!didSomething) {
3781 updateOomAdjLocked();
3782 }
3783
3784 return true;
3785 }
3786
3787 public final void attachApplication(IApplicationThread thread) {
3788 synchronized (this) {
3789 int callingPid = Binder.getCallingPid();
3790 final long origId = Binder.clearCallingIdentity();
3791 attachApplicationLocked(thread, callingPid);
3792 Binder.restoreCallingIdentity(origId);
3793 }
3794 }
3795
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003796 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003798 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3799 if (stopProfiling) {
3800 synchronized (this) {
3801 if (mProfileProc == r.app) {
3802 if (mProfileFd != null) {
3803 try {
3804 mProfileFd.close();
3805 } catch (IOException e) {
3806 }
3807 clearProfilerLocked();
3808 }
3809 }
3810 }
3811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 Binder.restoreCallingIdentity(origId);
3813 }
3814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003816 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003817 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003818 mWindowManager.enableScreenAfterBoot();
3819 }
3820
Dianne Hackborn661cd522011-08-22 00:26:20 -07003821 public void showBootMessage(final CharSequence msg, final boolean always) {
3822 mWindowManager.showBootMessage(msg, always);
3823 }
3824
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003825 public void dismissKeyguardOnNextActivity() {
3826 synchronized (this) {
3827 mMainStack.dismissKeyguardOnNextActivityLocked();
3828 }
3829 }
3830
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003831 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003832 IntentFilter pkgFilter = new IntentFilter();
3833 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3834 pkgFilter.addDataScheme("package");
3835 mContext.registerReceiver(new BroadcastReceiver() {
3836 @Override
3837 public void onReceive(Context context, Intent intent) {
3838 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3839 if (pkgs != null) {
3840 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003841 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003842 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003843 setResultCode(Activity.RESULT_OK);
3844 return;
3845 }
3846 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003847 }
3848 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003849 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003850 }, pkgFilter);
3851
3852 synchronized (this) {
3853 // Ensure that any processes we had put on hold are now started
3854 // up.
3855 final int NP = mProcessesOnHold.size();
3856 if (NP > 0) {
3857 ArrayList<ProcessRecord> procs =
3858 new ArrayList<ProcessRecord>(mProcessesOnHold);
3859 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003860 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3861 + procs.get(ip));
3862 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003863 }
3864 }
3865
3866 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003867 // Start looking for apps that are abusing wake locks.
3868 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003869 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003870 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003871 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003872 broadcastIntentLocked(null, null,
3873 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3874 null, null, 0, null, null,
3875 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3876 false, false, MY_PID, Process.SYSTEM_UID);
3877 }
3878 }
3879 }
3880
3881 final void ensureBootCompleted() {
3882 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003883 boolean enableScreen;
3884 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003885 booting = mBooting;
3886 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003887 enableScreen = !mBooted;
3888 mBooted = true;
3889 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003890
3891 if (booting) {
3892 finishBooting();
3893 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003894
3895 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003896 enableScreenAfterBoot();
3897 }
3898 }
3899
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003900 public final void activityPaused(IBinder token) {
3901 final long origId = Binder.clearCallingIdentity();
3902 mMainStack.activityPaused(token, false);
3903 Binder.restoreCallingIdentity(origId);
3904 }
3905
3906 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3907 CharSequence description) {
3908 if (localLOGV) Slog.v(
3909 TAG, "Activity stopped: token=" + token);
3910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 // Refuse possible leaked file descriptors
3912 if (icicle != null && icicle.hasFileDescriptors()) {
3913 throw new IllegalArgumentException("File descriptors passed in Bundle");
3914 }
3915
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003916 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917
3918 final long origId = Binder.clearCallingIdentity();
3919
3920 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003921 r = mMainStack.isInStackLocked(token);
3922 if (r != null) {
3923 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924 }
3925 }
3926
3927 if (r != null) {
3928 sendPendingThumbnail(r, null, null, null, false);
3929 }
3930
3931 trimApplications();
3932
3933 Binder.restoreCallingIdentity(origId);
3934 }
3935
3936 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003937 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003938 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 }
3940
3941 public String getCallingPackage(IBinder token) {
3942 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003943 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003944 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 }
3946 }
3947
3948 public ComponentName getCallingActivity(IBinder token) {
3949 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003950 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 return r != null ? r.intent.getComponent() : null;
3952 }
3953 }
3954
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003955 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003956 ActivityRecord r = mMainStack.isInStackLocked(token);
3957 if (r == null) {
3958 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003960 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 }
3962
3963 public ComponentName getActivityClassForToken(IBinder token) {
3964 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003965 ActivityRecord r = mMainStack.isInStackLocked(token);
3966 if (r == null) {
3967 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003969 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 }
3971 }
3972
3973 public String getPackageForToken(IBinder token) {
3974 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003975 ActivityRecord r = mMainStack.isInStackLocked(token);
3976 if (r == null) {
3977 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003979 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 }
3981 }
3982
3983 public IIntentSender getIntentSender(int type,
3984 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003985 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003987 if (intents != null) {
3988 if (intents.length < 1) {
3989 throw new IllegalArgumentException("Intents array length must be >= 1");
3990 }
3991 for (int i=0; i<intents.length; i++) {
3992 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003993 if (intent != null) {
3994 if (intent.hasFileDescriptors()) {
3995 throw new IllegalArgumentException("File descriptors passed in Intent");
3996 }
3997 if (type == INTENT_SENDER_BROADCAST &&
3998 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3999 throw new IllegalArgumentException(
4000 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4001 }
4002 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004003 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004004 }
4005 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004006 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004007 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004008 }
4009 }
4010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 synchronized(this) {
4012 int callingUid = Binder.getCallingUid();
4013 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004014 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004015 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 .getPackageUid(packageName);
4017 if (uid != Binder.getCallingUid()) {
4018 String msg = "Permission Denial: getIntentSender() from pid="
4019 + Binder.getCallingPid()
4020 + ", uid=" + Binder.getCallingUid()
4021 + ", (need uid=" + uid + ")"
4022 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004023 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 throw new SecurityException(msg);
4025 }
4026 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004027
4028 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004029 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 } catch (RemoteException e) {
4032 throw new SecurityException(e);
4033 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004034 }
4035 }
4036
4037 IIntentSender getIntentSenderLocked(int type,
4038 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004039 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004040 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004041 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004042 activity = mMainStack.isInStackLocked(token);
4043 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004044 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004045 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004046 if (activity.finishing) {
4047 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004049 }
4050
4051 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4052 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4053 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4054 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4055 |PendingIntent.FLAG_UPDATE_CURRENT);
4056
4057 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4058 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004059 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004060 WeakReference<PendingIntentRecord> ref;
4061 ref = mIntentSenderRecords.get(key);
4062 PendingIntentRecord rec = ref != null ? ref.get() : null;
4063 if (rec != null) {
4064 if (!cancelCurrent) {
4065 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004066 if (rec.key.requestIntent != null) {
4067 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4068 }
4069 if (intents != null) {
4070 intents[intents.length-1] = rec.key.requestIntent;
4071 rec.key.allIntents = intents;
4072 rec.key.allResolvedTypes = resolvedTypes;
4073 } else {
4074 rec.key.allIntents = null;
4075 rec.key.allResolvedTypes = null;
4076 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 return rec;
4079 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004080 rec.canceled = true;
4081 mIntentSenderRecords.remove(key);
4082 }
4083 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 return rec;
4085 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004086 rec = new PendingIntentRecord(this, key, callingUid);
4087 mIntentSenderRecords.put(key, rec.ref);
4088 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4089 if (activity.pendingResults == null) {
4090 activity.pendingResults
4091 = new HashSet<WeakReference<PendingIntentRecord>>();
4092 }
4093 activity.pendingResults.add(rec.ref);
4094 }
4095 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 }
4097
4098 public void cancelIntentSender(IIntentSender sender) {
4099 if (!(sender instanceof PendingIntentRecord)) {
4100 return;
4101 }
4102 synchronized(this) {
4103 PendingIntentRecord rec = (PendingIntentRecord)sender;
4104 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004105 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004106 .getPackageUid(rec.key.packageName);
4107 if (uid != Binder.getCallingUid()) {
4108 String msg = "Permission Denial: cancelIntentSender() from pid="
4109 + Binder.getCallingPid()
4110 + ", uid=" + Binder.getCallingUid()
4111 + " is not allowed to cancel packges "
4112 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004113 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 throw new SecurityException(msg);
4115 }
4116 } catch (RemoteException e) {
4117 throw new SecurityException(e);
4118 }
4119 cancelIntentSenderLocked(rec, true);
4120 }
4121 }
4122
4123 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4124 rec.canceled = true;
4125 mIntentSenderRecords.remove(rec.key);
4126 if (cleanActivity && rec.key.activity != null) {
4127 rec.key.activity.pendingResults.remove(rec.ref);
4128 }
4129 }
4130
4131 public String getPackageForIntentSender(IIntentSender pendingResult) {
4132 if (!(pendingResult instanceof PendingIntentRecord)) {
4133 return null;
4134 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004135 try {
4136 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4137 return res.key.packageName;
4138 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004139 }
4140 return null;
4141 }
4142
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004143 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4144 if (!(pendingResult instanceof PendingIntentRecord)) {
4145 return false;
4146 }
4147 try {
4148 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4149 if (res.key.allIntents == null) {
4150 return false;
4151 }
4152 for (int i=0; i<res.key.allIntents.length; i++) {
4153 Intent intent = res.key.allIntents[i];
4154 if (intent.getPackage() != null && intent.getComponent() != null) {
4155 return false;
4156 }
4157 }
4158 return true;
4159 } catch (ClassCastException e) {
4160 }
4161 return false;
4162 }
4163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 public void setProcessLimit(int max) {
4165 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4166 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004167 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004168 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004169 mProcessLimitOverride = max;
4170 }
4171 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 }
4173
4174 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004175 synchronized (this) {
4176 return mProcessLimitOverride;
4177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004178 }
4179
4180 void foregroundTokenDied(ForegroundToken token) {
4181 synchronized (ActivityManagerService.this) {
4182 synchronized (mPidsSelfLocked) {
4183 ForegroundToken cur
4184 = mForegroundProcesses.get(token.pid);
4185 if (cur != token) {
4186 return;
4187 }
4188 mForegroundProcesses.remove(token.pid);
4189 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4190 if (pr == null) {
4191 return;
4192 }
4193 pr.forcingToForeground = null;
4194 pr.foregroundServices = false;
4195 }
4196 updateOomAdjLocked();
4197 }
4198 }
4199
4200 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4201 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4202 "setProcessForeground()");
4203 synchronized(this) {
4204 boolean changed = false;
4205
4206 synchronized (mPidsSelfLocked) {
4207 ProcessRecord pr = mPidsSelfLocked.get(pid);
4208 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004209 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004210 return;
4211 }
4212 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4213 if (oldToken != null) {
4214 oldToken.token.unlinkToDeath(oldToken, 0);
4215 mForegroundProcesses.remove(pid);
4216 pr.forcingToForeground = null;
4217 changed = true;
4218 }
4219 if (isForeground && token != null) {
4220 ForegroundToken newToken = new ForegroundToken() {
4221 public void binderDied() {
4222 foregroundTokenDied(this);
4223 }
4224 };
4225 newToken.pid = pid;
4226 newToken.token = token;
4227 try {
4228 token.linkToDeath(newToken, 0);
4229 mForegroundProcesses.put(pid, newToken);
4230 pr.forcingToForeground = token;
4231 changed = true;
4232 } catch (RemoteException e) {
4233 // If the process died while doing this, we will later
4234 // do the cleanup with the process death link.
4235 }
4236 }
4237 }
4238
4239 if (changed) {
4240 updateOomAdjLocked();
4241 }
4242 }
4243 }
4244
4245 // =========================================================
4246 // PERMISSIONS
4247 // =========================================================
4248
4249 static class PermissionController extends IPermissionController.Stub {
4250 ActivityManagerService mActivityManagerService;
4251 PermissionController(ActivityManagerService activityManagerService) {
4252 mActivityManagerService = activityManagerService;
4253 }
4254
4255 public boolean checkPermission(String permission, int pid, int uid) {
4256 return mActivityManagerService.checkPermission(permission, pid,
4257 uid) == PackageManager.PERMISSION_GRANTED;
4258 }
4259 }
4260
4261 /**
4262 * This can be called with or without the global lock held.
4263 */
4264 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004265 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004266 // We might be performing an operation on behalf of an indirect binder
4267 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4268 // client identity accordingly before proceeding.
4269 Identity tlsIdentity = sCallerIdentity.get();
4270 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004271 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4273 uid = tlsIdentity.uid;
4274 pid = tlsIdentity.pid;
4275 }
4276
4277 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004278 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 return PackageManager.PERMISSION_GRANTED;
4280 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004281 // If there is a uid that owns whatever is being accessed, it has
4282 // blanket access to it regardless of the permissions it requires.
4283 if (owningUid >= 0 && uid == owningUid) {
4284 return PackageManager.PERMISSION_GRANTED;
4285 }
4286 // If the target is not exported, then nobody else can get to it.
4287 if (!exported) {
4288 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 return PackageManager.PERMISSION_DENIED;
4290 }
4291 if (permission == null) {
4292 return PackageManager.PERMISSION_GRANTED;
4293 }
4294 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004295 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 .checkUidPermission(permission, uid);
4297 } catch (RemoteException e) {
4298 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004299 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 }
4301 return PackageManager.PERMISSION_DENIED;
4302 }
4303
4304 /**
4305 * As the only public entry point for permissions checking, this method
4306 * can enforce the semantic that requesting a check on a null global
4307 * permission is automatically denied. (Internally a null permission
4308 * string is used when calling {@link #checkComponentPermission} in cases
4309 * when only uid-based security is needed.)
4310 *
4311 * This can be called with or without the global lock held.
4312 */
4313 public int checkPermission(String permission, int pid, int uid) {
4314 if (permission == null) {
4315 return PackageManager.PERMISSION_DENIED;
4316 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004317 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 }
4319
4320 /**
4321 * Binder IPC calls go through the public entry point.
4322 * This can be called with or without the global lock held.
4323 */
4324 int checkCallingPermission(String permission) {
4325 return checkPermission(permission,
4326 Binder.getCallingPid(),
4327 Binder.getCallingUid());
4328 }
4329
4330 /**
4331 * This can be called with or without the global lock held.
4332 */
4333 void enforceCallingPermission(String permission, String func) {
4334 if (checkCallingPermission(permission)
4335 == PackageManager.PERMISSION_GRANTED) {
4336 return;
4337 }
4338
4339 String msg = "Permission Denial: " + func + " from pid="
4340 + Binder.getCallingPid()
4341 + ", uid=" + Binder.getCallingUid()
4342 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004343 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004344 throw new SecurityException(msg);
4345 }
4346
4347 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004348 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4349 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4350 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4351 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4352 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004354 // Is the component private from the target uid?
4355 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4356
4357 // Acceptable if the there is no read permission needed from the
4358 // target or the target is holding the read permission.
4359 if (!readPerm) {
4360 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004362 == PackageManager.PERMISSION_GRANTED)) {
4363 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004364 }
4365 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004366
4367 // Acceptable if the there is no write permission needed from the
4368 // target or the target is holding the read permission.
4369 if (!writePerm) {
4370 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004372 == PackageManager.PERMISSION_GRANTED)) {
4373 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 }
4375 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004376
4377 // Acceptable if there is a path permission matching the URI that
4378 // the target holds the permission on.
4379 PathPermission[] pps = pi.pathPermissions;
4380 if (pps != null && (!readPerm || !writePerm)) {
4381 final String path = uri.getPath();
4382 int i = pps.length;
4383 while (i > 0 && (!readPerm || !writePerm)) {
4384 i--;
4385 PathPermission pp = pps[i];
4386 if (!readPerm) {
4387 final String pprperm = pp.getReadPermission();
4388 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4389 + pprperm + " for " + pp.getPath()
4390 + ": match=" + pp.match(path)
4391 + " check=" + pm.checkUidPermission(pprperm, uid));
4392 if (pprperm != null && pp.match(path) &&
4393 (pm.checkUidPermission(pprperm, uid)
4394 == PackageManager.PERMISSION_GRANTED)) {
4395 readPerm = true;
4396 }
4397 }
4398 if (!writePerm) {
4399 final String ppwperm = pp.getWritePermission();
4400 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4401 + ppwperm + " for " + pp.getPath()
4402 + ": match=" + pp.match(path)
4403 + " check=" + pm.checkUidPermission(ppwperm, uid));
4404 if (ppwperm != null && pp.match(path) &&
4405 (pm.checkUidPermission(ppwperm, uid)
4406 == PackageManager.PERMISSION_GRANTED)) {
4407 writePerm = true;
4408 }
4409 }
4410 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004412 } catch (RemoteException e) {
4413 return false;
4414 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004415
4416 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 }
4418
4419 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4420 int modeFlags) {
4421 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004422 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 return true;
4424 }
4425 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4426 if (perms == null) return false;
4427 UriPermission perm = perms.get(uri);
4428 if (perm == null) return false;
4429 return (modeFlags&perm.modeFlags) == modeFlags;
4430 }
4431
4432 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4433 // Another redirected-binder-call permissions check as in
4434 // {@link checkComponentPermission}.
4435 Identity tlsIdentity = sCallerIdentity.get();
4436 if (tlsIdentity != null) {
4437 uid = tlsIdentity.uid;
4438 pid = tlsIdentity.pid;
4439 }
4440
4441 // Our own process gets to do everything.
4442 if (pid == MY_PID) {
4443 return PackageManager.PERMISSION_GRANTED;
4444 }
4445 synchronized(this) {
4446 return checkUriPermissionLocked(uri, uid, modeFlags)
4447 ? PackageManager.PERMISSION_GRANTED
4448 : PackageManager.PERMISSION_DENIED;
4449 }
4450 }
4451
Dianne Hackborn39792d22010-08-19 18:01:52 -07004452 /**
4453 * Check if the targetPkg can be granted permission to access uri by
4454 * the callingUid using the given modeFlags. Throws a security exception
4455 * if callingUid is not allowed to do this. Returns the uid of the target
4456 * if the URI permission grant should be performed; returns -1 if it is not
4457 * needed (for example targetPkg already has permission to access the URI).
4458 */
4459 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4460 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4462 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4463 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004464 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 }
4466
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004467 if (targetPkg != null) {
4468 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4469 "Checking grant " + targetPkg + " permission to " + uri);
4470 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004471
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004472 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473
4474 // If this is not a content: uri, we can't do anything with it.
4475 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004476 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004477 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004478 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 }
4480
4481 String name = uri.getAuthority();
4482 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004483 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 if (cpr != null) {
4485 pi = cpr.info;
4486 } else {
4487 try {
4488 pi = pm.resolveContentProvider(name,
4489 PackageManager.GET_URI_PERMISSION_PATTERNS);
4490 } catch (RemoteException ex) {
4491 }
4492 }
4493 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004494 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004495 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 }
4497
4498 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004499 if (targetPkg != null) {
4500 try {
4501 targetUid = pm.getPackageUid(targetPkg);
4502 if (targetUid < 0) {
4503 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4504 "Can't grant URI permission no uid for: " + targetPkg);
4505 return -1;
4506 }
4507 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004508 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004510 } else {
4511 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 }
4513
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004514 if (targetUid >= 0) {
4515 // First... does the target actually need this permission?
4516 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4517 // No need to grant the target this permission.
4518 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4519 "Target " + targetPkg + " already has full permission to " + uri);
4520 return -1;
4521 }
4522 } else {
4523 // First... there is no target package, so can anyone access it?
4524 boolean allowed = pi.exported;
4525 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4526 if (pi.readPermission != null) {
4527 allowed = false;
4528 }
4529 }
4530 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4531 if (pi.writePermission != null) {
4532 allowed = false;
4533 }
4534 }
4535 if (allowed) {
4536 return -1;
4537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 }
4539
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004540 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 if (!pi.grantUriPermissions) {
4542 throw new SecurityException("Provider " + pi.packageName
4543 + "/" + pi.name
4544 + " does not allow granting of Uri permissions (uri "
4545 + uri + ")");
4546 }
4547 if (pi.uriPermissionPatterns != null) {
4548 final int N = pi.uriPermissionPatterns.length;
4549 boolean allowed = false;
4550 for (int i=0; i<N; i++) {
4551 if (pi.uriPermissionPatterns[i] != null
4552 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4553 allowed = true;
4554 break;
4555 }
4556 }
4557 if (!allowed) {
4558 throw new SecurityException("Provider " + pi.packageName
4559 + "/" + pi.name
4560 + " does not allow granting of permission to path of Uri "
4561 + uri);
4562 }
4563 }
4564
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004565 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004567 if (callingUid != Process.myUid()) {
4568 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4569 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4570 throw new SecurityException("Uid " + callingUid
4571 + " does not have permission to uri " + uri);
4572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 }
4574 }
4575
Dianne Hackborn39792d22010-08-19 18:01:52 -07004576 return targetUid;
4577 }
4578
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004579 public int checkGrantUriPermission(int callingUid, String targetPkg,
4580 Uri uri, int modeFlags) {
4581 synchronized(this) {
4582 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4583 }
4584 }
4585
Dianne Hackborn39792d22010-08-19 18:01:52 -07004586 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4587 Uri uri, int modeFlags, UriPermissionOwner owner) {
4588 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4589 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4590 if (modeFlags == 0) {
4591 return;
4592 }
4593
4594 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 // to the uri, and the target doesn't. Let's now give this to
4596 // the target.
4597
Joe Onorato8a9b2202010-02-26 18:56:32 -08004598 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004599 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 HashMap<Uri, UriPermission> targetUris
4602 = mGrantedUriPermissions.get(targetUid);
4603 if (targetUris == null) {
4604 targetUris = new HashMap<Uri, UriPermission>();
4605 mGrantedUriPermissions.put(targetUid, targetUris);
4606 }
4607
4608 UriPermission perm = targetUris.get(uri);
4609 if (perm == null) {
4610 perm = new UriPermission(targetUid, uri);
4611 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004615 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004617 } else {
4618 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4619 perm.readOwners.add(owner);
4620 owner.addReadPermission(perm);
4621 }
4622 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4623 perm.writeOwners.add(owner);
4624 owner.addWritePermission(perm);
4625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627 }
4628
Dianne Hackborn39792d22010-08-19 18:01:52 -07004629 void grantUriPermissionLocked(int callingUid,
4630 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004631 if (targetPkg == null) {
4632 throw new NullPointerException("targetPkg");
4633 }
4634
Dianne Hackborn39792d22010-08-19 18:01:52 -07004635 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4636 if (targetUid < 0) {
4637 return;
4638 }
4639
4640 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4641 }
4642
4643 /**
4644 * Like checkGrantUriPermissionLocked, but takes an Intent.
4645 */
4646 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4647 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004648 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004649 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004650 + " from " + intent + "; flags=0x"
4651 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4652
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004653 if (targetPkg == null) {
4654 throw new NullPointerException("targetPkg");
4655 }
4656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004658 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 }
4660 Uri data = intent.getData();
4661 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004662 return -1;
4663 }
4664 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4665 intent.getFlags());
4666 }
4667
4668 /**
4669 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4670 */
4671 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4672 String targetPkg, Intent intent, UriPermissionOwner owner) {
4673 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4674 intent.getFlags(), owner);
4675 }
4676
4677 void grantUriPermissionFromIntentLocked(int callingUid,
4678 String targetPkg, Intent intent, UriPermissionOwner owner) {
4679 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4680 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 return;
4682 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004683
4684 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004685 }
4686
4687 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4688 Uri uri, int modeFlags) {
4689 synchronized(this) {
4690 final ProcessRecord r = getRecordForAppLocked(caller);
4691 if (r == null) {
4692 throw new SecurityException("Unable to find app for caller "
4693 + caller
4694 + " when granting permission to uri " + uri);
4695 }
4696 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004697 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004698 }
4699 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004700 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 }
4702
4703 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4704 null);
4705 }
4706 }
4707
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004708 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4710 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4711 HashMap<Uri, UriPermission> perms
4712 = mGrantedUriPermissions.get(perm.uid);
4713 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004714 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004715 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004716 perms.remove(perm.uri);
4717 if (perms.size() == 0) {
4718 mGrantedUriPermissions.remove(perm.uid);
4719 }
4720 }
4721 }
4722 }
4723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004724 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4725 int modeFlags) {
4726 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4727 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4728 if (modeFlags == 0) {
4729 return;
4730 }
4731
Joe Onorato8a9b2202010-02-26 18:56:32 -08004732 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004733 "Revoking all granted permissions to " + uri);
4734
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004735 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736
4737 final String authority = uri.getAuthority();
4738 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004739 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 if (cpr != null) {
4741 pi = cpr.info;
4742 } else {
4743 try {
4744 pi = pm.resolveContentProvider(authority,
4745 PackageManager.GET_URI_PERMISSION_PATTERNS);
4746 } catch (RemoteException ex) {
4747 }
4748 }
4749 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004750 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 return;
4752 }
4753
4754 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004755 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 // Right now, if you are not the original owner of the permission,
4757 // you are not allowed to revoke it.
4758 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4759 throw new SecurityException("Uid " + callingUid
4760 + " does not have permission to uri " + uri);
4761 //}
4762 }
4763
4764 // Go through all of the permissions and remove any that match.
4765 final List<String> SEGMENTS = uri.getPathSegments();
4766 if (SEGMENTS != null) {
4767 final int NS = SEGMENTS.size();
4768 int N = mGrantedUriPermissions.size();
4769 for (int i=0; i<N; i++) {
4770 HashMap<Uri, UriPermission> perms
4771 = mGrantedUriPermissions.valueAt(i);
4772 Iterator<UriPermission> it = perms.values().iterator();
4773 toploop:
4774 while (it.hasNext()) {
4775 UriPermission perm = it.next();
4776 Uri targetUri = perm.uri;
4777 if (!authority.equals(targetUri.getAuthority())) {
4778 continue;
4779 }
4780 List<String> targetSegments = targetUri.getPathSegments();
4781 if (targetSegments == null) {
4782 continue;
4783 }
4784 if (targetSegments.size() < NS) {
4785 continue;
4786 }
4787 for (int j=0; j<NS; j++) {
4788 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4789 continue toploop;
4790 }
4791 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004792 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004793 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 perm.clearModes(modeFlags);
4795 if (perm.modeFlags == 0) {
4796 it.remove();
4797 }
4798 }
4799 if (perms.size() == 0) {
4800 mGrantedUriPermissions.remove(
4801 mGrantedUriPermissions.keyAt(i));
4802 N--;
4803 i--;
4804 }
4805 }
4806 }
4807 }
4808
4809 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4810 int modeFlags) {
4811 synchronized(this) {
4812 final ProcessRecord r = getRecordForAppLocked(caller);
4813 if (r == null) {
4814 throw new SecurityException("Unable to find app for caller "
4815 + caller
4816 + " when revoking permission to uri " + uri);
4817 }
4818 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004819 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004820 return;
4821 }
4822
4823 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4824 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4825 if (modeFlags == 0) {
4826 return;
4827 }
4828
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004829 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830
4831 final String authority = uri.getAuthority();
4832 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004833 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 if (cpr != null) {
4835 pi = cpr.info;
4836 } else {
4837 try {
4838 pi = pm.resolveContentProvider(authority,
4839 PackageManager.GET_URI_PERMISSION_PATTERNS);
4840 } catch (RemoteException ex) {
4841 }
4842 }
4843 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004844 Slog.w(TAG, "No content provider found for permission revoke: "
4845 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 return;
4847 }
4848
4849 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4850 }
4851 }
4852
Dianne Hackborn7e269642010-08-25 19:50:20 -07004853 @Override
4854 public IBinder newUriPermissionOwner(String name) {
4855 synchronized(this) {
4856 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4857 return owner.getExternalTokenLocked();
4858 }
4859 }
4860
4861 @Override
4862 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4863 Uri uri, int modeFlags) {
4864 synchronized(this) {
4865 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4866 if (owner == null) {
4867 throw new IllegalArgumentException("Unknown owner: " + token);
4868 }
4869 if (fromUid != Binder.getCallingUid()) {
4870 if (Binder.getCallingUid() != Process.myUid()) {
4871 // Only system code can grant URI permissions on behalf
4872 // of other users.
4873 throw new SecurityException("nice try");
4874 }
4875 }
4876 if (targetPkg == null) {
4877 throw new IllegalArgumentException("null target");
4878 }
4879 if (uri == null) {
4880 throw new IllegalArgumentException("null uri");
4881 }
4882
4883 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4884 }
4885 }
4886
4887 @Override
4888 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4889 synchronized(this) {
4890 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4891 if (owner == null) {
4892 throw new IllegalArgumentException("Unknown owner: " + token);
4893 }
4894
4895 if (uri == null) {
4896 owner.removeUriPermissionsLocked(mode);
4897 } else {
4898 owner.removeUriPermissionLocked(uri, mode);
4899 }
4900 }
4901 }
4902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4904 synchronized (this) {
4905 ProcessRecord app =
4906 who != null ? getRecordForAppLocked(who) : null;
4907 if (app == null) return;
4908
4909 Message msg = Message.obtain();
4910 msg.what = WAIT_FOR_DEBUGGER_MSG;
4911 msg.obj = app;
4912 msg.arg1 = waiting ? 1 : 0;
4913 mHandler.sendMessage(msg);
4914 }
4915 }
4916
4917 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004918 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4919 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004920 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004921 outInfo.threshold = homeAppMem;
4922 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4923 outInfo.hiddenAppThreshold = hiddenAppMem;
4924 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4925 ProcessList.SECONDARY_SERVER_ADJ);
4926 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4927 ProcessList.VISIBLE_APP_ADJ);
4928 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4929 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930 }
4931
4932 // =========================================================
4933 // TASK MANAGEMENT
4934 // =========================================================
4935
4936 public List getTasks(int maxNum, int flags,
4937 IThumbnailReceiver receiver) {
4938 ArrayList list = new ArrayList();
4939
4940 PendingThumbnailsRecord pending = null;
4941 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004942 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943
4944 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004945 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004946 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4947 + ", receiver=" + receiver);
4948
4949 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4950 != PackageManager.PERMISSION_GRANTED) {
4951 if (receiver != null) {
4952 // If the caller wants to wait for pending thumbnails,
4953 // it ain't gonna get them.
4954 try {
4955 receiver.finished();
4956 } catch (RemoteException ex) {
4957 }
4958 }
4959 String msg = "Permission Denial: getTasks() from pid="
4960 + Binder.getCallingPid()
4961 + ", uid=" + Binder.getCallingUid()
4962 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004963 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 throw new SecurityException(msg);
4965 }
4966
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004967 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004968 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004969 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004970 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 TaskRecord curTask = null;
4972 int numActivities = 0;
4973 int numRunning = 0;
4974 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004975 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004977 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978
4979 // Initialize state for next task if needed.
4980 if (top == null ||
4981 (top.state == ActivityState.INITIALIZING
4982 && top.task == r.task)) {
4983 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004984 curTask = r.task;
4985 numActivities = numRunning = 0;
4986 }
4987
4988 // Add 'r' into the current task.
4989 numActivities++;
4990 if (r.app != null && r.app.thread != null) {
4991 numRunning++;
4992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993
Joe Onorato8a9b2202010-02-26 18:56:32 -08004994 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 TAG, r.intent.getComponent().flattenToShortString()
4996 + ": task=" + r.task);
4997
4998 // If the next one is a different task, generate a new
4999 // TaskInfo entry for what we have.
5000 if (next == null || next.task != curTask) {
5001 ActivityManager.RunningTaskInfo ci
5002 = new ActivityManager.RunningTaskInfo();
5003 ci.id = curTask.taskId;
5004 ci.baseActivity = r.intent.getComponent();
5005 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005006 if (top.thumbHolder != null) {
5007 ci.description = top.thumbHolder.lastDescription;
5008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005009 ci.numActivities = numActivities;
5010 ci.numRunning = numRunning;
5011 //System.out.println(
5012 // "#" + maxNum + ": " + " descr=" + ci.description);
5013 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005014 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005015 TAG, "State=" + top.state + "Idle=" + top.idle
5016 + " app=" + top.app
5017 + " thr=" + (top.app != null ? top.app.thread : null));
5018 if (top.state == ActivityState.RESUMED
5019 || top.state == ActivityState.PAUSING) {
5020 if (top.idle && top.app != null
5021 && top.app.thread != null) {
5022 topRecord = top;
5023 topThumbnail = top.app.thread;
5024 } else {
5025 top.thumbnailNeeded = true;
5026 }
5027 }
5028 if (pending == null) {
5029 pending = new PendingThumbnailsRecord(receiver);
5030 }
5031 pending.pendingRecords.add(top);
5032 }
5033 list.add(ci);
5034 maxNum--;
5035 top = null;
5036 }
5037 }
5038
5039 if (pending != null) {
5040 mPendingThumbnails.add(pending);
5041 }
5042 }
5043
Joe Onorato8a9b2202010-02-26 18:56:32 -08005044 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045
5046 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005047 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005048 try {
5049 topThumbnail.requestThumbnail(topRecord);
5050 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005051 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 sendPendingThumbnail(null, topRecord, null, null, true);
5053 }
5054 }
5055
5056 if (pending == null && receiver != null) {
5057 // In this case all thumbnails were available and the client
5058 // is being asked to be told when the remaining ones come in...
5059 // which is unusually, since the top-most currently running
5060 // activity should never have a canned thumbnail! Oh well.
5061 try {
5062 receiver.finished();
5063 } catch (RemoteException ex) {
5064 }
5065 }
5066
5067 return list;
5068 }
5069
5070 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5071 int flags) {
5072 synchronized (this) {
5073 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5074 "getRecentTasks()");
5075
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005076 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 final int N = mRecentTasks.size();
5079 ArrayList<ActivityManager.RecentTaskInfo> res
5080 = new ArrayList<ActivityManager.RecentTaskInfo>(
5081 maxNum < N ? maxNum : N);
5082 for (int i=0; i<N && maxNum > 0; i++) {
5083 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005084 // Return the entry if desired by the caller. We always return
5085 // the first entry, because callers always expect this to be the
5086 // forground app. We may filter others if the caller has
5087 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5088 // we should exclude the entry.
5089 if (i == 0
5090 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 || (tr.intent == null)
5092 || ((tr.intent.getFlags()
5093 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5094 ActivityManager.RecentTaskInfo rti
5095 = new ActivityManager.RecentTaskInfo();
5096 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005097 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005098 rti.baseIntent = new Intent(
5099 tr.intent != null ? tr.intent : tr.affinityIntent);
5100 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005101 rti.description = tr.lastDescription;
5102
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005103 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5104 // Check whether this activity is currently available.
5105 try {
5106 if (rti.origActivity != null) {
5107 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5108 continue;
5109 }
5110 } else if (rti.baseIntent != null) {
5111 if (pm.queryIntentActivities(rti.baseIntent,
5112 null, 0) == null) {
5113 continue;
5114 }
5115 }
5116 } catch (RemoteException e) {
5117 // Will never happen.
5118 }
5119 }
5120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005121 res.add(rti);
5122 maxNum--;
5123 }
5124 }
5125 return res;
5126 }
5127 }
5128
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005129 private TaskRecord taskForIdLocked(int id) {
5130 final int N = mRecentTasks.size();
5131 for (int i=0; i<N; i++) {
5132 TaskRecord tr = mRecentTasks.get(i);
5133 if (tr.taskId == id) {
5134 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005135 }
5136 }
5137 return null;
5138 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005139
5140 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5141 synchronized (this) {
5142 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5143 "getTaskThumbnails()");
5144 TaskRecord tr = taskForIdLocked(id);
5145 if (tr != null) {
5146 return mMainStack.getTaskThumbnailsLocked(tr);
5147 }
5148 }
5149 return null;
5150 }
5151
5152 public boolean removeSubTask(int taskId, int subTaskIndex) {
5153 synchronized (this) {
5154 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5155 "removeSubTask()");
5156 long ident = Binder.clearCallingIdentity();
5157 try {
5158 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5159 } finally {
5160 Binder.restoreCallingIdentity(ident);
5161 }
5162 }
5163 }
5164
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005165 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005166 TaskRecord tr = root.task;
5167 Intent baseIntent = new Intent(
5168 tr.intent != null ? tr.intent : tr.affinityIntent);
5169 ComponentName component = baseIntent.getComponent();
5170 if (component == null) {
5171 Slog.w(TAG, "Now component for base intent of task: " + tr);
5172 return;
5173 }
5174
5175 // Find any running services associated with this app.
5176 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5177 for (ServiceRecord sr : mServices.values()) {
5178 if (sr.packageName.equals(component.getPackageName())) {
5179 services.add(sr);
5180 }
5181 }
5182
5183 // Take care of any running services associated with the app.
5184 for (int i=0; i<services.size(); i++) {
5185 ServiceRecord sr = services.get(i);
5186 if (sr.startRequested) {
5187 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005188 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005189 stopServiceLocked(sr);
5190 } else {
5191 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5192 sr.makeNextStartId(), baseIntent, -1));
5193 if (sr.app != null && sr.app.thread != null) {
5194 sendServiceArgsLocked(sr, false);
5195 }
5196 }
5197 }
5198 }
5199
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005200 if (killProcesses) {
5201 // Find any running processes associated with this app.
5202 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5203 SparseArray<ProcessRecord> appProcs
5204 = mProcessNames.getMap().get(component.getPackageName());
5205 if (appProcs != null) {
5206 for (int i=0; i<appProcs.size(); i++) {
5207 procs.add(appProcs.valueAt(i));
5208 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005209 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005210
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005211 // Kill the running processes.
5212 for (int i=0; i<procs.size(); i++) {
5213 ProcessRecord pr = procs.get(i);
5214 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5215 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5216 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5217 pr.processName, pr.setAdj, "remove task");
5218 Process.killProcessQuiet(pr.pid);
5219 } else {
5220 pr.waitingToKill = "remove task";
5221 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005222 }
5223 }
5224 }
5225
5226 public boolean removeTask(int taskId, int flags) {
5227 synchronized (this) {
5228 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5229 "removeTask()");
5230 long ident = Binder.clearCallingIdentity();
5231 try {
5232 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5233 if (r != null) {
5234 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005235 cleanUpRemovedTaskLocked(r,
5236 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005237 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005238 } else {
5239 TaskRecord tr = null;
5240 int i=0;
5241 while (i < mRecentTasks.size()) {
5242 TaskRecord t = mRecentTasks.get(i);
5243 if (t.taskId == taskId) {
5244 tr = t;
5245 break;
5246 }
5247 i++;
5248 }
5249 if (tr != null) {
5250 if (tr.numActivities <= 0) {
5251 // Caller is just removing a recent task that is
5252 // not actively running. That is easy!
5253 mRecentTasks.remove(i);
5254 } else {
5255 Slog.w(TAG, "removeTask: task " + taskId
5256 + " does not have activities to remove, "
5257 + " but numActivities=" + tr.numActivities
5258 + ": " + tr);
5259 }
5260 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005261 }
5262 } finally {
5263 Binder.restoreCallingIdentity(ident);
5264 }
5265 }
5266 return false;
5267 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005269 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5270 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005271 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 TaskRecord jt = startTask;
5273
5274 // First look backwards
5275 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005276 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005277 if (r.task != jt) {
5278 jt = r.task;
5279 if (affinity.equals(jt.affinity)) {
5280 return j;
5281 }
5282 }
5283 }
5284
5285 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005286 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 jt = startTask;
5288 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005289 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 if (r.task != jt) {
5291 if (affinity.equals(jt.affinity)) {
5292 return j;
5293 }
5294 jt = r.task;
5295 }
5296 }
5297
5298 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005299 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005300 return N-1;
5301 }
5302
5303 return -1;
5304 }
5305
5306 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005307 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005308 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005309 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005310 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5311 "moveTaskToFront()");
5312
5313 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005314 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5315 Binder.getCallingUid(), "Task to front")) {
5316 return;
5317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 final long origId = Binder.clearCallingIdentity();
5319 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005320 TaskRecord tr = taskForIdLocked(task);
5321 if (tr != null) {
5322 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5323 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005325 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5326 // Caller wants the home activity moved with it. To accomplish this,
5327 // we'll just move the home task to the top first.
5328 mMainStack.moveHomeToFrontLocked();
5329 }
5330 mMainStack.moveTaskToFrontLocked(tr, null);
5331 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005332 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005333 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5334 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005336 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5337 mMainStack.mUserLeaving = true;
5338 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005339 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5340 // Caller wants the home activity moved with it. To accomplish this,
5341 // we'll just move the home task to the top first.
5342 mMainStack.moveHomeToFrontLocked();
5343 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005344 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 return;
5346 }
5347 }
5348 } finally {
5349 Binder.restoreCallingIdentity(origId);
5350 }
5351 }
5352 }
5353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005354 public void moveTaskToBack(int task) {
5355 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5356 "moveTaskToBack()");
5357
5358 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005359 if (mMainStack.mResumedActivity != null
5360 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005361 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5362 Binder.getCallingUid(), "Task to back")) {
5363 return;
5364 }
5365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005367 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005368 Binder.restoreCallingIdentity(origId);
5369 }
5370 }
5371
5372 /**
5373 * Moves an activity, and all of the other activities within the same task, to the bottom
5374 * of the history stack. The activity's order within the task is unchanged.
5375 *
5376 * @param token A reference to the activity we wish to move
5377 * @param nonRoot If false then this only works if the activity is the root
5378 * of a task; if true it will work for any activity in a task.
5379 * @return Returns true if the move completed, false if not.
5380 */
5381 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5382 synchronized(this) {
5383 final long origId = Binder.clearCallingIdentity();
5384 int taskId = getTaskForActivityLocked(token, !nonRoot);
5385 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005386 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005387 }
5388 Binder.restoreCallingIdentity(origId);
5389 }
5390 return false;
5391 }
5392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 public void moveTaskBackwards(int task) {
5394 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5395 "moveTaskBackwards()");
5396
5397 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005398 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5399 Binder.getCallingUid(), "Task backwards")) {
5400 return;
5401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005402 final long origId = Binder.clearCallingIdentity();
5403 moveTaskBackwardsLocked(task);
5404 Binder.restoreCallingIdentity(origId);
5405 }
5406 }
5407
5408 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005409 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 }
5411
5412 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5413 synchronized(this) {
5414 return getTaskForActivityLocked(token, onlyRoot);
5415 }
5416 }
5417
5418 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005419 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 TaskRecord lastTask = null;
5421 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005422 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 if (r == token) {
5424 if (!onlyRoot || lastTask != r.task) {
5425 return r.task.taskId;
5426 }
5427 return -1;
5428 }
5429 lastTask = r.task;
5430 }
5431
5432 return -1;
5433 }
5434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005435 public void finishOtherInstances(IBinder token, ComponentName className) {
5436 synchronized(this) {
5437 final long origId = Binder.clearCallingIdentity();
5438
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005439 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005440 TaskRecord lastTask = null;
5441 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005442 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005443 if (r.realActivity.equals(className)
5444 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005445 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 null, "others")) {
5447 i--;
5448 N--;
5449 }
5450 }
5451 lastTask = r.task;
5452 }
5453
5454 Binder.restoreCallingIdentity(origId);
5455 }
5456 }
5457
5458 // =========================================================
5459 // THUMBNAILS
5460 // =========================================================
5461
5462 public void reportThumbnail(IBinder token,
5463 Bitmap thumbnail, CharSequence description) {
5464 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5465 final long origId = Binder.clearCallingIdentity();
5466 sendPendingThumbnail(null, token, thumbnail, description, true);
5467 Binder.restoreCallingIdentity(origId);
5468 }
5469
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005470 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005471 Bitmap thumbnail, CharSequence description, boolean always) {
5472 TaskRecord task = null;
5473 ArrayList receivers = null;
5474
5475 //System.out.println("Send pending thumbnail: " + r);
5476
5477 synchronized(this) {
5478 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005479 r = mMainStack.isInStackLocked(token);
5480 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005481 return;
5482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005483 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005484 if (thumbnail == null && r.thumbHolder != null) {
5485 thumbnail = r.thumbHolder.lastThumbnail;
5486 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487 }
5488 if (thumbnail == null && !always) {
5489 // If there is no thumbnail, and this entry is not actually
5490 // going away, then abort for now and pick up the next
5491 // thumbnail we get.
5492 return;
5493 }
5494 task = r.task;
5495
5496 int N = mPendingThumbnails.size();
5497 int i=0;
5498 while (i<N) {
5499 PendingThumbnailsRecord pr =
5500 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5501 //System.out.println("Looking in " + pr.pendingRecords);
5502 if (pr.pendingRecords.remove(r)) {
5503 if (receivers == null) {
5504 receivers = new ArrayList();
5505 }
5506 receivers.add(pr);
5507 if (pr.pendingRecords.size() == 0) {
5508 pr.finished = true;
5509 mPendingThumbnails.remove(i);
5510 N--;
5511 continue;
5512 }
5513 }
5514 i++;
5515 }
5516 }
5517
5518 if (receivers != null) {
5519 final int N = receivers.size();
5520 for (int i=0; i<N; i++) {
5521 try {
5522 PendingThumbnailsRecord pr =
5523 (PendingThumbnailsRecord)receivers.get(i);
5524 pr.receiver.newThumbnail(
5525 task != null ? task.taskId : -1, thumbnail, description);
5526 if (pr.finished) {
5527 pr.receiver.finished();
5528 }
5529 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005530 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 }
5532 }
5533 }
5534 }
5535
5536 // =========================================================
5537 // CONTENT PROVIDERS
5538 // =========================================================
5539
Jeff Brown10e89712011-07-08 18:52:57 -07005540 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5541 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005543 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005544 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005545 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005546 } catch (RemoteException ex) {
5547 }
5548 if (providers != null) {
5549 final int N = providers.size();
5550 for (int i=0; i<N; i++) {
5551 ProviderInfo cpi =
5552 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005553 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5554 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005556 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005557 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558 }
5559 app.pubProviders.put(cpi.name, cpr);
5560 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005561 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 }
5563 }
5564 return providers;
5565 }
5566
5567 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005568 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5570 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5571 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005572 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005573 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 return null;
5575 }
5576 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005577 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005578 == PackageManager.PERMISSION_GRANTED) {
5579 return null;
5580 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005581
5582 PathPermission[] pps = cpi.pathPermissions;
5583 if (pps != null) {
5584 int i = pps.length;
5585 while (i > 0) {
5586 i--;
5587 PathPermission pp = pps[i];
5588 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005589 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005590 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005591 return null;
5592 }
5593 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005594 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005595 == PackageManager.PERMISSION_GRANTED) {
5596 return null;
5597 }
5598 }
5599 }
5600
Dianne Hackbornb424b632010-08-18 15:59:05 -07005601 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5602 if (perms != null) {
5603 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5604 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5605 return null;
5606 }
5607 }
5608 }
5609
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005610 String msg;
5611 if (!cpi.exported) {
5612 msg = "Permission Denial: opening provider " + cpi.name
5613 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5614 + ", uid=" + callingUid + ") that is not exported from uid "
5615 + cpi.applicationInfo.uid;
5616 } else {
5617 msg = "Permission Denial: opening provider " + cpi.name
5618 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5619 + ", uid=" + callingUid + ") requires "
5620 + cpi.readPermission + " or " + cpi.writePermission;
5621 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005622 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 return msg;
5624 }
5625
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005626 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5627 if (r != null) {
5628 Integer cnt = r.conProviders.get(cpr);
5629 if (DEBUG_PROVIDER) Slog.v(TAG,
5630 "Adding provider requested by "
5631 + r.processName + " from process "
5632 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5633 + " cnt=" + (cnt == null ? 1 : cnt));
5634 if (cnt == null) {
5635 cpr.clients.add(r);
5636 r.conProviders.put(cpr, new Integer(1));
5637 return true;
5638 } else {
5639 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5640 }
5641 } else {
5642 cpr.externals++;
5643 }
5644 return false;
5645 }
5646
5647 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5648 if (r != null) {
5649 Integer cnt = r.conProviders.get(cpr);
5650 if (DEBUG_PROVIDER) Slog.v(TAG,
5651 "Removing provider requested by "
5652 + r.processName + " from process "
5653 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5654 + " cnt=" + cnt);
5655 if (cnt == null || cnt.intValue() <= 1) {
5656 cpr.clients.remove(r);
5657 r.conProviders.remove(cpr);
5658 return true;
5659 } else {
5660 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5661 }
5662 } else {
5663 cpr.externals++;
5664 }
5665 return false;
5666 }
5667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005668 private final ContentProviderHolder getContentProviderImpl(
5669 IApplicationThread caller, String name) {
5670 ContentProviderRecord cpr;
5671 ProviderInfo cpi = null;
5672
5673 synchronized(this) {
5674 ProcessRecord r = null;
5675 if (caller != null) {
5676 r = getRecordForAppLocked(caller);
5677 if (r == null) {
5678 throw new SecurityException(
5679 "Unable to find app for caller " + caller
5680 + " (pid=" + Binder.getCallingPid()
5681 + ") when getting content provider " + name);
5682 }
5683 }
5684
5685 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005686 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005687 boolean providerRunning = cpr != null;
5688 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005690 String msg;
5691 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5692 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005693 }
5694
5695 if (r != null && cpr.canRunHere(r)) {
5696 // This provider has been published or is in the process
5697 // of being published... but it is also allowed to run
5698 // in the caller's process, so don't make a connection
5699 // and just let the caller instantiate its own instance.
5700 if (cpr.provider != null) {
5701 // don't give caller the provider object, it needs
5702 // to make its own.
5703 cpr = new ContentProviderRecord(cpr);
5704 }
5705 return cpr;
5706 }
5707
5708 final long origId = Binder.clearCallingIdentity();
5709
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005710 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005711 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005712 final boolean countChanged = incProviderCount(r, cpr);
5713 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005714 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005715 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005716 // make sure to count it as being accessed and thus
5717 // back up on the LRU list. This is good because
5718 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005719 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005720 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005721 }
5722
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005723 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005724 if (false) {
5725 if (cpr.name.flattenToShortString().equals(
5726 "com.android.providers.calendar/.CalendarProvider2")) {
5727 Slog.v(TAG, "****************** KILLING "
5728 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005729 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005730 }
5731 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005732 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005733 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5734 // NOTE: there is still a race here where a signal could be
5735 // pending on the process even though we managed to update its
5736 // adj level. Not sure what to do about this, but at least
5737 // the race is now smaller.
5738 if (!success) {
5739 // Uh oh... it looks like the provider's process
5740 // has been killed on us. We need to wait for a new
5741 // process to be started, and make sure its death
5742 // doesn't kill our process.
5743 Slog.i(TAG,
5744 "Existing provider " + cpr.name.flattenToShortString()
5745 + " is crashing; detaching " + r);
5746 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005747 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005748 if (!lastRef) {
5749 // This wasn't the last ref our process had on
5750 // the provider... we have now been killed, bail.
5751 return null;
5752 }
5753 providerRunning = false;
5754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005755 }
5756
5757 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005758 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005759
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005760 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005762 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005763 resolveContentProvider(name,
5764 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005765 } catch (RemoteException ex) {
5766 }
5767 if (cpi == null) {
5768 return null;
5769 }
5770
Dianne Hackbornb424b632010-08-18 15:59:05 -07005771 String msg;
5772 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5773 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 }
5775
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005776 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005777 && !cpi.processName.equals("system")) {
5778 // If this content provider does not run in the system
5779 // process, and the system is not yet ready to run other
5780 // processes, then fail fast instead of hanging.
5781 throw new IllegalArgumentException(
5782 "Attempt to launch content provider before system ready");
5783 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005784
5785 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5786 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005787 final boolean firstClass = cpr == null;
5788 if (firstClass) {
5789 try {
5790 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005791 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005792 getApplicationInfo(
5793 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005794 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005795 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005796 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 + cpi.name);
5798 return null;
5799 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005800 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005801 } catch (RemoteException ex) {
5802 // pm is in same process, this will never happen.
5803 }
5804 }
5805
5806 if (r != null && cpr.canRunHere(r)) {
5807 // If this is a multiprocess provider, then just return its
5808 // info and allow the caller to instantiate it. Only do
5809 // this if the provider is the same user as the caller's
5810 // process, or can run as root (so can be in any process).
5811 return cpr;
5812 }
5813
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005814 if (DEBUG_PROVIDER) {
5815 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005816 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005817 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005818 }
5819
5820 // This is single process, and our app is now connecting to it.
5821 // See if we are already in the process of launching this
5822 // provider.
5823 final int N = mLaunchingProviders.size();
5824 int i;
5825 for (i=0; i<N; i++) {
5826 if (mLaunchingProviders.get(i) == cpr) {
5827 break;
5828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005829 }
5830
5831 // If the provider is not already being launched, then get it
5832 // started.
5833 if (i >= N) {
5834 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005835
5836 try {
5837 // Content provider is now in use, its package can't be stopped.
5838 try {
5839 AppGlobals.getPackageManager().setPackageStoppedState(
5840 cpr.appInfo.packageName, false);
5841 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005842 } catch (IllegalArgumentException e) {
5843 Slog.w(TAG, "Failed trying to unstop package "
5844 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005845 }
5846
5847 ProcessRecord proc = startProcessLocked(cpi.processName,
5848 cpr.appInfo, false, 0, "content provider",
5849 new ComponentName(cpi.applicationInfo.packageName,
5850 cpi.name), false);
5851 if (proc == null) {
5852 Slog.w(TAG, "Unable to launch app "
5853 + cpi.applicationInfo.packageName + "/"
5854 + cpi.applicationInfo.uid + " for provider "
5855 + name + ": process is bad");
5856 return null;
5857 }
5858 cpr.launchingApp = proc;
5859 mLaunchingProviders.add(cpr);
5860 } finally {
5861 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005863 }
5864
5865 // Make sure the provider is published (the same provider class
5866 // may be published under multiple names).
5867 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005868 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 }
5870 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005871 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005872 }
5873 }
5874
5875 // Wait for the provider to be published...
5876 synchronized (cpr) {
5877 while (cpr.provider == null) {
5878 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005879 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005880 + cpi.applicationInfo.packageName + "/"
5881 + cpi.applicationInfo.uid + " for provider "
5882 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005883 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884 cpi.applicationInfo.packageName,
5885 cpi.applicationInfo.uid, name);
5886 return null;
5887 }
5888 try {
5889 cpr.wait();
5890 } catch (InterruptedException ex) {
5891 }
5892 }
5893 }
5894 return cpr;
5895 }
5896
5897 public final ContentProviderHolder getContentProvider(
5898 IApplicationThread caller, String name) {
5899 if (caller == null) {
5900 String msg = "null IApplicationThread when getting content provider "
5901 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005902 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 throw new SecurityException(msg);
5904 }
5905
5906 return getContentProviderImpl(caller, name);
5907 }
5908
5909 private ContentProviderHolder getContentProviderExternal(String name) {
5910 return getContentProviderImpl(null, name);
5911 }
5912
5913 /**
5914 * Drop a content provider from a ProcessRecord's bookkeeping
5915 * @param cpr
5916 */
5917 public void removeContentProvider(IApplicationThread caller, String name) {
5918 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005919 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005921 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005922 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005923 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 return;
5925 }
5926 final ProcessRecord r = getRecordForAppLocked(caller);
5927 if (r == null) {
5928 throw new SecurityException(
5929 "Unable to find app for caller " + caller +
5930 " when removing content provider " + name);
5931 }
5932 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005933 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5934 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005935 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005937 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005938 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 return;
5940 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005941 if (decProviderCount(r, localCpr)) {
5942 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005945 }
5946 }
5947
5948 private void removeContentProviderExternal(String name) {
5949 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005950 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005951 if(cpr == null) {
5952 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005953 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005954 return;
5955 }
5956
5957 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005958 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5959 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005960 localCpr.externals--;
5961 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005962 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005963 }
5964 updateOomAdjLocked();
5965 }
5966 }
5967
5968 public final void publishContentProviders(IApplicationThread caller,
5969 List<ContentProviderHolder> providers) {
5970 if (providers == null) {
5971 return;
5972 }
5973
5974 synchronized(this) {
5975 final ProcessRecord r = getRecordForAppLocked(caller);
5976 if (r == null) {
5977 throw new SecurityException(
5978 "Unable to find app for caller " + caller
5979 + " (pid=" + Binder.getCallingPid()
5980 + ") when publishing content providers");
5981 }
5982
5983 final long origId = Binder.clearCallingIdentity();
5984
5985 final int N = providers.size();
5986 for (int i=0; i<N; i++) {
5987 ContentProviderHolder src = providers.get(i);
5988 if (src == null || src.info == null || src.provider == null) {
5989 continue;
5990 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005991 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005992 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005993 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5994 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005995 String names[] = dst.info.authority.split(";");
5996 for (int j = 0; j < names.length; j++) {
5997 mProvidersByName.put(names[j], dst);
5998 }
5999
6000 int NL = mLaunchingProviders.size();
6001 int j;
6002 for (j=0; j<NL; j++) {
6003 if (mLaunchingProviders.get(j) == dst) {
6004 mLaunchingProviders.remove(j);
6005 j--;
6006 NL--;
6007 }
6008 }
6009 synchronized (dst) {
6010 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006011 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 dst.notifyAll();
6013 }
6014 updateOomAdjLocked(r);
6015 }
6016 }
6017
6018 Binder.restoreCallingIdentity(origId);
6019 }
6020 }
6021
6022 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006023 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006024 synchronized (mSelf) {
6025 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6026 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006027 if (providers != null) {
6028 for (int i=providers.size()-1; i>=0; i--) {
6029 ProviderInfo pi = (ProviderInfo)providers.get(i);
6030 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6031 Slog.w(TAG, "Not installing system proc provider " + pi.name
6032 + ": not system .apk");
6033 providers.remove(i);
6034 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006035 }
6036 }
6037 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006038 if (providers != null) {
6039 mSystemThread.installSystemProviders(providers);
6040 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006041
6042 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006043
6044 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006045 }
6046
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006047 /**
6048 * Allows app to retrieve the MIME type of a URI without having permission
6049 * to access its content provider.
6050 *
6051 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6052 *
6053 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6054 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6055 */
6056 public String getProviderMimeType(Uri uri) {
6057 final String name = uri.getAuthority();
6058 final long ident = Binder.clearCallingIdentity();
6059 ContentProviderHolder holder = null;
6060
6061 try {
6062 holder = getContentProviderExternal(name);
6063 if (holder != null) {
6064 return holder.provider.getType(uri);
6065 }
6066 } catch (RemoteException e) {
6067 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6068 return null;
6069 } finally {
6070 if (holder != null) {
6071 removeContentProviderExternal(name);
6072 }
6073 Binder.restoreCallingIdentity(ident);
6074 }
6075
6076 return null;
6077 }
6078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006079 // =========================================================
6080 // GLOBAL MANAGEMENT
6081 // =========================================================
6082
6083 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6084 ApplicationInfo info, String customProcess) {
6085 String proc = customProcess != null ? customProcess : info.processName;
6086 BatteryStatsImpl.Uid.Proc ps = null;
6087 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6088 synchronized (stats) {
6089 ps = stats.getProcessStatsLocked(info.uid, proc);
6090 }
6091 return new ProcessRecord(ps, thread, info, proc);
6092 }
6093
6094 final ProcessRecord addAppLocked(ApplicationInfo info) {
6095 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6096
6097 if (app == null) {
6098 app = newProcessRecordLocked(null, info, null);
6099 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006100 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 }
6102
Dianne Hackborne7f97212011-02-24 14:40:20 -08006103 // This package really, really can not be stopped.
6104 try {
6105 AppGlobals.getPackageManager().setPackageStoppedState(
6106 info.packageName, false);
6107 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006108 } catch (IllegalArgumentException e) {
6109 Slog.w(TAG, "Failed trying to unstop package "
6110 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006111 }
6112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6114 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6115 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006116 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006117 }
6118 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6119 mPersistentStartingProcesses.add(app);
6120 startProcessLocked(app, "added application", app.processName);
6121 }
6122
6123 return app;
6124 }
6125
6126 public void unhandledBack() {
6127 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6128 "unhandledBack()");
6129
6130 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006131 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006132 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 TAG, "Performing unhandledBack(): stack size = " + count);
6134 if (count > 1) {
6135 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006136 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006137 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6138 Binder.restoreCallingIdentity(origId);
6139 }
6140 }
6141 }
6142
6143 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6144 String name = uri.getAuthority();
6145 ContentProviderHolder cph = getContentProviderExternal(name);
6146 ParcelFileDescriptor pfd = null;
6147 if (cph != null) {
6148 // We record the binder invoker's uid in thread-local storage before
6149 // going to the content provider to open the file. Later, in the code
6150 // that handles all permissions checks, we look for this uid and use
6151 // that rather than the Activity Manager's own uid. The effect is that
6152 // we do the check against the caller's permissions even though it looks
6153 // to the content provider like the Activity Manager itself is making
6154 // the request.
6155 sCallerIdentity.set(new Identity(
6156 Binder.getCallingPid(), Binder.getCallingUid()));
6157 try {
6158 pfd = cph.provider.openFile(uri, "r");
6159 } catch (FileNotFoundException e) {
6160 // do nothing; pfd will be returned null
6161 } finally {
6162 // Ensure that whatever happens, we clean up the identity state
6163 sCallerIdentity.remove();
6164 }
6165
6166 // We've got the fd now, so we're done with the provider.
6167 removeContentProviderExternal(name);
6168 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006169 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006170 }
6171 return pfd;
6172 }
6173
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006174 // Actually is sleeping or shutting down or whatever else in the future
6175 // is an inactive state.
6176 public boolean isSleeping() {
6177 return mSleeping || mShuttingDown;
6178 }
6179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006180 public void goingToSleep() {
6181 synchronized(this) {
6182 mSleeping = true;
6183 mWindowManager.setEventDispatching(false);
6184
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006185 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006186
6187 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006188 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006189 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6190 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006191 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006192 }
6193 }
6194
Dianne Hackborn55280a92009-05-07 15:53:46 -07006195 public boolean shutdown(int timeout) {
6196 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6197 != PackageManager.PERMISSION_GRANTED) {
6198 throw new SecurityException("Requires permission "
6199 + android.Manifest.permission.SHUTDOWN);
6200 }
6201
6202 boolean timedout = false;
6203
6204 synchronized(this) {
6205 mShuttingDown = true;
6206 mWindowManager.setEventDispatching(false);
6207
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006208 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006209 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006210 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006211 while (mMainStack.mResumedActivity != null
6212 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006213 long delay = endTime - System.currentTimeMillis();
6214 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006215 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006216 timedout = true;
6217 break;
6218 }
6219 try {
6220 this.wait();
6221 } catch (InterruptedException e) {
6222 }
6223 }
6224 }
6225 }
6226
6227 mUsageStatsService.shutdown();
6228 mBatteryStatsService.shutdown();
6229
6230 return timedout;
6231 }
6232
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006233 public final void activitySlept(IBinder token) {
6234 if (localLOGV) Slog.v(
6235 TAG, "Activity slept: token=" + token);
6236
6237 ActivityRecord r = null;
6238
6239 final long origId = Binder.clearCallingIdentity();
6240
6241 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006242 r = mMainStack.isInStackLocked(token);
6243 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006244 mMainStack.activitySleptLocked(r);
6245 }
6246 }
6247
6248 Binder.restoreCallingIdentity(origId);
6249 }
6250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006251 public void wakingUp() {
6252 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 mWindowManager.setEventDispatching(true);
6254 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006255 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006256 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006257 }
6258 }
6259
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006260 public void stopAppSwitches() {
6261 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6262 != PackageManager.PERMISSION_GRANTED) {
6263 throw new SecurityException("Requires permission "
6264 + android.Manifest.permission.STOP_APP_SWITCHES);
6265 }
6266
6267 synchronized(this) {
6268 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6269 + APP_SWITCH_DELAY_TIME;
6270 mDidAppSwitch = false;
6271 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6272 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6273 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6274 }
6275 }
6276
6277 public void resumeAppSwitches() {
6278 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6279 != PackageManager.PERMISSION_GRANTED) {
6280 throw new SecurityException("Requires permission "
6281 + android.Manifest.permission.STOP_APP_SWITCHES);
6282 }
6283
6284 synchronized(this) {
6285 // Note that we don't execute any pending app switches... we will
6286 // let those wait until either the timeout, or the next start
6287 // activity request.
6288 mAppSwitchesAllowedTime = 0;
6289 }
6290 }
6291
6292 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6293 String name) {
6294 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6295 return true;
6296 }
6297
6298 final int perm = checkComponentPermission(
6299 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006300 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006301 if (perm == PackageManager.PERMISSION_GRANTED) {
6302 return true;
6303 }
6304
Joe Onorato8a9b2202010-02-26 18:56:32 -08006305 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006306 return false;
6307 }
6308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 public void setDebugApp(String packageName, boolean waitForDebugger,
6310 boolean persistent) {
6311 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6312 "setDebugApp()");
6313
6314 // Note that this is not really thread safe if there are multiple
6315 // callers into it at the same time, but that's not a situation we
6316 // care about.
6317 if (persistent) {
6318 final ContentResolver resolver = mContext.getContentResolver();
6319 Settings.System.putString(
6320 resolver, Settings.System.DEBUG_APP,
6321 packageName);
6322 Settings.System.putInt(
6323 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6324 waitForDebugger ? 1 : 0);
6325 }
6326
6327 synchronized (this) {
6328 if (!persistent) {
6329 mOrigDebugApp = mDebugApp;
6330 mOrigWaitForDebugger = mWaitForDebugger;
6331 }
6332 mDebugApp = packageName;
6333 mWaitForDebugger = waitForDebugger;
6334 mDebugTransient = !persistent;
6335 if (packageName != null) {
6336 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006337 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338 Binder.restoreCallingIdentity(origId);
6339 }
6340 }
6341 }
6342
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006343 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6344 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6345 synchronized (this) {
6346 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6347 if (!isDebuggable) {
6348 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6349 throw new SecurityException("Process not debuggable: " + app.packageName);
6350 }
6351 }
6352 mProfileApp = processName;
6353 mProfileFile = profileFile;
6354 if (mProfileFd != null) {
6355 try {
6356 mProfileFd.close();
6357 } catch (IOException e) {
6358 }
6359 mProfileFd = null;
6360 }
6361 mProfileFd = profileFd;
6362 mProfileType = 0;
6363 mAutoStopProfiler = autoStopProfiler;
6364 }
6365 }
6366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006367 public void setAlwaysFinish(boolean enabled) {
6368 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6369 "setAlwaysFinish()");
6370
6371 Settings.System.putInt(
6372 mContext.getContentResolver(),
6373 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6374
6375 synchronized (this) {
6376 mAlwaysFinishActivities = enabled;
6377 }
6378 }
6379
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006380 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006382 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006384 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006385 }
6386 }
6387
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006388 public boolean isUserAMonkey() {
6389 // For now the fact that there is a controller implies
6390 // we have a monkey.
6391 synchronized (this) {
6392 return mController != null;
6393 }
6394 }
6395
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006396 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006397 synchronized (this) {
6398 mWatchers.register(watcher);
6399 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006400 }
6401
6402 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006403 synchronized (this) {
6404 mWatchers.unregister(watcher);
6405 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006406 }
6407
Jeff Sharkeya4620792011-05-20 15:29:23 -07006408 public void registerProcessObserver(IProcessObserver observer) {
6409 mProcessObservers.register(observer);
6410 }
6411
6412 public void unregisterProcessObserver(IProcessObserver observer) {
6413 mProcessObservers.unregister(observer);
6414 }
6415
Daniel Sandler69a48172010-06-23 16:29:36 -04006416 public void setImmersive(IBinder token, boolean immersive) {
6417 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006418 ActivityRecord r = mMainStack.isInStackLocked(token);
6419 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006420 throw new IllegalArgumentException();
6421 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006422 r.immersive = immersive;
6423 }
6424 }
6425
6426 public boolean isImmersive(IBinder token) {
6427 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006428 ActivityRecord r = mMainStack.isInStackLocked(token);
6429 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006430 throw new IllegalArgumentException();
6431 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006432 return r.immersive;
6433 }
6434 }
6435
6436 public boolean isTopActivityImmersive() {
6437 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006438 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006439 return (r != null) ? r.immersive : false;
6440 }
6441 }
6442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 public final void enterSafeMode() {
6444 synchronized(this) {
6445 // It only makes sense to do this before the system is ready
6446 // and started launching other packages.
6447 if (!mSystemReady) {
6448 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006449 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 } catch (RemoteException e) {
6451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006452 }
6453 }
6454 }
6455
Jeff Brownb09abc12011-01-13 21:08:27 -08006456 public final void showSafeModeOverlay() {
6457 View v = LayoutInflater.from(mContext).inflate(
6458 com.android.internal.R.layout.safe_mode, null);
6459 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6460 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6461 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6462 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6463 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6464 lp.format = v.getBackground().getOpacity();
6465 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6466 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6467 ((WindowManager)mContext.getSystemService(
6468 Context.WINDOW_SERVICE)).addView(v, lp);
6469 }
6470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006471 public void noteWakeupAlarm(IIntentSender sender) {
6472 if (!(sender instanceof PendingIntentRecord)) {
6473 return;
6474 }
6475 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6476 synchronized (stats) {
6477 if (mBatteryStatsService.isOnBattery()) {
6478 mBatteryStatsService.enforceCallingPermission();
6479 PendingIntentRecord rec = (PendingIntentRecord)sender;
6480 int MY_UID = Binder.getCallingUid();
6481 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6482 BatteryStatsImpl.Uid.Pkg pkg =
6483 stats.getPackageStatsLocked(uid, rec.key.packageName);
6484 pkg.incWakeupsLocked();
6485 }
6486 }
6487 }
6488
Dianne Hackborn64825172011-03-02 21:32:58 -08006489 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006490 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006491 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006492 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006493 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006494 // XXX Note: don't acquire main activity lock here, because the window
6495 // manager calls in with its locks held.
6496
6497 boolean killed = false;
6498 synchronized (mPidsSelfLocked) {
6499 int[] types = new int[pids.length];
6500 int worstType = 0;
6501 for (int i=0; i<pids.length; i++) {
6502 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6503 if (proc != null) {
6504 int type = proc.setAdj;
6505 types[i] = type;
6506 if (type > worstType) {
6507 worstType = type;
6508 }
6509 }
6510 }
6511
Dianne Hackborn64825172011-03-02 21:32:58 -08006512 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006514 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6515 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006516 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006517
6518 // If this is not a secure call, don't let it kill processes that
6519 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006520 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6521 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006522 }
6523
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006524 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006525 for (int i=0; i<pids.length; i++) {
6526 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6527 if (proc == null) {
6528 continue;
6529 }
6530 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006531 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006532 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006533 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6534 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006536 proc.killedBackground = true;
6537 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 }
6539 }
6540 }
6541 return killed;
6542 }
6543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 public final void startRunning(String pkg, String cls, String action,
6545 String data) {
6546 synchronized(this) {
6547 if (mStartRunning) {
6548 return;
6549 }
6550 mStartRunning = true;
6551 mTopComponent = pkg != null && cls != null
6552 ? new ComponentName(pkg, cls) : null;
6553 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6554 mTopData = data;
6555 if (!mSystemReady) {
6556 return;
6557 }
6558 }
6559
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006560 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561 }
6562
6563 private void retrieveSettings() {
6564 final ContentResolver resolver = mContext.getContentResolver();
6565 String debugApp = Settings.System.getString(
6566 resolver, Settings.System.DEBUG_APP);
6567 boolean waitForDebugger = Settings.System.getInt(
6568 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6569 boolean alwaysFinishActivities = Settings.System.getInt(
6570 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6571
6572 Configuration configuration = new Configuration();
6573 Settings.System.getConfiguration(resolver, configuration);
6574
6575 synchronized (this) {
6576 mDebugApp = mOrigDebugApp = debugApp;
6577 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6578 mAlwaysFinishActivities = alwaysFinishActivities;
6579 // This happens before any activities are started, so we can
6580 // change mConfiguration in-place.
6581 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006582 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006583 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006584 }
6585 }
6586
6587 public boolean testIsSystemReady() {
6588 // no need to synchronize(this) just to read & return the value
6589 return mSystemReady;
6590 }
6591
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006592 private static File getCalledPreBootReceiversFile() {
6593 File dataDir = Environment.getDataDirectory();
6594 File systemDir = new File(dataDir, "system");
6595 File fname = new File(systemDir, "called_pre_boots.dat");
6596 return fname;
6597 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006598
6599 static final int LAST_DONE_VERSION = 10000;
6600
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006601 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6602 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6603 File file = getCalledPreBootReceiversFile();
6604 FileInputStream fis = null;
6605 try {
6606 fis = new FileInputStream(file);
6607 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006608 int fvers = dis.readInt();
6609 if (fvers == LAST_DONE_VERSION) {
6610 String vers = dis.readUTF();
6611 String codename = dis.readUTF();
6612 String build = dis.readUTF();
6613 if (android.os.Build.VERSION.RELEASE.equals(vers)
6614 && android.os.Build.VERSION.CODENAME.equals(codename)
6615 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6616 int num = dis.readInt();
6617 while (num > 0) {
6618 num--;
6619 String pkg = dis.readUTF();
6620 String cls = dis.readUTF();
6621 lastDoneReceivers.add(new ComponentName(pkg, cls));
6622 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006623 }
6624 }
6625 } catch (FileNotFoundException e) {
6626 } catch (IOException e) {
6627 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6628 } finally {
6629 if (fis != null) {
6630 try {
6631 fis.close();
6632 } catch (IOException e) {
6633 }
6634 }
6635 }
6636 return lastDoneReceivers;
6637 }
6638
6639 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6640 File file = getCalledPreBootReceiversFile();
6641 FileOutputStream fos = null;
6642 DataOutputStream dos = null;
6643 try {
6644 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6645 fos = new FileOutputStream(file);
6646 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006647 dos.writeInt(LAST_DONE_VERSION);
6648 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006649 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006650 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006651 dos.writeInt(list.size());
6652 for (int i=0; i<list.size(); i++) {
6653 dos.writeUTF(list.get(i).getPackageName());
6654 dos.writeUTF(list.get(i).getClassName());
6655 }
6656 } catch (IOException e) {
6657 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6658 file.delete();
6659 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006660 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006661 if (dos != null) {
6662 try {
6663 dos.close();
6664 } catch (IOException e) {
6665 // TODO Auto-generated catch block
6666 e.printStackTrace();
6667 }
6668 }
6669 }
6670 }
6671
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006672 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 synchronized(this) {
6674 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006675 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006676 return;
6677 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006678
6679 // Check to see if there are any update receivers to run.
6680 if (!mDidUpdate) {
6681 if (mWaitingUpdate) {
6682 return;
6683 }
6684 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6685 List<ResolveInfo> ris = null;
6686 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006687 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006688 intent, null, 0);
6689 } catch (RemoteException e) {
6690 }
6691 if (ris != null) {
6692 for (int i=ris.size()-1; i>=0; i--) {
6693 if ((ris.get(i).activityInfo.applicationInfo.flags
6694 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6695 ris.remove(i);
6696 }
6697 }
6698 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006699
6700 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6701
6702 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006703 for (int i=0; i<ris.size(); i++) {
6704 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006705 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6706 if (lastDoneReceivers.contains(comp)) {
6707 ris.remove(i);
6708 i--;
6709 }
6710 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006711
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006712 for (int i=0; i<ris.size(); i++) {
6713 ActivityInfo ai = ris.get(i).activityInfo;
6714 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6715 doneReceivers.add(comp);
6716 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006717 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006718 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006719 finisher = new IIntentReceiver.Stub() {
6720 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006721 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006722 boolean sticky) {
6723 // The raw IIntentReceiver interface is called
6724 // with the AM lock held, so redispatch to
6725 // execute our code without the lock.
6726 mHandler.post(new Runnable() {
6727 public void run() {
6728 synchronized (ActivityManagerService.this) {
6729 mDidUpdate = true;
6730 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006731 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006732 showBootMessage(mContext.getText(
6733 R.string.android_upgrading_complete),
6734 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006735 systemReady(goingCallback);
6736 }
6737 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006738 }
6739 };
6740 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006741 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006742 broadcastIntentLocked(null, null, intent, null, finisher,
6743 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006744 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006745 mWaitingUpdate = true;
6746 }
6747 }
6748 }
6749 if (mWaitingUpdate) {
6750 return;
6751 }
6752 mDidUpdate = true;
6753 }
6754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 mSystemReady = true;
6756 if (!mStartRunning) {
6757 return;
6758 }
6759 }
6760
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006761 ArrayList<ProcessRecord> procsToKill = null;
6762 synchronized(mPidsSelfLocked) {
6763 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6764 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6765 if (!isAllowedWhileBooting(proc.info)){
6766 if (procsToKill == null) {
6767 procsToKill = new ArrayList<ProcessRecord>();
6768 }
6769 procsToKill.add(proc);
6770 }
6771 }
6772 }
6773
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006774 synchronized(this) {
6775 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006776 for (int i=procsToKill.size()-1; i>=0; i--) {
6777 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006778 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006779 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006780 }
6781 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006782
6783 // Now that we have cleaned up any update processes, we
6784 // are ready to start launching real processes and know that
6785 // we won't trample on them any more.
6786 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006787 }
6788
Joe Onorato8a9b2202010-02-26 18:56:32 -08006789 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006790 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 SystemClock.uptimeMillis());
6792
6793 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006794 // Make sure we have no pre-ready processes sitting around.
6795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6797 ResolveInfo ri = mContext.getPackageManager()
6798 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006799 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800 CharSequence errorMsg = null;
6801 if (ri != null) {
6802 ActivityInfo ai = ri.activityInfo;
6803 ApplicationInfo app = ai.applicationInfo;
6804 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6805 mTopAction = Intent.ACTION_FACTORY_TEST;
6806 mTopData = null;
6807 mTopComponent = new ComponentName(app.packageName,
6808 ai.name);
6809 } else {
6810 errorMsg = mContext.getResources().getText(
6811 com.android.internal.R.string.factorytest_not_system);
6812 }
6813 } else {
6814 errorMsg = mContext.getResources().getText(
6815 com.android.internal.R.string.factorytest_no_action);
6816 }
6817 if (errorMsg != null) {
6818 mTopAction = null;
6819 mTopData = null;
6820 mTopComponent = null;
6821 Message msg = Message.obtain();
6822 msg.what = SHOW_FACTORY_ERROR_MSG;
6823 msg.getData().putCharSequence("msg", errorMsg);
6824 mHandler.sendMessage(msg);
6825 }
6826 }
6827 }
6828
6829 retrieveSettings();
6830
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006831 if (goingCallback != null) goingCallback.run();
6832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 synchronized (this) {
6834 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6835 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006836 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006837 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006838 if (apps != null) {
6839 int N = apps.size();
6840 int i;
6841 for (i=0; i<N; i++) {
6842 ApplicationInfo info
6843 = (ApplicationInfo)apps.get(i);
6844 if (info != null &&
6845 !info.packageName.equals("android")) {
6846 addAppLocked(info);
6847 }
6848 }
6849 }
6850 } catch (RemoteException ex) {
6851 // pm is in same process, this will never happen.
6852 }
6853 }
6854
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006855 // Start up initial activity.
6856 mBooting = true;
6857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006859 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006860 Message msg = Message.obtain();
6861 msg.what = SHOW_UID_ERROR_MSG;
6862 mHandler.sendMessage(msg);
6863 }
6864 } catch (RemoteException e) {
6865 }
6866
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006867 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 }
6869 }
6870
Dan Egnorb7f03672009-12-09 16:22:32 -08006871 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006872 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006874 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006875 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 startAppProblemLocked(app);
6877 app.stopFreezingAllLocked();
6878 return handleAppCrashLocked(app);
6879 }
6880
Dan Egnorb7f03672009-12-09 16:22:32 -08006881 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006882 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006884 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006885 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6886 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 startAppProblemLocked(app);
6888 app.stopFreezingAllLocked();
6889 }
6890
6891 /**
6892 * Generate a process error record, suitable for attachment to a ProcessRecord.
6893 *
6894 * @param app The ProcessRecord in which the error occurred.
6895 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6896 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006897 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006898 * @param shortMsg Short message describing the crash.
6899 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006900 * @param stackTrace Full crash stack trace, may be null.
6901 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 * @return Returns a fully-formed AppErrorStateInfo record.
6903 */
6904 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006905 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 report.condition = condition;
6909 report.processName = app.processName;
6910 report.pid = app.pid;
6911 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006912 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006913 report.shortMsg = shortMsg;
6914 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006915 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916
6917 return report;
6918 }
6919
Dan Egnor42471dd2010-01-07 17:25:22 -08006920 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006921 synchronized (this) {
6922 app.crashing = false;
6923 app.crashingReport = null;
6924 app.notResponding = false;
6925 app.notRespondingReport = null;
6926 if (app.anrDialog == fromDialog) {
6927 app.anrDialog = null;
6928 }
6929 if (app.waitDialog == fromDialog) {
6930 app.waitDialog = null;
6931 }
6932 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006933 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006934 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006935 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6936 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006937 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 }
6940 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006941
Dan Egnorb7f03672009-12-09 16:22:32 -08006942 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006943 long now = SystemClock.uptimeMillis();
6944
6945 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6946 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006947 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006949 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006951 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006953 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6954 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006955 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006956 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006958 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006959 }
6960 }
6961 if (!app.persistent) {
6962 // We don't want to start this process again until the user
6963 // explicitly does so... but for persistent process, we really
6964 // need to keep it running. If a persistent process is actually
6965 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006966 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006967 app.info.processName);
6968 mBadProcesses.put(app.info.processName, app.info.uid, now);
6969 app.bad = true;
6970 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6971 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006972 // Don't let services in this process be restarted and potentially
6973 // annoy the user repeatedly. Unless it is persistent, since those
6974 // processes run critical code.
6975 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006976 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 return false;
6978 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006979 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006980 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006981 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006982 if (r.app == app) {
6983 // If the top running activity is from this crashing
6984 // process, then terminate it to avoid getting in a loop.
6985 Slog.w(TAG, " Force finishing activity "
6986 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006987 int index = mMainStack.indexOfTokenLocked(r);
6988 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006989 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006990 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006991 // stopped, to avoid a situation where one will get
6992 // re-start our crashing activity once it gets resumed again.
6993 index--;
6994 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006995 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006996 if (r.state == ActivityState.RESUMED
6997 || r.state == ActivityState.PAUSING
6998 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006999 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007000 Slog.w(TAG, " Force finishing activity "
7001 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007002 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007003 Activity.RESULT_CANCELED, null, "crashed");
7004 }
7005 }
7006 }
7007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007008 }
7009
7010 // Bump up the crash count of any services currently running in the proc.
7011 if (app.services.size() != 0) {
7012 // Any services running in the application need to be placed
7013 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007014 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007016 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007017 sr.crashCount++;
7018 }
7019 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007020
7021 // If the crashing process is what we consider to be the "home process" and it has been
7022 // replaced by a third-party app, clear the package preferred activities from packages
7023 // with a home activity running in the process to prevent a repeatedly crashing app
7024 // from blocking the user to manually clear the list.
7025 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7026 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7027 Iterator it = mHomeProcess.activities.iterator();
7028 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007029 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007030 if (r.isHomeActivity) {
7031 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7032 try {
7033 ActivityThread.getPackageManager()
7034 .clearPackagePreferredActivities(r.packageName);
7035 } catch (RemoteException c) {
7036 // pm is in same process, this will never happen.
7037 }
7038 }
7039 }
7040 }
7041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007042 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7043 return true;
7044 }
7045
7046 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007047 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7048 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007049 skipCurrentReceiverLocked(app);
7050 }
7051
7052 void skipCurrentReceiverLocked(ProcessRecord app) {
7053 boolean reschedule = false;
7054 BroadcastRecord r = app.curReceiver;
7055 if (r != null) {
7056 // The current broadcast is waiting for this app's receiver
7057 // to be finished. Looks like that's not going to happen, so
7058 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007059 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7061 r.resultExtras, r.resultAbort, true);
7062 reschedule = true;
7063 }
7064 r = mPendingBroadcast;
7065 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007066 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007068 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007069 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7070 r.resultExtras, r.resultAbort, true);
7071 reschedule = true;
7072 }
7073 if (reschedule) {
7074 scheduleBroadcastsLocked();
7075 }
7076 }
7077
Dan Egnor60d87622009-12-16 16:32:58 -08007078 /**
7079 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7080 * The application process will exit immediately after this call returns.
7081 * @param app object of the crashing app, null for the system server
7082 * @param crashInfo describing the exception
7083 */
7084 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007085 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007086 final String processName = app == null ? "system_server"
7087 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007088
7089 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007090 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007091 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007092 crashInfo.exceptionClassName,
7093 crashInfo.exceptionMessage,
7094 crashInfo.throwFileName,
7095 crashInfo.throwLineNumber);
7096
Jeff Sharkeya353d262011-10-28 11:12:06 -07007097 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007098
7099 crashApplication(r, crashInfo);
7100 }
7101
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007102 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007103 IBinder app,
7104 int violationMask,
7105 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007106 ProcessRecord r = findAppProcess(app, "StrictMode");
7107 if (r == null) {
7108 return;
7109 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007110
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007111 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007112 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007113 boolean logIt = true;
7114 synchronized (mAlreadyLoggedViolatedStacks) {
7115 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7116 logIt = false;
7117 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007118 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007119 // the relative pain numbers, without logging all
7120 // the stack traces repeatedly. We'd want to do
7121 // likewise in the client code, which also does
7122 // dup suppression, before the Binder call.
7123 } else {
7124 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7125 mAlreadyLoggedViolatedStacks.clear();
7126 }
7127 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7128 }
7129 }
7130 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007131 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007132 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007133 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007134
7135 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7136 AppErrorResult result = new AppErrorResult();
7137 synchronized (this) {
7138 final long origId = Binder.clearCallingIdentity();
7139
7140 Message msg = Message.obtain();
7141 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7142 HashMap<String, Object> data = new HashMap<String, Object>();
7143 data.put("result", result);
7144 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007145 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007146 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007147 msg.obj = data;
7148 mHandler.sendMessage(msg);
7149
7150 Binder.restoreCallingIdentity(origId);
7151 }
7152 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007153 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007154 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007155 }
7156
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007157 // Depending on the policy in effect, there could be a bunch of
7158 // these in quick succession so we try to batch these together to
7159 // minimize disk writes, number of dropbox entries, and maximize
7160 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007161 private void logStrictModeViolationToDropBox(
7162 ProcessRecord process,
7163 StrictMode.ViolationInfo info) {
7164 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007165 return;
7166 }
7167 final boolean isSystemApp = process == null ||
7168 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7169 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007170 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007171 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7172 final DropBoxManager dbox = (DropBoxManager)
7173 mContext.getSystemService(Context.DROPBOX_SERVICE);
7174
7175 // Exit early if the dropbox isn't configured to accept this report type.
7176 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7177
7178 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007179 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007180 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7181 synchronized (sb) {
7182 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007183 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007184 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7185 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007186 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7187 if (info.violationNumThisLoop != 0) {
7188 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7189 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007190 if (info.numAnimationsRunning != 0) {
7191 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7192 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007193 if (info.broadcastIntentAction != null) {
7194 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7195 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007196 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007197 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007198 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007199 if (info.numInstances != -1) {
7200 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7201 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007202 if (info.tags != null) {
7203 for (String tag : info.tags) {
7204 sb.append("Span-Tag: ").append(tag).append("\n");
7205 }
7206 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007207 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007208 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7209 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007210 }
7211 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007212
7213 // Only buffer up to ~64k. Various logging bits truncate
7214 // things at 128k.
7215 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007216 }
7217
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007218 // Flush immediately if the buffer's grown too large, or this
7219 // is a non-system app. Non-system apps are isolated with a
7220 // different tag & policy and not batched.
7221 //
7222 // Batching is useful during internal testing with
7223 // StrictMode settings turned up high. Without batching,
7224 // thousands of separate files could be created on boot.
7225 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007226 new Thread("Error dump: " + dropboxTag) {
7227 @Override
7228 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007229 String report;
7230 synchronized (sb) {
7231 report = sb.toString();
7232 sb.delete(0, sb.length());
7233 sb.trimToSize();
7234 }
7235 if (report.length() != 0) {
7236 dbox.addText(dropboxTag, report);
7237 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007238 }
7239 }.start();
7240 return;
7241 }
7242
7243 // System app batching:
7244 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007245 // An existing dropbox-writing thread is outstanding, so
7246 // we don't need to start it up. The existing thread will
7247 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007248 return;
7249 }
7250
7251 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7252 // (After this point, we shouldn't access AMS internal data structures.)
7253 new Thread("Error dump: " + dropboxTag) {
7254 @Override
7255 public void run() {
7256 // 5 second sleep to let stacks arrive and be batched together
7257 try {
7258 Thread.sleep(5000); // 5 seconds
7259 } catch (InterruptedException e) {}
7260
7261 String errorReport;
7262 synchronized (mStrictModeBuffer) {
7263 errorReport = mStrictModeBuffer.toString();
7264 if (errorReport.length() == 0) {
7265 return;
7266 }
7267 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7268 mStrictModeBuffer.trimToSize();
7269 }
7270 dbox.addText(dropboxTag, errorReport);
7271 }
7272 }.start();
7273 }
7274
Dan Egnor60d87622009-12-16 16:32:58 -08007275 /**
7276 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7277 * @param app object of the crashing app, null for the system server
7278 * @param tag reported by the caller
7279 * @param crashInfo describing the context of the error
7280 * @return true if the process should exit immediately (WTF is fatal)
7281 */
7282 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007283 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007284 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007285 final String processName = app == null ? "system_server"
7286 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007287
7288 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007289 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007290 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007291 tag, crashInfo.exceptionMessage);
7292
Jeff Sharkeya353d262011-10-28 11:12:06 -07007293 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007294
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007295 if (r != null && r.pid != Process.myPid() &&
7296 Settings.Secure.getInt(mContext.getContentResolver(),
7297 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007298 crashApplication(r, crashInfo);
7299 return true;
7300 } else {
7301 return false;
7302 }
7303 }
7304
7305 /**
7306 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7307 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7308 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007309 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007310 if (app == null) {
7311 return null;
7312 }
7313
7314 synchronized (this) {
7315 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7316 final int NA = apps.size();
7317 for (int ia=0; ia<NA; ia++) {
7318 ProcessRecord p = apps.valueAt(ia);
7319 if (p.thread != null && p.thread.asBinder() == app) {
7320 return p;
7321 }
7322 }
7323 }
7324
Dianne Hackborncb44d962011-03-10 17:02:27 -08007325 Slog.w(TAG, "Can't find mystery application for " + reason
7326 + " from pid=" + Binder.getCallingPid()
7327 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007328 return null;
7329 }
7330 }
7331
7332 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007333 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7334 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007335 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007336 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7337 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007338 // Watchdog thread ends up invoking this function (with
7339 // a null ProcessRecord) to add the stack file to dropbox.
7340 // Do not acquire a lock on this (am) in such cases, as it
7341 // could cause a potential deadlock, if and when watchdog
7342 // is invoked due to unavailability of lock on am and it
7343 // would prevent watchdog from killing system_server.
7344 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007345 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007346 return;
7347 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007348 // Note: ProcessRecord 'process' is guarded by the service
7349 // instance. (notably process.pkgList, which could otherwise change
7350 // concurrently during execution of this method)
7351 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007352 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007353 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007354 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007355 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7356 for (String pkg : process.pkgList) {
7357 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007358 try {
Dan Egnora455d192010-03-12 08:52:28 -08007359 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7360 if (pi != null) {
7361 sb.append(" v").append(pi.versionCode);
7362 if (pi.versionName != null) {
7363 sb.append(" (").append(pi.versionName).append(")");
7364 }
7365 }
7366 } catch (RemoteException e) {
7367 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007368 }
Dan Egnora455d192010-03-12 08:52:28 -08007369 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007370 }
Dan Egnora455d192010-03-12 08:52:28 -08007371 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007372 }
7373
7374 private static String processClass(ProcessRecord process) {
7375 if (process == null || process.pid == MY_PID) {
7376 return "system_server";
7377 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7378 return "system_app";
7379 } else {
7380 return "data_app";
7381 }
7382 }
7383
7384 /**
7385 * Write a description of an error (crash, WTF, ANR) to the drop box.
7386 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7387 * @param process which caused the error, null means the system server
7388 * @param activity which triggered the error, null if unknown
7389 * @param parent activity related to the error, null if unknown
7390 * @param subject line related to the error, null if absent
7391 * @param report in long form describing the error, null if absent
7392 * @param logFile to include in the report, null if none
7393 * @param crashInfo giving an application stack trace, null if absent
7394 */
7395 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007396 ProcessRecord process, String processName, ActivityRecord activity,
7397 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007398 final String report, final File logFile,
7399 final ApplicationErrorReport.CrashInfo crashInfo) {
7400 // NOTE -- this must never acquire the ActivityManagerService lock,
7401 // otherwise the watchdog may be prevented from resetting the system.
7402
7403 final String dropboxTag = processClass(process) + "_" + eventType;
7404 final DropBoxManager dbox = (DropBoxManager)
7405 mContext.getSystemService(Context.DROPBOX_SERVICE);
7406
7407 // Exit early if the dropbox isn't configured to accept this report type.
7408 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7409
7410 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007411 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007412 if (activity != null) {
7413 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7414 }
7415 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7416 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7417 }
7418 if (parent != null && parent != activity) {
7419 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7420 }
7421 if (subject != null) {
7422 sb.append("Subject: ").append(subject).append("\n");
7423 }
7424 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007425 if (Debug.isDebuggerConnected()) {
7426 sb.append("Debugger: Connected\n");
7427 }
Dan Egnora455d192010-03-12 08:52:28 -08007428 sb.append("\n");
7429
7430 // Do the rest in a worker thread to avoid blocking the caller on I/O
7431 // (After this point, we shouldn't access AMS internal data structures.)
7432 Thread worker = new Thread("Error dump: " + dropboxTag) {
7433 @Override
7434 public void run() {
7435 if (report != null) {
7436 sb.append(report);
7437 }
7438 if (logFile != null) {
7439 try {
7440 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7441 } catch (IOException e) {
7442 Slog.e(TAG, "Error reading " + logFile, e);
7443 }
7444 }
7445 if (crashInfo != null && crashInfo.stackTrace != null) {
7446 sb.append(crashInfo.stackTrace);
7447 }
7448
7449 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7450 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7451 if (lines > 0) {
7452 sb.append("\n");
7453
7454 // Merge several logcat streams, and take the last N lines
7455 InputStreamReader input = null;
7456 try {
7457 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7458 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7459 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7460
7461 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7462 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7463 input = new InputStreamReader(logcat.getInputStream());
7464
7465 int num;
7466 char[] buf = new char[8192];
7467 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7468 } catch (IOException e) {
7469 Slog.e(TAG, "Error running logcat", e);
7470 } finally {
7471 if (input != null) try { input.close(); } catch (IOException e) {}
7472 }
7473 }
7474
7475 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007476 }
Dan Egnora455d192010-03-12 08:52:28 -08007477 };
7478
7479 if (process == null || process.pid == MY_PID) {
7480 worker.run(); // We may be about to die -- need to run this synchronously
7481 } else {
7482 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007483 }
7484 }
7485
7486 /**
7487 * Bring up the "unexpected error" dialog box for a crashing app.
7488 * Deal with edge cases (intercepts from instrumented applications,
7489 * ActivityController, error intent receivers, that sort of thing).
7490 * @param r the application crashing
7491 * @param crashInfo describing the failure
7492 */
7493 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007494 long timeMillis = System.currentTimeMillis();
7495 String shortMsg = crashInfo.exceptionClassName;
7496 String longMsg = crashInfo.exceptionMessage;
7497 String stackTrace = crashInfo.stackTrace;
7498 if (shortMsg != null && longMsg != null) {
7499 longMsg = shortMsg + ": " + longMsg;
7500 } else if (shortMsg != null) {
7501 longMsg = shortMsg;
7502 }
7503
Dan Egnor60d87622009-12-16 16:32:58 -08007504 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007505 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007506 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007507 try {
7508 String name = r != null ? r.processName : null;
7509 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007510 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007511 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007512 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 + " at watcher's request");
7514 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007515 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007516 }
7517 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007518 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 }
7520 }
7521
7522 final long origId = Binder.clearCallingIdentity();
7523
7524 // If this process is running instrumentation, finish it.
7525 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007526 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007528 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7529 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007530 Bundle info = new Bundle();
7531 info.putString("shortMsg", shortMsg);
7532 info.putString("longMsg", longMsg);
7533 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7534 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007535 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 }
7537
Dan Egnor60d87622009-12-16 16:32:58 -08007538 // If we can't identify the process or it's already exceeded its crash quota,
7539 // quit right away without showing a crash dialog.
7540 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007542 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 }
7544
7545 Message msg = Message.obtain();
7546 msg.what = SHOW_ERROR_MSG;
7547 HashMap data = new HashMap();
7548 data.put("result", result);
7549 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007550 msg.obj = data;
7551 mHandler.sendMessage(msg);
7552
7553 Binder.restoreCallingIdentity(origId);
7554 }
7555
7556 int res = result.get();
7557
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007558 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 synchronized (this) {
7560 if (r != null) {
7561 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7562 SystemClock.uptimeMillis());
7563 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007564 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007565 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007566 }
7567 }
7568
7569 if (appErrorIntent != null) {
7570 try {
7571 mContext.startActivity(appErrorIntent);
7572 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007573 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007576 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007577
7578 Intent createAppErrorIntentLocked(ProcessRecord r,
7579 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7580 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007581 if (report == null) {
7582 return null;
7583 }
7584 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7585 result.setComponent(r.errorReportReceiver);
7586 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7587 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7588 return result;
7589 }
7590
Dan Egnorb7f03672009-12-09 16:22:32 -08007591 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7592 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007593 if (r.errorReportReceiver == null) {
7594 return null;
7595 }
7596
7597 if (!r.crashing && !r.notResponding) {
7598 return null;
7599 }
7600
Dan Egnorb7f03672009-12-09 16:22:32 -08007601 ApplicationErrorReport report = new ApplicationErrorReport();
7602 report.packageName = r.info.packageName;
7603 report.installerPackageName = r.errorReportReceiver.getPackageName();
7604 report.processName = r.processName;
7605 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007606 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007607
Dan Egnorb7f03672009-12-09 16:22:32 -08007608 if (r.crashing) {
7609 report.type = ApplicationErrorReport.TYPE_CRASH;
7610 report.crashInfo = crashInfo;
7611 } else if (r.notResponding) {
7612 report.type = ApplicationErrorReport.TYPE_ANR;
7613 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007614
Dan Egnorb7f03672009-12-09 16:22:32 -08007615 report.anrInfo.activity = r.notRespondingReport.tag;
7616 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7617 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007618 }
7619
Dan Egnorb7f03672009-12-09 16:22:32 -08007620 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007621 }
7622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007623 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7624 // assume our apps are happy - lazy create the list
7625 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7626
7627 synchronized (this) {
7628
7629 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007630 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7631 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007632 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7633 // This one's in trouble, so we'll generate a report for it
7634 // crashes are higher priority (in case there's a crash *and* an anr)
7635 ActivityManager.ProcessErrorStateInfo report = null;
7636 if (app.crashing) {
7637 report = app.crashingReport;
7638 } else if (app.notResponding) {
7639 report = app.notRespondingReport;
7640 }
7641
7642 if (report != null) {
7643 if (errList == null) {
7644 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7645 }
7646 errList.add(report);
7647 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007648 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007649 " crashing = " + app.crashing +
7650 " notResponding = " + app.notResponding);
7651 }
7652 }
7653 }
7654 }
7655
7656 return errList;
7657 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007658
7659 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7660 if (adj >= ProcessList.EMPTY_APP_ADJ) {
7661 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7662 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7663 if (currApp != null) {
7664 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7665 }
7666 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7667 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7668 if (currApp != null) {
7669 currApp.lru = 0;
7670 }
7671 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7672 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
7673 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7674 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7675 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7676 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7677 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7678 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7679 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7680 } else {
7681 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7682 }
7683 }
7684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007685 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7686 // Lazy instantiation of list
7687 List<ActivityManager.RunningAppProcessInfo> runList = null;
7688 synchronized (this) {
7689 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007690 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7691 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007692 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7693 // Generate process state info for running application
7694 ActivityManager.RunningAppProcessInfo currApp =
7695 new ActivityManager.RunningAppProcessInfo(app.processName,
7696 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007697 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007698 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007699 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007700 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007701 if (app.persistent) {
7702 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007704 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007705 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007706 currApp.importanceReasonCode = app.adjTypeCode;
7707 if (app.adjSource instanceof ProcessRecord) {
7708 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007709 currApp.importanceReasonImportance = oomAdjToImportance(
7710 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007711 } else if (app.adjSource instanceof ActivityRecord) {
7712 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007713 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7714 }
7715 if (app.adjTarget instanceof ComponentName) {
7716 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7717 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007718 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007719 // + " lru=" + currApp.lru);
7720 if (runList == null) {
7721 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7722 }
7723 runList.add(currApp);
7724 }
7725 }
7726 }
7727 return runList;
7728 }
7729
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007730 public List<ApplicationInfo> getRunningExternalApplications() {
7731 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7732 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7733 if (runningApps != null && runningApps.size() > 0) {
7734 Set<String> extList = new HashSet<String>();
7735 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7736 if (app.pkgList != null) {
7737 for (String pkg : app.pkgList) {
7738 extList.add(pkg);
7739 }
7740 }
7741 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007742 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007743 for (String pkg : extList) {
7744 try {
7745 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7746 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7747 retList.add(info);
7748 }
7749 } catch (RemoteException e) {
7750 }
7751 }
7752 }
7753 return retList;
7754 }
7755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007756 @Override
7757 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007758 if (checkCallingPermission(android.Manifest.permission.DUMP)
7759 != PackageManager.PERMISSION_GRANTED) {
7760 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7761 + Binder.getCallingPid()
7762 + ", uid=" + Binder.getCallingUid()
7763 + " without permission "
7764 + android.Manifest.permission.DUMP);
7765 return;
7766 }
7767
7768 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007769 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007770
7771 int opti = 0;
7772 while (opti < args.length) {
7773 String opt = args[opti];
7774 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7775 break;
7776 }
7777 opti++;
7778 if ("-a".equals(opt)) {
7779 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007780 } else if ("-c".equals(opt)) {
7781 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007782 } else if ("-h".equals(opt)) {
7783 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007784 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007785 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007786 pw.println(" a[ctivities]: activity stack state");
7787 pw.println(" b[roadcasts]: broadcast state");
7788 pw.println(" i[ntents]: pending intent state");
7789 pw.println(" p[rocesses]: process state");
7790 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007791 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7792 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007793 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007794 pw.println(" all: dump all activities");
7795 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007796 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007797 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7798 pw.println(" a partial substring in a component name, a");
7799 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007800 pw.println(" -a: include all available server state.");
7801 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007803 } else {
7804 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007805 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007806 }
7807
7808 // Is the caller requesting to dump a particular piece of data?
7809 if (opti < args.length) {
7810 String cmd = args[opti];
7811 opti++;
7812 if ("activities".equals(cmd) || "a".equals(cmd)) {
7813 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007814 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007815 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007816 return;
7817 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7818 synchronized (this) {
7819 dumpBroadcastsLocked(fd, pw, args, opti, true);
7820 }
7821 return;
7822 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7823 synchronized (this) {
7824 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7825 }
7826 return;
7827 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7828 synchronized (this) {
7829 dumpProcessesLocked(fd, pw, args, opti, true);
7830 }
7831 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007832 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7833 synchronized (this) {
7834 dumpOomLocked(fd, pw, args, opti, true);
7835 }
7836 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007837 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7838 synchronized (this) {
7839 dumpProvidersLocked(fd, pw, args, opti, true);
7840 }
7841 return;
7842 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007843 String[] newArgs;
7844 String name;
7845 if (opti >= args.length) {
7846 name = null;
7847 newArgs = EMPTY_STRING_ARRAY;
7848 } else {
7849 name = args[opti];
7850 opti++;
7851 newArgs = new String[args.length - opti];
7852 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7853 }
7854 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7855 pw.println("No services match: " + name);
7856 pw.println("Use -h for help.");
7857 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007858 return;
7859 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7860 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007861 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007862 }
7863 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007864 } else {
7865 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007866 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7867 pw.println("Bad activity command, or no activities match: " + cmd);
7868 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007869 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007870 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007871 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007872 }
7873
7874 // No piece of data specified, dump everything.
7875 synchronized (this) {
7876 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007877 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007878 if (needSep) {
7879 pw.println(" ");
7880 }
7881 if (dumpAll) {
7882 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007883 }
7884 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7885 if (needSep) {
7886 pw.println(" ");
7887 }
7888 if (dumpAll) {
7889 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007890 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007891 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007892 if (needSep) {
7893 pw.println(" ");
7894 }
7895 if (dumpAll) {
7896 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007897 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007898 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007899 if (needSep) {
7900 pw.println(" ");
7901 }
7902 if (dumpAll) {
7903 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007904 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007905 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007906 if (needSep) {
7907 pw.println(" ");
7908 }
7909 if (dumpAll) {
7910 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911 }
7912 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7913 }
7914 }
7915
7916 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007917 int opti, boolean dumpAll, boolean dumpClient) {
7918 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7919 pw.println(" Main stack:");
7920 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007921 pw.println(" ");
7922 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007923 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007924 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007926 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007927 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7928 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007930 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007931 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007932 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007933 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7934 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007935 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007936 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7937 pw.println(" ");
7938 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007939 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7940 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007941 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007942 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007943 pw.println(" ");
7944 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007945 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7946 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007949 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007950 if (mMainStack.mPausingActivity != null) {
7951 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7952 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007953 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007954 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007955 if (dumpAll) {
7956 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7957 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007958 pw.println(" mDismissKeyguardOnNextActivity: "
7959 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007961
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007962 if (mRecentTasks.size() > 0) {
7963 pw.println();
7964 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007965
7966 final int N = mRecentTasks.size();
7967 for (int i=0; i<N; i++) {
7968 TaskRecord tr = mRecentTasks.get(i);
7969 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7970 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007971 if (dumpAll) {
7972 mRecentTasks.get(i).dump(pw, " ");
7973 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007974 }
7975 }
7976
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007977 if (dumpAll) {
7978 pw.println(" ");
7979 pw.println(" mCurTask: " + mCurTask);
7980 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007981
7982 return true;
7983 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007984
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007985 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7986 int opti, boolean dumpAll) {
7987 boolean needSep = false;
7988 int numPers = 0;
7989
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007990 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7991
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007992 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007993 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7994 final int NA = procs.size();
7995 for (int ia=0; ia<NA; ia++) {
7996 if (!needSep) {
7997 pw.println(" All known processes:");
7998 needSep = true;
7999 }
8000 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008001 pw.print(r.persistent ? " *PERS*" : " *APP*");
8002 pw.print(" UID "); pw.print(procs.keyAt(ia));
8003 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 r.dump(pw, " ");
8005 if (r.persistent) {
8006 numPers++;
8007 }
8008 }
8009 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008010 }
8011
8012 if (mLruProcesses.size() > 0) {
8013 if (needSep) pw.println(" ");
8014 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008015 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008016 dumpProcessOomList(pw, this, mLruProcesses, " ",
8017 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008018 needSep = true;
8019 }
8020
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008021 if (dumpAll) {
8022 synchronized (mPidsSelfLocked) {
8023 if (mPidsSelfLocked.size() > 0) {
8024 if (needSep) pw.println(" ");
8025 needSep = true;
8026 pw.println(" PID mappings:");
8027 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8028 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8029 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008031 }
8032 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008033 }
8034
8035 if (mForegroundProcesses.size() > 0) {
8036 if (needSep) pw.println(" ");
8037 needSep = true;
8038 pw.println(" Foreground Processes:");
8039 for (int i=0; i<mForegroundProcesses.size(); i++) {
8040 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8041 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008042 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008043 }
8044
8045 if (mPersistentStartingProcesses.size() > 0) {
8046 if (needSep) pw.println(" ");
8047 needSep = true;
8048 pw.println(" Persisent processes that are starting:");
8049 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008050 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008052
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008053 if (mRemovedProcesses.size() > 0) {
8054 if (needSep) pw.println(" ");
8055 needSep = true;
8056 pw.println(" Processes that are being removed:");
8057 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008058 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008059 }
8060
8061 if (mProcessesOnHold.size() > 0) {
8062 if (needSep) pw.println(" ");
8063 needSep = true;
8064 pw.println(" Processes that are on old until the system is ready:");
8065 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008066 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068
Dianne Hackborn287952c2010-09-22 22:34:31 -07008069 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070
8071 if (mProcessCrashTimes.getMap().size() > 0) {
8072 if (needSep) pw.println(" ");
8073 needSep = true;
8074 pw.println(" Time since processes crashed:");
8075 long now = SystemClock.uptimeMillis();
8076 for (Map.Entry<String, SparseArray<Long>> procs
8077 : mProcessCrashTimes.getMap().entrySet()) {
8078 SparseArray<Long> uids = procs.getValue();
8079 final int N = uids.size();
8080 for (int i=0; i<N; i++) {
8081 pw.print(" Process "); pw.print(procs.getKey());
8082 pw.print(" uid "); pw.print(uids.keyAt(i));
8083 pw.print(": last crashed ");
8084 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008085 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008086 }
8087 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008090 if (mBadProcesses.getMap().size() > 0) {
8091 if (needSep) pw.println(" ");
8092 needSep = true;
8093 pw.println(" Bad processes:");
8094 for (Map.Entry<String, SparseArray<Long>> procs
8095 : mBadProcesses.getMap().entrySet()) {
8096 SparseArray<Long> uids = procs.getValue();
8097 final int N = uids.size();
8098 for (int i=0; i<N; i++) {
8099 pw.print(" Bad process "); pw.print(procs.getKey());
8100 pw.print(" uid "); pw.print(uids.keyAt(i));
8101 pw.print(": crashed at time ");
8102 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 }
8104 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008106
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008107 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008108 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008109 if (mHeavyWeightProcess != null) {
8110 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8111 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008112 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008113 if (dumpAll) {
8114 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008115 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008116 pw.println(" mScreenCompatPackages:");
8117 for (Map.Entry<String, Integer> entry
8118 : mCompatModePackages.getPackages().entrySet()) {
8119 String pkg = entry.getKey();
8120 int mode = entry.getValue();
8121 pw.print(" "); pw.print(pkg); pw.print(": ");
8122 pw.print(mode); pw.println();
8123 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008124 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008125 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008126 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8127 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8128 || mOrigWaitForDebugger) {
8129 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8130 + " mDebugTransient=" + mDebugTransient
8131 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8132 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008133 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8134 || mProfileFd != null) {
8135 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8136 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8137 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8138 + mAutoStopProfiler);
8139 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008140 if (mAlwaysFinishActivities || mController != null) {
8141 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8142 + " mController=" + mController);
8143 }
8144 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008145 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008147 + " mProcessesReady=" + mProcessesReady
8148 + " mSystemReady=" + mSystemReady);
8149 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 + " mBooted=" + mBooted
8151 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008152 pw.print(" mLastPowerCheckRealtime=");
8153 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8154 pw.println("");
8155 pw.print(" mLastPowerCheckUptime=");
8156 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8157 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008158 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8159 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008160 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008161 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008162
8163 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164 }
8165
Dianne Hackborn287952c2010-09-22 22:34:31 -07008166 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8167 int opti, boolean needSep, boolean dumpAll) {
8168 if (mProcessesToGc.size() > 0) {
8169 if (needSep) pw.println(" ");
8170 needSep = true;
8171 pw.println(" Processes that are waiting to GC:");
8172 long now = SystemClock.uptimeMillis();
8173 for (int i=0; i<mProcessesToGc.size(); i++) {
8174 ProcessRecord proc = mProcessesToGc.get(i);
8175 pw.print(" Process "); pw.println(proc);
8176 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8177 pw.print(", last gced=");
8178 pw.print(now-proc.lastRequestedGc);
8179 pw.print(" ms ago, last lowMem=");
8180 pw.print(now-proc.lastLowMemory);
8181 pw.println(" ms ago");
8182
8183 }
8184 }
8185 return needSep;
8186 }
8187
8188 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8189 int opti, boolean dumpAll) {
8190 boolean needSep = false;
8191
8192 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008193 if (needSep) pw.println(" ");
8194 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008195 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008196 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8197 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8198 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8199 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8200 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8201 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8202 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8203 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8204 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8205 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8206 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008207
8208 if (needSep) pw.println(" ");
8209 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008210 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008211 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008212 "Proc", "PERS", true);
8213 needSep = true;
8214 }
8215
8216 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8217
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008218 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008219 pw.println(" mHomeProcess: " + mHomeProcess);
8220 if (mHeavyWeightProcess != null) {
8221 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8222 }
8223
8224 return true;
8225 }
8226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227 /**
8228 * There are three ways to call this:
8229 * - no service specified: dump all the services
8230 * - a flattened component name that matched an existing service was specified as the
8231 * first arg: dump that one service
8232 * - the first arg isn't the flattened component name of an existing service:
8233 * dump all services whose component contains the first arg as a substring
8234 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008235 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8236 int opti, boolean dumpAll) {
8237 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008239 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008240 synchronized (this) {
8241 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008242 services.add(r1);
8243 }
8244 }
8245 } else {
8246 ComponentName componentName = name != null
8247 ? ComponentName.unflattenFromString(name) : null;
8248 int objectId = 0;
8249 if (componentName == null) {
8250 // Not a '/' separated full component name; maybe an object ID?
8251 try {
8252 objectId = Integer.parseInt(name, 16);
8253 name = null;
8254 componentName = null;
8255 } catch (RuntimeException e) {
8256 }
8257 }
8258
8259 synchronized (this) {
8260 for (ServiceRecord r1 : mServices.values()) {
8261 if (componentName != null) {
8262 if (r1.name.equals(componentName)) {
8263 services.add(r1);
8264 }
8265 } else if (name != null) {
8266 if (r1.name.flattenToString().contains(name)) {
8267 services.add(r1);
8268 }
8269 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008270 services.add(r1);
8271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008272 }
8273 }
8274 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008275
8276 if (services.size() <= 0) {
8277 return false;
8278 }
8279
8280 boolean needSep = false;
8281 for (int i=0; i<services.size(); i++) {
8282 if (needSep) {
8283 pw.println();
8284 }
8285 needSep = true;
8286 dumpService("", fd, pw, services.get(i), args, dumpAll);
8287 }
8288 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289 }
8290
8291 /**
8292 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8293 * there is a thread associated with the service.
8294 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008295 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8296 final ServiceRecord r, String[] args, boolean dumpAll) {
8297 String innerPrefix = prefix + " ";
8298 synchronized (this) {
8299 pw.print(prefix); pw.print("SERVICE ");
8300 pw.print(r.shortName); pw.print(" ");
8301 pw.print(Integer.toHexString(System.identityHashCode(r)));
8302 pw.print(" pid=");
8303 if (r.app != null) pw.println(r.app.pid);
8304 else pw.println("(not running)");
8305 if (dumpAll) {
8306 r.dump(pw, innerPrefix);
8307 }
8308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008309 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008310 pw.print(prefix); pw.println(" Client:");
8311 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008312 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008313 TransferPipe tp = new TransferPipe();
8314 try {
8315 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8316 tp.setBufferPrefix(prefix + " ");
8317 tp.go(fd);
8318 } finally {
8319 tp.kill();
8320 }
8321 } catch (IOException e) {
8322 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008323 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008324 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008325 }
8326 }
8327 }
8328
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008329 static class ItemMatcher {
8330 ArrayList<ComponentName> components;
8331 ArrayList<String> strings;
8332 ArrayList<Integer> objects;
8333 boolean all;
8334
8335 ItemMatcher() {
8336 all = true;
8337 }
8338
8339 void build(String name) {
8340 ComponentName componentName = ComponentName.unflattenFromString(name);
8341 if (componentName != null) {
8342 if (components == null) {
8343 components = new ArrayList<ComponentName>();
8344 }
8345 components.add(componentName);
8346 all = false;
8347 } else {
8348 int objectId = 0;
8349 // Not a '/' separated full component name; maybe an object ID?
8350 try {
8351 objectId = Integer.parseInt(name, 16);
8352 if (objects == null) {
8353 objects = new ArrayList<Integer>();
8354 }
8355 objects.add(objectId);
8356 all = false;
8357 } catch (RuntimeException e) {
8358 // Not an integer; just do string match.
8359 if (strings == null) {
8360 strings = new ArrayList<String>();
8361 }
8362 strings.add(name);
8363 all = false;
8364 }
8365 }
8366 }
8367
8368 int build(String[] args, int opti) {
8369 for (; opti<args.length; opti++) {
8370 String name = args[opti];
8371 if ("--".equals(name)) {
8372 return opti+1;
8373 }
8374 build(name);
8375 }
8376 return opti;
8377 }
8378
8379 boolean match(Object object, ComponentName comp) {
8380 if (all) {
8381 return true;
8382 }
8383 if (components != null) {
8384 for (int i=0; i<components.size(); i++) {
8385 if (components.get(i).equals(comp)) {
8386 return true;
8387 }
8388 }
8389 }
8390 if (objects != null) {
8391 for (int i=0; i<objects.size(); i++) {
8392 if (System.identityHashCode(object) == objects.get(i)) {
8393 return true;
8394 }
8395 }
8396 }
8397 if (strings != null) {
8398 String flat = comp.flattenToString();
8399 for (int i=0; i<strings.size(); i++) {
8400 if (flat.contains(strings.get(i))) {
8401 return true;
8402 }
8403 }
8404 }
8405 return false;
8406 }
8407 }
8408
Dianne Hackborn625ac272010-09-17 18:29:22 -07008409 /**
8410 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008411 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008412 * - the cmd arg isn't the flattened component name of an existing activity:
8413 * dump all activity whose component contains the cmd as a substring
8414 * - A hex number of the ActivityRecord object instance.
8415 */
8416 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8417 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008418 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008419
8420 if ("all".equals(name)) {
8421 synchronized (this) {
8422 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008423 activities.add(r1);
8424 }
8425 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008426 } else if ("top".equals(name)) {
8427 synchronized (this) {
8428 final int N = mMainStack.mHistory.size();
8429 if (N > 0) {
8430 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8431 }
8432 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008433 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008434 ItemMatcher matcher = new ItemMatcher();
8435 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008436
8437 synchronized (this) {
8438 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008439 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008440 activities.add(r1);
8441 }
8442 }
8443 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008444 }
8445
8446 if (activities.size() <= 0) {
8447 return false;
8448 }
8449
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008450 String[] newArgs = new String[args.length - opti];
8451 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8452
Dianne Hackborn30d71892010-12-11 10:37:55 -08008453 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008454 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008455 for (int i=activities.size()-1; i>=0; i--) {
8456 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008457 if (needSep) {
8458 pw.println();
8459 }
8460 needSep = true;
8461 synchronized (this) {
8462 if (lastTask != r.task) {
8463 lastTask = r.task;
8464 pw.print("TASK "); pw.print(lastTask.affinity);
8465 pw.print(" id="); pw.println(lastTask.taskId);
8466 if (dumpAll) {
8467 lastTask.dump(pw, " ");
8468 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008469 }
8470 }
8471 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008472 }
8473 return true;
8474 }
8475
8476 /**
8477 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8478 * there is a thread associated with the activity.
8479 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008480 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008481 final ActivityRecord r, String[] args, boolean dumpAll) {
8482 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008483 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008484 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8485 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8486 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008487 if (r.app != null) pw.println(r.app.pid);
8488 else pw.println("(not running)");
8489 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008490 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008491 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008492 }
8493 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008494 // flush anything that is already in the PrintWriter since the thread is going
8495 // to write to the file descriptor directly
8496 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008497 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008498 TransferPipe tp = new TransferPipe();
8499 try {
8500 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8501 innerPrefix, args);
8502 tp.go(fd);
8503 } finally {
8504 tp.kill();
8505 }
8506 } catch (IOException e) {
8507 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008508 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008509 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008510 }
8511 }
8512 }
8513
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008514 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8515 int opti, boolean dumpAll) {
8516 boolean needSep = false;
8517
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008518 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008519 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008520 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521 pw.println(" Registered Receivers:");
8522 Iterator it = mRegisteredReceivers.values().iterator();
8523 while (it.hasNext()) {
8524 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008525 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008526 r.dump(pw, " ");
8527 }
8528 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008529
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008530 pw.println();
8531 pw.println(" Receiver Resolver Table:");
8532 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008533 needSep = true;
8534 }
8535
8536 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8537 || mPendingBroadcast != null) {
8538 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008539 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008540 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008542 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8543 pw.println(" Broadcast #" + i + ":");
8544 mParallelBroadcasts.get(i).dump(pw, " ");
8545 }
8546 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008547 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008548 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008549 }
8550 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8551 pw.println(" Serialized Broadcast #" + i + ":");
8552 mOrderedBroadcasts.get(i).dump(pw, " ");
8553 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008554 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008555 pw.println(" Pending broadcast:");
8556 if (mPendingBroadcast != null) {
8557 mPendingBroadcast.dump(pw, " ");
8558 } else {
8559 pw.println(" (null)");
8560 }
8561 needSep = true;
8562 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008564 if (needSep) {
8565 pw.println();
8566 }
8567 pw.println(" Historical broadcasts:");
8568 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8569 BroadcastRecord r = mBroadcastHistory[i];
8570 if (r == null) {
8571 break;
8572 }
8573 if (dumpAll) {
8574 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8575 r.dump(pw, " ");
8576 } else {
8577 if (i >= 50) {
8578 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008579 break;
8580 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008581 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008582 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008583 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008584 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008585
8586 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008587 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008588 pw.println(" Sticky broadcasts:");
8589 StringBuilder sb = new StringBuilder(128);
8590 for (Map.Entry<String, ArrayList<Intent>> ent
8591 : mStickyBroadcasts.entrySet()) {
8592 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008593 if (dumpAll) {
8594 pw.println(":");
8595 ArrayList<Intent> intents = ent.getValue();
8596 final int N = intents.size();
8597 for (int i=0; i<N; i++) {
8598 sb.setLength(0);
8599 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008600 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008601 pw.println(sb.toString());
8602 Bundle bundle = intents.get(i).getExtras();
8603 if (bundle != null) {
8604 pw.print(" ");
8605 pw.println(bundle.toString());
8606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008607 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008608 } else {
8609 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 }
8611 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008612 needSep = true;
8613 }
8614
8615 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008616 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008617 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 pw.println(" mHandler:");
8619 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008620 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008622
8623 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008624 }
8625
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008626 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008627 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008628 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008629
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008630 ItemMatcher matcher = new ItemMatcher();
8631 matcher.build(args, opti);
8632
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008633 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8634 if (mServices.size() > 0) {
8635 pw.println(" Active services:");
8636 long nowReal = SystemClock.elapsedRealtime();
8637 Iterator<ServiceRecord> it = mServices.values().iterator();
8638 needSep = false;
8639 while (it.hasNext()) {
8640 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008641 if (!matcher.match(r, r.name)) {
8642 continue;
8643 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008644 if (needSep) {
8645 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008646 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008647 pw.print(" * "); pw.println(r);
8648 if (dumpAll) {
8649 r.dump(pw, " ");
8650 needSep = true;
8651 } else {
8652 pw.print(" app="); pw.println(r.app);
8653 pw.print(" created=");
8654 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8655 pw.print(" started="); pw.print(r.startRequested);
8656 pw.print(" connections="); pw.println(r.connections.size());
8657 }
8658 if (dumpClient && r.app != null && r.app.thread != null) {
8659 pw.println(" Client:");
8660 pw.flush();
8661 try {
8662 TransferPipe tp = new TransferPipe();
8663 try {
8664 r.app.thread.dumpService(
8665 tp.getWriteFd().getFileDescriptor(), r, args);
8666 tp.setBufferPrefix(" ");
8667 // Short timeout, since blocking here can
8668 // deadlock with the application.
8669 tp.go(fd, 2000);
8670 } finally {
8671 tp.kill();
8672 }
8673 } catch (IOException e) {
8674 pw.println(" Failure while dumping the service: " + e);
8675 } catch (RemoteException e) {
8676 pw.println(" Got a RemoteException while dumping the service");
8677 }
8678 needSep = true;
8679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008680 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008681 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008683
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008684 if (mPendingServices.size() > 0) {
8685 if (needSep) pw.println(" ");
8686 pw.println(" Pending services:");
8687 for (int i=0; i<mPendingServices.size(); i++) {
8688 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008689 if (!matcher.match(r, r.name)) {
8690 continue;
8691 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008692 pw.print(" * Pending "); pw.println(r);
8693 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008694 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008695 needSep = true;
8696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008697
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008698 if (mRestartingServices.size() > 0) {
8699 if (needSep) pw.println(" ");
8700 pw.println(" Restarting services:");
8701 for (int i=0; i<mRestartingServices.size(); i++) {
8702 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008703 if (!matcher.match(r, r.name)) {
8704 continue;
8705 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008706 pw.print(" * Restarting "); pw.println(r);
8707 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008709 needSep = true;
8710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008711
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008712 if (mStoppingServices.size() > 0) {
8713 if (needSep) pw.println(" ");
8714 pw.println(" Stopping services:");
8715 for (int i=0; i<mStoppingServices.size(); i++) {
8716 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008717 if (!matcher.match(r, r.name)) {
8718 continue;
8719 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008720 pw.print(" * Stopping "); pw.println(r);
8721 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008722 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008723 needSep = true;
8724 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008725
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008726 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008727 if (mServiceConnections.size() > 0) {
8728 if (needSep) pw.println(" ");
8729 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008730 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008731 = mServiceConnections.values().iterator();
8732 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008733 ArrayList<ConnectionRecord> r = it.next();
8734 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008735 ConnectionRecord cr = r.get(i);
8736 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8737 continue;
8738 }
8739 pw.print(" * "); pw.println(cr);
8740 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008743 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008744 }
8745 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008746
8747 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008748 }
8749
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008750 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8751 int opti, boolean dumpAll) {
8752 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008753
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008754 ItemMatcher matcher = new ItemMatcher();
8755 matcher.build(args, opti);
8756
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008757 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8758 if (mProvidersByClass.size() > 0) {
8759 if (needSep) pw.println(" ");
8760 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008761 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008762 = mProvidersByClass.entrySet().iterator();
8763 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008764 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008765 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008766 ComponentName comp = e.getKey();
8767 String cls = comp.getClassName();
8768 int end = cls.lastIndexOf('.');
8769 if (end > 0 && end < (cls.length()-2)) {
8770 cls = cls.substring(end+1);
8771 }
8772 if (!matcher.match(r, comp)) {
8773 continue;
8774 }
8775 pw.print(" * "); pw.print(cls); pw.print(" (");
8776 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008777 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008778 pw.println();
8779 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008780 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008781 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008782 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008783 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008784 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008785 } else {
8786 pw.println();
8787 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008789 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008790 needSep = true;
8791 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008792
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008793 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008794 if (mProvidersByName.size() > 0) {
8795 pw.println(" ");
8796 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008797 Iterator<Map.Entry<String, ContentProviderRecord>> it
8798 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008799 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008800 Map.Entry<String, ContentProviderRecord> e = it.next();
8801 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008802 if (!matcher.match(r, r.name)) {
8803 continue;
8804 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008805 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8806 pw.println(r);
8807 }
8808 needSep = true;
8809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008810 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008811
8812 if (mLaunchingProviders.size() > 0) {
8813 if (needSep) pw.println(" ");
8814 pw.println(" Launching content providers:");
8815 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8816 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8817 pw.println(mLaunchingProviders.get(i));
8818 }
8819 needSep = true;
8820 }
8821
8822 if (mGrantedUriPermissions.size() > 0) {
8823 pw.println();
8824 pw.println("Granted Uri Permissions:");
8825 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8826 int uid = mGrantedUriPermissions.keyAt(i);
8827 HashMap<Uri, UriPermission> perms
8828 = mGrantedUriPermissions.valueAt(i);
8829 pw.print(" * UID "); pw.print(uid);
8830 pw.println(" holds:");
8831 for (UriPermission perm : perms.values()) {
8832 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008833 if (dumpAll) {
8834 perm.dump(pw, " ");
8835 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008836 }
8837 }
8838 needSep = true;
8839 }
8840
8841 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008842 }
8843
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008844 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8845 int opti, boolean dumpAll) {
8846 boolean needSep = false;
8847
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008848 if (this.mIntentSenderRecords.size() > 0) {
8849 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8850 Iterator<WeakReference<PendingIntentRecord>> it
8851 = mIntentSenderRecords.values().iterator();
8852 while (it.hasNext()) {
8853 WeakReference<PendingIntentRecord> ref = it.next();
8854 PendingIntentRecord rec = ref != null ? ref.get(): null;
8855 needSep = true;
8856 if (rec != null) {
8857 pw.print(" * "); pw.println(rec);
8858 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008859 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008860 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 } else {
8862 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008863 }
8864 }
8865 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008866
8867 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008868 }
8869
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008870 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8871 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008872 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008873 boolean needNL = false;
8874 final String innerPrefix = prefix + " ";
8875 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008876 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008877 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008878 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008879 if (needNL) {
8880 pw.println(" ");
8881 needNL = false;
8882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 if (lastTask != r.task) {
8884 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008885 pw.print(prefix);
8886 pw.print(full ? "* " : " ");
8887 pw.println(lastTask);
8888 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008889 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008890 } else if (complete) {
8891 // Complete + brief == give a summary. Isn't that obvious?!?
8892 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008893 pw.print(prefix); pw.print(" ");
8894 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008895 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008897 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008898 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8899 pw.print(" #"); pw.print(i); pw.print(": ");
8900 pw.println(r);
8901 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008902 r.dump(pw, innerPrefix);
8903 } else if (complete) {
8904 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008905 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008906 if (r.app != null) {
8907 pw.print(innerPrefix); pw.println(r.app);
8908 }
8909 }
8910 if (client && r.app != null && r.app.thread != null) {
8911 // flush anything that is already in the PrintWriter since the thread is going
8912 // to write to the file descriptor directly
8913 pw.flush();
8914 try {
8915 TransferPipe tp = new TransferPipe();
8916 try {
8917 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8918 innerPrefix, args);
8919 // Short timeout, since blocking here can
8920 // deadlock with the application.
8921 tp.go(fd, 2000);
8922 } finally {
8923 tp.kill();
8924 }
8925 } catch (IOException e) {
8926 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8927 } catch (RemoteException e) {
8928 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8929 }
8930 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008932 }
8933 }
8934
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008935 private static String buildOomTag(String prefix, String space, int val, int base) {
8936 if (val == base) {
8937 if (space == null) return prefix;
8938 return prefix + " ";
8939 }
8940 return prefix + "+" + Integer.toString(val-base);
8941 }
8942
8943 private static final int dumpProcessList(PrintWriter pw,
8944 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008945 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008946 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008947 final int N = list.size()-1;
8948 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008949 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008950 pw.println(String.format("%s%s #%2d: %s",
8951 prefix, (r.persistent ? persistentLabel : normalLabel),
8952 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008953 if (r.persistent) {
8954 numPers++;
8955 }
8956 }
8957 return numPers;
8958 }
8959
Dianne Hackborn287952c2010-09-22 22:34:31 -07008960 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008961 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008962 String prefix, String normalLabel, String persistentLabel,
8963 boolean inclDetails) {
8964
Dianne Hackborn905577f2011-09-07 18:31:28 -07008965 ArrayList<Pair<ProcessRecord, Integer>> list
8966 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8967 for (int i=0; i<origList.size(); i++) {
8968 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8969 }
8970
8971 Comparator<Pair<ProcessRecord, Integer>> comparator
8972 = new Comparator<Pair<ProcessRecord, Integer>>() {
8973 @Override
8974 public int compare(Pair<ProcessRecord, Integer> object1,
8975 Pair<ProcessRecord, Integer> object2) {
8976 if (object1.first.setAdj != object2.first.setAdj) {
8977 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8978 }
8979 if (object1.second.intValue() != object2.second.intValue()) {
8980 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8981 }
8982 return 0;
8983 }
8984 };
8985
8986 Collections.sort(list, comparator);
8987
Dianne Hackborn287952c2010-09-22 22:34:31 -07008988 final long curRealtime = SystemClock.elapsedRealtime();
8989 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8990 final long curUptime = SystemClock.uptimeMillis();
8991 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8992
8993 final int N = list.size()-1;
8994 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008995 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008996 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008997 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8998 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8999 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9000 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9001 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9002 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9003 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
9004 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
9005 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9006 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9007 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9008 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9009 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9010 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9011 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9012 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9013 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9014 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9015 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
9016 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
9017 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9018 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009019 } else {
9020 oomAdj = Integer.toString(r.setAdj);
9021 }
9022 String schedGroup;
9023 switch (r.setSchedGroup) {
9024 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9025 schedGroup = "B";
9026 break;
9027 case Process.THREAD_GROUP_DEFAULT:
9028 schedGroup = "F";
9029 break;
9030 default:
9031 schedGroup = Integer.toString(r.setSchedGroup);
9032 break;
9033 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009034 String foreground;
9035 if (r.foregroundActivities) {
9036 foreground = "A";
9037 } else if (r.foregroundServices) {
9038 foreground = "S";
9039 } else {
9040 foreground = " ";
9041 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009042 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009043 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009044 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009045 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009046 if (r.adjSource != null || r.adjTarget != null) {
9047 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009048 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009049 if (r.adjTarget instanceof ComponentName) {
9050 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9051 } else if (r.adjTarget != null) {
9052 pw.print(r.adjTarget.toString());
9053 } else {
9054 pw.print("{null}");
9055 }
9056 pw.print("<=");
9057 if (r.adjSource instanceof ProcessRecord) {
9058 pw.print("Proc{");
9059 pw.print(((ProcessRecord)r.adjSource).toShortString());
9060 pw.println("}");
9061 } else if (r.adjSource != null) {
9062 pw.println(r.adjSource.toString());
9063 } else {
9064 pw.println("{null}");
9065 }
9066 }
9067 if (inclDetails) {
9068 pw.print(prefix);
9069 pw.print(" ");
9070 pw.print("oom: max="); pw.print(r.maxAdj);
9071 pw.print(" hidden="); pw.print(r.hiddenAdj);
9072 pw.print(" curRaw="); pw.print(r.curRawAdj);
9073 pw.print(" setRaw="); pw.print(r.setRawAdj);
9074 pw.print(" cur="); pw.print(r.curAdj);
9075 pw.print(" set="); pw.println(r.setAdj);
9076 pw.print(prefix);
9077 pw.print(" ");
9078 pw.print("keeping="); pw.print(r.keeping);
9079 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009080 pw.print(" empty="); pw.print(r.empty);
9081 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009082
9083 if (!r.keeping) {
9084 if (r.lastWakeTime != 0) {
9085 long wtime;
9086 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9087 synchronized (stats) {
9088 wtime = stats.getProcessWakeTime(r.info.uid,
9089 r.pid, curRealtime);
9090 }
9091 long timeUsed = wtime - r.lastWakeTime;
9092 pw.print(prefix);
9093 pw.print(" ");
9094 pw.print("keep awake over ");
9095 TimeUtils.formatDuration(realtimeSince, pw);
9096 pw.print(" used ");
9097 TimeUtils.formatDuration(timeUsed, pw);
9098 pw.print(" (");
9099 pw.print((timeUsed*100)/realtimeSince);
9100 pw.println("%)");
9101 }
9102 if (r.lastCpuTime != 0) {
9103 long timeUsed = r.curCpuTime - r.lastCpuTime;
9104 pw.print(prefix);
9105 pw.print(" ");
9106 pw.print("run cpu over ");
9107 TimeUtils.formatDuration(uptimeSince, pw);
9108 pw.print(" used ");
9109 TimeUtils.formatDuration(timeUsed, pw);
9110 pw.print(" (");
9111 pw.print((timeUsed*100)/uptimeSince);
9112 pw.println("%)");
9113 }
9114 }
9115 }
9116 }
9117 }
9118
Dianne Hackbornb437e092011-08-05 17:50:29 -07009119 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009120 ArrayList<ProcessRecord> procs;
9121 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009122 if (args != null && args.length > start
9123 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009124 procs = new ArrayList<ProcessRecord>();
9125 int pid = -1;
9126 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009127 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009128 } catch (NumberFormatException e) {
9129
9130 }
9131 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9132 ProcessRecord proc = mLruProcesses.get(i);
9133 if (proc.pid == pid) {
9134 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009135 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009136 procs.add(proc);
9137 }
9138 }
9139 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009140 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009141 return null;
9142 }
9143 } else {
9144 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9145 }
9146 }
9147 return procs;
9148 }
9149
9150 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9151 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009152 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009153 if (procs == null) {
9154 return;
9155 }
9156
9157 long uptime = SystemClock.uptimeMillis();
9158 long realtime = SystemClock.elapsedRealtime();
9159 pw.println("Applications Graphics Acceleration Info:");
9160 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9161
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009162 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9163 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009164 if (r.thread != null) {
9165 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9166 pw.flush();
9167 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009168 TransferPipe tp = new TransferPipe();
9169 try {
9170 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9171 tp.go(fd);
9172 } finally {
9173 tp.kill();
9174 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009175 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009176 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009177 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009178 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009179 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009180 pw.flush();
9181 }
9182 }
9183 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009184 }
9185
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009186 final static class MemItem {
9187 final String label;
9188 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009189 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009190
9191 public MemItem(String _label, long _pss) {
9192 label = _label;
9193 pss = _pss;
9194 }
9195 }
9196
Dianne Hackbornb437e092011-08-05 17:50:29 -07009197 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9198 boolean sort) {
9199 if (sort) {
9200 Collections.sort(items, new Comparator<MemItem>() {
9201 @Override
9202 public int compare(MemItem lhs, MemItem rhs) {
9203 if (lhs.pss < rhs.pss) {
9204 return 1;
9205 } else if (lhs.pss > rhs.pss) {
9206 return -1;
9207 }
9208 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009209 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009210 });
9211 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009212
9213 for (int i=0; i<items.size(); i++) {
9214 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009215 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9216 if (mi.subitems != null) {
9217 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9218 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009219 }
9220 }
9221
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009222 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9223 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009224 boolean dumpAll = false;
9225
9226 int opti = 0;
9227 while (opti < args.length) {
9228 String opt = args[opti];
9229 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9230 break;
9231 }
9232 opti++;
9233 if ("-a".equals(opt)) {
9234 dumpAll = true;
9235 } else if ("-h".equals(opt)) {
9236 pw.println("meminfo dump options: [-a] [process]");
9237 pw.println(" -a: include all available information for each process.");
9238 pw.println("If [process] is specified it can be the name or ");
9239 pw.println("pid of a specific process to dump.");
9240 return;
9241 } else {
9242 pw.println("Unknown argument: " + opt + "; use -h for help");
9243 }
9244 }
9245
9246 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009247 if (procs == null) {
9248 return;
9249 }
9250
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009251 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252 long uptime = SystemClock.uptimeMillis();
9253 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009254
9255 if (procs.size() == 1 || isCheckinRequest) {
9256 dumpAll = true;
9257 }
9258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009259 if (isCheckinRequest) {
9260 // short checkin version
9261 pw.println(uptime + "," + realtime);
9262 pw.flush();
9263 } else {
9264 pw.println("Applications Memory Usage (kB):");
9265 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9266 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009267
Dianne Hackbornb437e092011-08-05 17:50:29 -07009268 String[] innerArgs = new String[args.length-opti];
9269 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9270
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009271 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9272 long nativePss=0, dalvikPss=0, otherPss=0;
9273 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9274
Dianne Hackbornb437e092011-08-05 17:50:29 -07009275 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009276 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9277 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9278 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009279 };
9280 final String[] oomLabel = new String[] {
9281 "System", "Persistent", "Foreground",
9282 "Visible", "Perceptible", "Heavy Weight",
9283 "Backup", "Services", "Home", "Background"
9284 };
9285 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009286 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009287
9288 long totalPss = 0;
9289
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009290 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9291 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009292 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009293 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9295 pw.flush();
9296 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009297 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009298 if (dumpAll) {
9299 try {
9300 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9301 } catch (RemoteException e) {
9302 if (!isCheckinRequest) {
9303 pw.println("Got RemoteException!");
9304 pw.flush();
9305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009307 } else {
9308 mi = new Debug.MemoryInfo();
9309 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009310 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009311
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009312 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009313 long myTotalPss = mi.getTotalPss();
9314 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009315 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9316 myTotalPss);
9317 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009318
9319 nativePss += mi.nativePss;
9320 dalvikPss += mi.dalvikPss;
9321 otherPss += mi.otherPss;
9322 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9323 long mem = mi.getOtherPss(j);
9324 miscPss[j] += mem;
9325 otherPss -= mem;
9326 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009327
9328 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9329 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9330 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009331 if (oomProcs[oomIndex] == null) {
9332 oomProcs[oomIndex] = new ArrayList<MemItem>();
9333 }
9334 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009335 break;
9336 }
9337 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009339 }
9340 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009341
9342 if (!isCheckinRequest && procs.size() > 1) {
9343 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9344
9345 catMems.add(new MemItem("Native", nativePss));
9346 catMems.add(new MemItem("Dalvik", dalvikPss));
9347 catMems.add(new MemItem("Unknown", otherPss));
9348 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9349 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9350 }
9351
Dianne Hackbornb437e092011-08-05 17:50:29 -07009352 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9353 for (int j=0; j<oomPss.length; j++) {
9354 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009355 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9356 item.subitems = oomProcs[j];
9357 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009358 }
9359 }
9360
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009361 pw.println();
9362 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009363 dumpMemItems(pw, " ", procMems, true);
9364 pw.println();
9365 pw.println("Total PSS by OOM adjustment:");
9366 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009367 pw.println();
9368 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009369 dumpMemItems(pw, " ", catMems, true);
9370 pw.println();
9371 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009373 }
9374
9375 /**
9376 * Searches array of arguments for the specified string
9377 * @param args array of argument strings
9378 * @param value value to search for
9379 * @return true if the value is contained in the array
9380 */
9381 private static boolean scanArgs(String[] args, String value) {
9382 if (args != null) {
9383 for (String arg : args) {
9384 if (value.equals(arg)) {
9385 return true;
9386 }
9387 }
9388 }
9389 return false;
9390 }
9391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009392 private final void killServicesLocked(ProcessRecord app,
9393 boolean allowRestart) {
9394 // Report disconnected services.
9395 if (false) {
9396 // XXX we are letting the client link to the service for
9397 // death notifications.
9398 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009399 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009401 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009402 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009403 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009404 = r.connections.values().iterator();
9405 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009406 ArrayList<ConnectionRecord> cl = jt.next();
9407 for (int i=0; i<cl.size(); i++) {
9408 ConnectionRecord c = cl.get(i);
9409 if (c.binding.client != app) {
9410 try {
9411 //c.conn.connected(r.className, null);
9412 } catch (Exception e) {
9413 // todo: this should be asynchronous!
9414 Slog.w(TAG, "Exception thrown disconnected servce "
9415 + r.shortName
9416 + " from app " + app.processName, e);
9417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009418 }
9419 }
9420 }
9421 }
9422 }
9423 }
9424 }
9425
9426 // Clean up any connections this application has to other services.
9427 if (app.connections.size() > 0) {
9428 Iterator<ConnectionRecord> it = app.connections.iterator();
9429 while (it.hasNext()) {
9430 ConnectionRecord r = it.next();
9431 removeConnectionLocked(r, app, null);
9432 }
9433 }
9434 app.connections.clear();
9435
9436 if (app.services.size() != 0) {
9437 // Any services running in the application need to be placed
9438 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009439 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009440 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009441 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 synchronized (sr.stats.getBatteryStats()) {
9443 sr.stats.stopLaunchedLocked();
9444 }
9445 sr.app = null;
9446 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009447 if (mStoppingServices.remove(sr)) {
9448 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9449 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009450
9451 boolean hasClients = sr.bindings.size() > 0;
9452 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009453 Iterator<IntentBindRecord> bindings
9454 = sr.bindings.values().iterator();
9455 while (bindings.hasNext()) {
9456 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009457 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009458 + ": shouldUnbind=" + b.hasBound);
9459 b.binder = null;
9460 b.requested = b.received = b.hasBound = false;
9461 }
9462 }
9463
Dianne Hackborn070783f2010-12-29 16:46:28 -08009464 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9465 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009466 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009467 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009468 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009469 sr.crashCount, sr.shortName, app.pid);
9470 bringDownServiceLocked(sr, true);
9471 } else if (!allowRestart) {
9472 bringDownServiceLocked(sr, true);
9473 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009474 boolean canceled = scheduleServiceRestartLocked(sr, true);
9475
9476 // Should the service remain running? Note that in the
9477 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009478 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009479 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9480 if (sr.pendingStarts.size() == 0) {
9481 sr.startRequested = false;
9482 if (!hasClients) {
9483 // Whoops, no reason to restart!
9484 bringDownServiceLocked(sr, true);
9485 }
9486 }
9487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009488 }
9489 }
9490
9491 if (!allowRestart) {
9492 app.services.clear();
9493 }
9494 }
9495
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009496 // Make sure we have no more records on the stopping list.
9497 int i = mStoppingServices.size();
9498 while (i > 0) {
9499 i--;
9500 ServiceRecord sr = mStoppingServices.get(i);
9501 if (sr.app == app) {
9502 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009503 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009504 }
9505 }
9506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009507 app.executingServices.clear();
9508 }
9509
9510 private final void removeDyingProviderLocked(ProcessRecord proc,
9511 ContentProviderRecord cpr) {
9512 synchronized (cpr) {
9513 cpr.launchingApp = null;
9514 cpr.notifyAll();
9515 }
9516
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009517 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 String names[] = cpr.info.authority.split(";");
9519 for (int j = 0; j < names.length; j++) {
9520 mProvidersByName.remove(names[j]);
9521 }
9522
9523 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9524 while (cit.hasNext()) {
9525 ProcessRecord capp = cit.next();
9526 if (!capp.persistent && capp.thread != null
9527 && capp.pid != 0
9528 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009529 Slog.i(TAG, "Kill " + capp.processName
9530 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009531 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009532 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009533 capp.processName, capp.setAdj, "dying provider "
9534 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009535 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009536 }
9537 }
9538
9539 mLaunchingProviders.remove(cpr);
9540 }
9541
9542 /**
9543 * Main code for cleaning up a process when it has gone away. This is
9544 * called both as a result of the process dying, or directly when stopping
9545 * a process when running in single process mode.
9546 */
9547 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009548 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009550 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009551 }
9552
Dianne Hackborn36124872009-10-08 16:22:03 -07009553 mProcessesToGc.remove(app);
9554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 // Dismiss any open dialogs.
9556 if (app.crashDialog != null) {
9557 app.crashDialog.dismiss();
9558 app.crashDialog = null;
9559 }
9560 if (app.anrDialog != null) {
9561 app.anrDialog.dismiss();
9562 app.anrDialog = null;
9563 }
9564 if (app.waitDialog != null) {
9565 app.waitDialog.dismiss();
9566 app.waitDialog = null;
9567 }
9568
9569 app.crashing = false;
9570 app.notResponding = false;
9571
9572 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009573 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009574 app.thread = null;
9575 app.forcingToForeground = null;
9576 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009577 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009578 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009579 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009580
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009581 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009582
9583 boolean restart = false;
9584
9585 int NL = mLaunchingProviders.size();
9586
9587 // Remove published content providers.
9588 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009589 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009590 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009591 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009592 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009593 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009594
9595 // See if someone is waiting for this provider... in which
9596 // case we don't remove it, but just let it restart.
9597 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009598 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 for (; i<NL; i++) {
9600 if (mLaunchingProviders.get(i) == cpr) {
9601 restart = true;
9602 break;
9603 }
9604 }
9605 } else {
9606 i = NL;
9607 }
9608
9609 if (i >= NL) {
9610 removeDyingProviderLocked(app, cpr);
9611 NL = mLaunchingProviders.size();
9612 }
9613 }
9614 app.pubProviders.clear();
9615 }
9616
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009617 // Take care of any launching providers waiting for this process.
9618 if (checkAppInLaunchingProvidersLocked(app, false)) {
9619 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009620 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009622 // Unregister from connected content providers.
9623 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009624 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009625 while (it.hasNext()) {
9626 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9627 cpr.clients.remove(app);
9628 }
9629 app.conProviders.clear();
9630 }
9631
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009632 // At this point there may be remaining entries in mLaunchingProviders
9633 // where we were the only one waiting, so they are no longer of use.
9634 // Look for these and clean up if found.
9635 // XXX Commented out for now. Trying to figure out a way to reproduce
9636 // the actual situation to identify what is actually going on.
9637 if (false) {
9638 for (int i=0; i<NL; i++) {
9639 ContentProviderRecord cpr = (ContentProviderRecord)
9640 mLaunchingProviders.get(i);
9641 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9642 synchronized (cpr) {
9643 cpr.launchingApp = null;
9644 cpr.notifyAll();
9645 }
9646 }
9647 }
9648 }
9649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009650 skipCurrentReceiverLocked(app);
9651
9652 // Unregister any receivers.
9653 if (app.receivers.size() > 0) {
9654 Iterator<ReceiverList> it = app.receivers.iterator();
9655 while (it.hasNext()) {
9656 removeReceiverLocked(it.next());
9657 }
9658 app.receivers.clear();
9659 }
9660
Christopher Tate181fafa2009-05-14 11:12:14 -07009661 // If the app is undergoing backup, tell the backup manager about it
9662 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009663 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009664 try {
9665 IBackupManager bm = IBackupManager.Stub.asInterface(
9666 ServiceManager.getService(Context.BACKUP_SERVICE));
9667 bm.agentDisconnected(app.info.packageName);
9668 } catch (RemoteException e) {
9669 // can't happen; backup manager is local
9670 }
9671 }
9672
Jeff Sharkey287bd832011-05-28 19:36:26 -07009673 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009675 // If the caller is restarting this app, then leave it in its
9676 // current lists and let the caller take care of it.
9677 if (restarting) {
9678 return;
9679 }
9680
9681 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009682 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009683 "Removing non-persistent process during cleanup: " + app);
9684 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009685 if (mHeavyWeightProcess == app) {
9686 mHeavyWeightProcess = null;
9687 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009689 } else if (!app.removed) {
9690 // This app is persistent, so we need to keep its record around.
9691 // If it is not already on the pending app list, add it there
9692 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009693 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9694 mPersistentStartingProcesses.add(app);
9695 restart = true;
9696 }
9697 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009698 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9699 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 mProcessesOnHold.remove(app);
9701
The Android Open Source Project4df24232009-03-05 14:34:35 -08009702 if (app == mHomeProcess) {
9703 mHomeProcess = null;
9704 }
9705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009706 if (restart) {
9707 // We have components that still need to be running in the
9708 // process, so re-launch it.
9709 mProcessNames.put(app.processName, app.info.uid, app);
9710 startProcessLocked(app, "restart", app.processName);
9711 } else if (app.pid > 0 && app.pid != MY_PID) {
9712 // Goodbye!
9713 synchronized (mPidsSelfLocked) {
9714 mPidsSelfLocked.remove(app.pid);
9715 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9716 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009717 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009718 }
9719 }
9720
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009721 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9722 // Look through the content providers we are waiting to have launched,
9723 // and if any run in this process then either schedule a restart of
9724 // the process or kill the client waiting for it if this process has
9725 // gone bad.
9726 int NL = mLaunchingProviders.size();
9727 boolean restart = false;
9728 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009729 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009730 if (cpr.launchingApp == app) {
9731 if (!alwaysBad && !app.bad) {
9732 restart = true;
9733 } else {
9734 removeDyingProviderLocked(app, cpr);
9735 NL = mLaunchingProviders.size();
9736 }
9737 }
9738 }
9739 return restart;
9740 }
9741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009742 // =========================================================
9743 // SERVICES
9744 // =========================================================
9745
9746 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9747 ActivityManager.RunningServiceInfo info =
9748 new ActivityManager.RunningServiceInfo();
9749 info.service = r.name;
9750 if (r.app != null) {
9751 info.pid = r.app.pid;
9752 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009753 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754 info.process = r.processName;
9755 info.foreground = r.isForeground;
9756 info.activeSince = r.createTime;
9757 info.started = r.startRequested;
9758 info.clientCount = r.connections.size();
9759 info.crashCount = r.crashCount;
9760 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009761 if (r.isForeground) {
9762 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9763 }
9764 if (r.startRequested) {
9765 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9766 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009767 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009768 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9769 }
9770 if (r.app != null && r.app.persistent) {
9771 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9772 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009773
9774 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9775 for (int i=0; i<connl.size(); i++) {
9776 ConnectionRecord conn = connl.get(i);
9777 if (conn.clientLabel != 0) {
9778 info.clientPackage = conn.binding.client.info.packageName;
9779 info.clientLabel = conn.clientLabel;
9780 return info;
9781 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009782 }
9783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009784 return info;
9785 }
9786
9787 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9788 int flags) {
9789 synchronized (this) {
9790 ArrayList<ActivityManager.RunningServiceInfo> res
9791 = new ArrayList<ActivityManager.RunningServiceInfo>();
9792
9793 if (mServices.size() > 0) {
9794 Iterator<ServiceRecord> it = mServices.values().iterator();
9795 while (it.hasNext() && res.size() < maxNum) {
9796 res.add(makeRunningServiceInfoLocked(it.next()));
9797 }
9798 }
9799
9800 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9801 ServiceRecord r = mRestartingServices.get(i);
9802 ActivityManager.RunningServiceInfo info =
9803 makeRunningServiceInfoLocked(r);
9804 info.restarting = r.nextRestartTime;
9805 res.add(info);
9806 }
9807
9808 return res;
9809 }
9810 }
9811
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009812 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9813 synchronized (this) {
9814 ServiceRecord r = mServices.get(name);
9815 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009816 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9817 for (int i=0; i<conn.size(); i++) {
9818 if (conn.get(i).clientIntent != null) {
9819 return conn.get(i).clientIntent;
9820 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009821 }
9822 }
9823 }
9824 }
9825 return null;
9826 }
9827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 private final ServiceRecord findServiceLocked(ComponentName name,
9829 IBinder token) {
9830 ServiceRecord r = mServices.get(name);
9831 return r == token ? r : null;
9832 }
9833
9834 private final class ServiceLookupResult {
9835 final ServiceRecord record;
9836 final String permission;
9837
9838 ServiceLookupResult(ServiceRecord _record, String _permission) {
9839 record = _record;
9840 permission = _permission;
9841 }
9842 };
9843
9844 private ServiceLookupResult findServiceLocked(Intent service,
9845 String resolvedType) {
9846 ServiceRecord r = null;
9847 if (service.getComponent() != null) {
9848 r = mServices.get(service.getComponent());
9849 }
9850 if (r == null) {
9851 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9852 r = mServicesByIntent.get(filter);
9853 }
9854
9855 if (r == null) {
9856 try {
9857 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009858 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 service, resolvedType, 0);
9860 ServiceInfo sInfo =
9861 rInfo != null ? rInfo.serviceInfo : null;
9862 if (sInfo == null) {
9863 return null;
9864 }
9865
9866 ComponentName name = new ComponentName(
9867 sInfo.applicationInfo.packageName, sInfo.name);
9868 r = mServices.get(name);
9869 } catch (RemoteException ex) {
9870 // pm is in same process, this will never happen.
9871 }
9872 }
9873 if (r != null) {
9874 int callingPid = Binder.getCallingPid();
9875 int callingUid = Binder.getCallingUid();
9876 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009877 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009879 if (!r.exported) {
9880 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9881 + " from pid=" + callingPid
9882 + ", uid=" + callingUid
9883 + " that is not exported from uid " + r.appInfo.uid);
9884 return new ServiceLookupResult(null, "not exported from uid "
9885 + r.appInfo.uid);
9886 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009887 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009888 + " from pid=" + callingPid
9889 + ", uid=" + callingUid
9890 + " requires " + r.permission);
9891 return new ServiceLookupResult(null, r.permission);
9892 }
9893 return new ServiceLookupResult(r, null);
9894 }
9895 return null;
9896 }
9897
9898 private class ServiceRestarter implements Runnable {
9899 private ServiceRecord mService;
9900
9901 void setService(ServiceRecord service) {
9902 mService = service;
9903 }
9904
9905 public void run() {
9906 synchronized(ActivityManagerService.this) {
9907 performServiceRestartLocked(mService);
9908 }
9909 }
9910 }
9911
9912 private ServiceLookupResult retrieveServiceLocked(Intent service,
9913 String resolvedType, int callingPid, int callingUid) {
9914 ServiceRecord r = null;
9915 if (service.getComponent() != null) {
9916 r = mServices.get(service.getComponent());
9917 }
9918 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9919 r = mServicesByIntent.get(filter);
9920 if (r == null) {
9921 try {
9922 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009923 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009924 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 ServiceInfo sInfo =
9926 rInfo != null ? rInfo.serviceInfo : null;
9927 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009928 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009929 ": not found");
9930 return null;
9931 }
9932
9933 ComponentName name = new ComponentName(
9934 sInfo.applicationInfo.packageName, sInfo.name);
9935 r = mServices.get(name);
9936 if (r == null) {
9937 filter = new Intent.FilterComparison(service.cloneFilter());
9938 ServiceRestarter res = new ServiceRestarter();
9939 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9940 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9941 synchronized (stats) {
9942 ss = stats.getServiceStatsLocked(
9943 sInfo.applicationInfo.uid, sInfo.packageName,
9944 sInfo.name);
9945 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009946 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009947 res.setService(r);
9948 mServices.put(name, r);
9949 mServicesByIntent.put(filter, r);
9950
9951 // Make sure this component isn't in the pending list.
9952 int N = mPendingServices.size();
9953 for (int i=0; i<N; i++) {
9954 ServiceRecord pr = mPendingServices.get(i);
9955 if (pr.name.equals(name)) {
9956 mPendingServices.remove(i);
9957 i--;
9958 N--;
9959 }
9960 }
9961 }
9962 } catch (RemoteException ex) {
9963 // pm is in same process, this will never happen.
9964 }
9965 }
9966 if (r != null) {
9967 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009968 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009969 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009970 if (!r.exported) {
9971 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9972 + " from pid=" + callingPid
9973 + ", uid=" + callingUid
9974 + " that is not exported from uid " + r.appInfo.uid);
9975 return new ServiceLookupResult(null, "not exported from uid "
9976 + r.appInfo.uid);
9977 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009978 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009979 + " from pid=" + callingPid
9980 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 + " requires " + r.permission);
9982 return new ServiceLookupResult(null, r.permission);
9983 }
9984 return new ServiceLookupResult(r, null);
9985 }
9986 return null;
9987 }
9988
Dianne Hackborn287952c2010-09-22 22:34:31 -07009989 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9990 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9991 + why + " of " + r + " in app " + r.app);
9992 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9993 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009994 long now = SystemClock.uptimeMillis();
9995 if (r.executeNesting == 0 && r.app != null) {
9996 if (r.app.executingServices.size() == 0) {
9997 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9998 msg.obj = r.app;
9999 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10000 }
10001 r.app.executingServices.add(r);
10002 }
10003 r.executeNesting++;
10004 r.executingStart = now;
10005 }
10006
10007 private final void sendServiceArgsLocked(ServiceRecord r,
10008 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010009 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010010 if (N == 0) {
10011 return;
10012 }
10013
Dianne Hackborn39792d22010-08-19 18:01:52 -070010014 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010015 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010016 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010017 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10018 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010019 if (si.intent == null && N > 1) {
10020 // If somehow we got a dummy null intent in the middle,
10021 // then skip it. DO NOT skip a null intent when it is
10022 // the only one in the list -- this is to support the
10023 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010024 continue;
10025 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010026 si.deliveredTime = SystemClock.uptimeMillis();
10027 r.deliveredStarts.add(si);
10028 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010029 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010030 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010031 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010032 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010033 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010034 if (!oomAdjusted) {
10035 oomAdjusted = true;
10036 updateOomAdjLocked(r.app);
10037 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010038 int flags = 0;
10039 if (si.deliveryCount > 0) {
10040 flags |= Service.START_FLAG_RETRY;
10041 }
10042 if (si.doneExecutingCount > 0) {
10043 flags |= Service.START_FLAG_REDELIVERY;
10044 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010045 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010046 } catch (RemoteException e) {
10047 // Remote process gone... we'll let the normal cleanup take
10048 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010049 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010050 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010052 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010053 break;
10054 }
10055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010056 }
10057
10058 private final boolean requestServiceBindingLocked(ServiceRecord r,
10059 IntentBindRecord i, boolean rebind) {
10060 if (r.app == null || r.app.thread == null) {
10061 // If service is not currently running, can't yet bind.
10062 return false;
10063 }
10064 if ((!i.requested || rebind) && i.apps.size() > 0) {
10065 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010066 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10068 if (!rebind) {
10069 i.requested = true;
10070 }
10071 i.hasBound = true;
10072 i.doRebind = false;
10073 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010074 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010075 return false;
10076 }
10077 }
10078 return true;
10079 }
10080
10081 private final void requestServiceBindingsLocked(ServiceRecord r) {
10082 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10083 while (bindings.hasNext()) {
10084 IntentBindRecord i = bindings.next();
10085 if (!requestServiceBindingLocked(r, i, false)) {
10086 break;
10087 }
10088 }
10089 }
10090
10091 private final void realStartServiceLocked(ServiceRecord r,
10092 ProcessRecord app) throws RemoteException {
10093 if (app.thread == null) {
10094 throw new RemoteException();
10095 }
10096
10097 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010098 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010099
10100 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010101 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010102 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103
10104 boolean created = false;
10105 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010106 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010107 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010108 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010109 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010110 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010111 synchronized (r.stats.getBatteryStats()) {
10112 r.stats.startLaunchedLocked();
10113 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010114 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010115 app.thread.scheduleCreateService(r, r.serviceInfo,
10116 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010117 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010118 created = true;
10119 } finally {
10120 if (!created) {
10121 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010122 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010123 }
10124 }
10125
10126 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010127
10128 // If the service is in the started state, and there are no
10129 // pending arguments, then fake up one so its onStartCommand() will
10130 // be called.
10131 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010132 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10133 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010134 }
10135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010136 sendServiceArgsLocked(r, true);
10137 }
10138
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010139 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10140 boolean allowCancel) {
10141 boolean canceled = false;
10142
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010143 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010144 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010145 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010146
Dianne Hackborn070783f2010-12-29 16:46:28 -080010147 if ((r.serviceInfo.applicationInfo.flags
10148 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10149 minDuration /= 4;
10150 }
10151
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010152 // Any delivered but not yet finished starts should be put back
10153 // on the pending list.
10154 final int N = r.deliveredStarts.size();
10155 if (N > 0) {
10156 for (int i=N-1; i>=0; i--) {
10157 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010158 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010159 if (si.intent == null) {
10160 // We'll generate this again if needed.
10161 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10162 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10163 r.pendingStarts.add(0, si);
10164 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10165 dur *= 2;
10166 if (minDuration < dur) minDuration = dur;
10167 if (resetTime < dur) resetTime = dur;
10168 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010169 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010170 + r.name);
10171 canceled = true;
10172 }
10173 }
10174 r.deliveredStarts.clear();
10175 }
10176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 r.totalRestartCount++;
10178 if (r.restartDelay == 0) {
10179 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010180 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181 } else {
10182 // If it has been a "reasonably long time" since the service
10183 // was started, then reset our restart duration back to
10184 // the beginning, so we don't infinitely increase the duration
10185 // on a service that just occasionally gets killed (which is
10186 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010187 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010189 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010190 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010191 if ((r.serviceInfo.applicationInfo.flags
10192 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10193 // Services in peristent processes will restart much more
10194 // quickly, since they are pretty important. (Think SystemUI).
10195 r.restartDelay += minDuration/2;
10196 } else {
10197 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10198 if (r.restartDelay < minDuration) {
10199 r.restartDelay = minDuration;
10200 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 }
10203 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010204
10205 r.nextRestartTime = now + r.restartDelay;
10206
10207 // Make sure that we don't end up restarting a bunch of services
10208 // all at the same time.
10209 boolean repeat;
10210 do {
10211 repeat = false;
10212 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10213 ServiceRecord r2 = mRestartingServices.get(i);
10214 if (r2 != r && r.nextRestartTime
10215 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10216 && r.nextRestartTime
10217 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10218 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10219 r.restartDelay = r.nextRestartTime - now;
10220 repeat = true;
10221 break;
10222 }
10223 }
10224 } while (repeat);
10225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010226 if (!mRestartingServices.contains(r)) {
10227 mRestartingServices.add(r);
10228 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010229
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010230 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010232 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010233 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010234 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010235 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010236 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010237 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010238 r.shortName, r.restartDelay);
10239
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010240 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010241 }
10242
10243 final void performServiceRestartLocked(ServiceRecord r) {
10244 if (!mRestartingServices.contains(r)) {
10245 return;
10246 }
10247 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10248 }
10249
10250 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10251 if (r.restartDelay == 0) {
10252 return false;
10253 }
10254 r.resetRestartCounter();
10255 mRestartingServices.remove(r);
10256 mHandler.removeCallbacks(r.restarter);
10257 return true;
10258 }
10259
10260 private final boolean bringUpServiceLocked(ServiceRecord r,
10261 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010262 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010263 //r.dump(" ");
10264
Dianne Hackborn36124872009-10-08 16:22:03 -070010265 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 sendServiceArgsLocked(r, false);
10267 return true;
10268 }
10269
10270 if (!whileRestarting && r.restartDelay > 0) {
10271 // If waiting for a restart, then do nothing.
10272 return true;
10273 }
10274
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010275 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010276
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010277 // We are now bringing the service up, so no longer in the
10278 // restarting state.
10279 mRestartingServices.remove(r);
10280
Dianne Hackborne7f97212011-02-24 14:40:20 -080010281 // Service is now being launched, its package can't be stopped.
10282 try {
10283 AppGlobals.getPackageManager().setPackageStoppedState(
10284 r.packageName, false);
10285 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010286 } catch (IllegalArgumentException e) {
10287 Slog.w(TAG, "Failed trying to unstop package "
10288 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010289 }
10290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010291 final String appName = r.processName;
10292 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10293 if (app != null && app.thread != null) {
10294 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010295 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 realStartServiceLocked(r, app);
10297 return true;
10298 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010299 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 }
10301
10302 // If a dead object exception was thrown -- fall through to
10303 // restart the application.
10304 }
10305
Dianne Hackborn36124872009-10-08 16:22:03 -070010306 // Not running -- get it started, and enqueue this service record
10307 // to be executed when the app comes up.
10308 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10309 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010310 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010311 + r.appInfo.packageName + "/"
10312 + r.appInfo.uid + " for service "
10313 + r.intent.getIntent() + ": process is bad");
10314 bringDownServiceLocked(r, true);
10315 return false;
10316 }
10317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 mPendingServices.add(r);
10320 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010322 return true;
10323 }
10324
10325 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010326 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010327 //r.dump(" ");
10328
10329 // Does it still need to run?
10330 if (!force && r.startRequested) {
10331 return;
10332 }
10333 if (r.connections.size() > 0) {
10334 if (!force) {
10335 // XXX should probably keep a count of the number of auto-create
10336 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010337 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010338 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010339 ArrayList<ConnectionRecord> cr = it.next();
10340 for (int i=0; i<cr.size(); i++) {
10341 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10342 return;
10343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010344 }
10345 }
10346 }
10347
10348 // Report to all of the connections that the service is no longer
10349 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010350 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010351 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010352 ArrayList<ConnectionRecord> c = it.next();
10353 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010354 ConnectionRecord cr = c.get(i);
10355 // There is still a connection to the service that is
10356 // being brought down. Mark it as dead.
10357 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010358 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010359 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010360 } catch (Exception e) {
10361 Slog.w(TAG, "Failure disconnecting service " + r.name +
10362 " to connection " + c.get(i).conn.asBinder() +
10363 " (in " + c.get(i).binding.client.processName + ")", e);
10364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010365 }
10366 }
10367 }
10368
10369 // Tell the service that it has been unbound.
10370 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10371 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10372 while (it.hasNext()) {
10373 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010374 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010375 + ": hasBound=" + ibr.hasBound);
10376 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10377 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010378 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 updateOomAdjLocked(r.app);
10380 ibr.hasBound = false;
10381 r.app.thread.scheduleUnbindService(r,
10382 ibr.intent.getIntent());
10383 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010384 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010385 + r.shortName, e);
10386 serviceDoneExecutingLocked(r, true);
10387 }
10388 }
10389 }
10390 }
10391
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010392 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010393 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010394 System.identityHashCode(r), r.shortName,
10395 (r.app != null) ? r.app.pid : -1);
10396
10397 mServices.remove(r.name);
10398 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010399 r.totalRestartCount = 0;
10400 unscheduleServiceRestartLocked(r);
10401
10402 // Also make sure it is not on the pending list.
10403 int N = mPendingServices.size();
10404 for (int i=0; i<N; i++) {
10405 if (mPendingServices.get(i) == r) {
10406 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010407 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010408 i--;
10409 N--;
10410 }
10411 }
10412
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010413 r.cancelNotification();
10414 r.isForeground = false;
10415 r.foregroundId = 0;
10416 r.foregroundNoti = null;
10417
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010418 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010419 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010420 r.pendingStarts.clear();
10421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010422 if (r.app != null) {
10423 synchronized (r.stats.getBatteryStats()) {
10424 r.stats.stopLaunchedLocked();
10425 }
10426 r.app.services.remove(r);
10427 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010428 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010429 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010430 mStoppingServices.add(r);
10431 updateOomAdjLocked(r.app);
10432 r.app.thread.scheduleStopService(r);
10433 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010434 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010435 + r.shortName, e);
10436 serviceDoneExecutingLocked(r, true);
10437 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010438 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010439 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010440 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010441 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010442 }
10443 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010444 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010445 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010446 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010447
10448 if (r.bindings.size() > 0) {
10449 r.bindings.clear();
10450 }
10451
10452 if (r.restarter instanceof ServiceRestarter) {
10453 ((ServiceRestarter)r.restarter).setService(null);
10454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010455 }
10456
10457 ComponentName startServiceLocked(IApplicationThread caller,
10458 Intent service, String resolvedType,
10459 int callingPid, int callingUid) {
10460 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010461 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010462 + " type=" + resolvedType + " args=" + service.getExtras());
10463
10464 if (caller != null) {
10465 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10466 if (callerApp == null) {
10467 throw new SecurityException(
10468 "Unable to find app for caller " + caller
10469 + " (pid=" + Binder.getCallingPid()
10470 + ") when starting service " + service);
10471 }
10472 }
10473
10474 ServiceLookupResult res =
10475 retrieveServiceLocked(service, resolvedType,
10476 callingPid, callingUid);
10477 if (res == null) {
10478 return null;
10479 }
10480 if (res.record == null) {
10481 return new ComponentName("!", res.permission != null
10482 ? res.permission : "private to package");
10483 }
10484 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010485 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10486 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010487 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010488 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 }
10490 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010491 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010492 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010493 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010494 r.lastActivity = SystemClock.uptimeMillis();
10495 synchronized (r.stats.getBatteryStats()) {
10496 r.stats.startRunningLocked();
10497 }
10498 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10499 return new ComponentName("!", "Service process is bad");
10500 }
10501 return r.name;
10502 }
10503 }
10504
10505 public ComponentName startService(IApplicationThread caller, Intent service,
10506 String resolvedType) {
10507 // Refuse possible leaked file descriptors
10508 if (service != null && service.hasFileDescriptors() == true) {
10509 throw new IllegalArgumentException("File descriptors passed in Intent");
10510 }
10511
10512 synchronized(this) {
10513 final int callingPid = Binder.getCallingPid();
10514 final int callingUid = Binder.getCallingUid();
10515 final long origId = Binder.clearCallingIdentity();
10516 ComponentName res = startServiceLocked(caller, service,
10517 resolvedType, callingPid, callingUid);
10518 Binder.restoreCallingIdentity(origId);
10519 return res;
10520 }
10521 }
10522
10523 ComponentName startServiceInPackage(int uid,
10524 Intent service, String resolvedType) {
10525 synchronized(this) {
10526 final long origId = Binder.clearCallingIdentity();
10527 ComponentName res = startServiceLocked(null, service,
10528 resolvedType, -1, uid);
10529 Binder.restoreCallingIdentity(origId);
10530 return res;
10531 }
10532 }
10533
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010534 private void stopServiceLocked(ServiceRecord service) {
10535 synchronized (service.stats.getBatteryStats()) {
10536 service.stats.stopRunningLocked();
10537 }
10538 service.startRequested = false;
10539 service.callStart = false;
10540 bringDownServiceLocked(service, false);
10541 }
10542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010543 public int stopService(IApplicationThread caller, Intent service,
10544 String resolvedType) {
10545 // Refuse possible leaked file descriptors
10546 if (service != null && service.hasFileDescriptors() == true) {
10547 throw new IllegalArgumentException("File descriptors passed in Intent");
10548 }
10549
10550 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010551 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010552 + " type=" + resolvedType);
10553
10554 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10555 if (caller != null && callerApp == null) {
10556 throw new SecurityException(
10557 "Unable to find app for caller " + caller
10558 + " (pid=" + Binder.getCallingPid()
10559 + ") when stopping service " + service);
10560 }
10561
10562 // If this service is active, make sure it is stopped.
10563 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10564 if (r != null) {
10565 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010567 try {
10568 stopServiceLocked(r.record);
10569 } finally {
10570 Binder.restoreCallingIdentity(origId);
10571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010572 return 1;
10573 }
10574 return -1;
10575 }
10576 }
10577
10578 return 0;
10579 }
10580
10581 public IBinder peekService(Intent service, String resolvedType) {
10582 // Refuse possible leaked file descriptors
10583 if (service != null && service.hasFileDescriptors() == true) {
10584 throw new IllegalArgumentException("File descriptors passed in Intent");
10585 }
10586
10587 IBinder ret = null;
10588
10589 synchronized(this) {
10590 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10591
10592 if (r != null) {
10593 // r.record is null if findServiceLocked() failed the caller permission check
10594 if (r.record == null) {
10595 throw new SecurityException(
10596 "Permission Denial: Accessing service " + r.record.name
10597 + " from pid=" + Binder.getCallingPid()
10598 + ", uid=" + Binder.getCallingUid()
10599 + " requires " + r.permission);
10600 }
10601 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10602 if (ib != null) {
10603 ret = ib.binder;
10604 }
10605 }
10606 }
10607
10608 return ret;
10609 }
10610
10611 public boolean stopServiceToken(ComponentName className, IBinder token,
10612 int startId) {
10613 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010614 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 + " " + token + " startId=" + startId);
10616 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010617 if (r != null) {
10618 if (startId >= 0) {
10619 // Asked to only stop if done with all work. Note that
10620 // to avoid leaks, we will take this as dropping all
10621 // start items up to and including this one.
10622 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10623 if (si != null) {
10624 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010625 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10626 cur.removeUriPermissionsLocked();
10627 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010628 break;
10629 }
10630 }
10631 }
10632
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010633 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010634 return false;
10635 }
10636
10637 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010638 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010639 + " is last, but have " + r.deliveredStarts.size()
10640 + " remaining args");
10641 }
10642 }
10643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 synchronized (r.stats.getBatteryStats()) {
10645 r.stats.stopRunningLocked();
10646 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010647 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010648 }
10649 final long origId = Binder.clearCallingIdentity();
10650 bringDownServiceLocked(r, false);
10651 Binder.restoreCallingIdentity(origId);
10652 return true;
10653 }
10654 }
10655 return false;
10656 }
10657
10658 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010659 int id, Notification notification, boolean removeNotification) {
10660 final long origId = Binder.clearCallingIdentity();
10661 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010662 synchronized(this) {
10663 ServiceRecord r = findServiceLocked(className, token);
10664 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010665 if (id != 0) {
10666 if (notification == null) {
10667 throw new IllegalArgumentException("null notification");
10668 }
10669 if (r.foregroundId != id) {
10670 r.cancelNotification();
10671 r.foregroundId = id;
10672 }
10673 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10674 r.foregroundNoti = notification;
10675 r.isForeground = true;
10676 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010677 if (r.app != null) {
10678 updateServiceForegroundLocked(r.app, true);
10679 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010680 } else {
10681 if (r.isForeground) {
10682 r.isForeground = false;
10683 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010684 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010685 updateServiceForegroundLocked(r.app, true);
10686 }
10687 }
10688 if (removeNotification) {
10689 r.cancelNotification();
10690 r.foregroundId = 0;
10691 r.foregroundNoti = null;
10692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010693 }
10694 }
10695 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010696 } finally {
10697 Binder.restoreCallingIdentity(origId);
10698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010699 }
10700
10701 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10702 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010703 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010704 if (sr.isForeground) {
10705 anyForeground = true;
10706 break;
10707 }
10708 }
10709 if (anyForeground != proc.foregroundServices) {
10710 proc.foregroundServices = anyForeground;
10711 if (oomAdj) {
10712 updateOomAdjLocked();
10713 }
10714 }
10715 }
10716
10717 public int bindService(IApplicationThread caller, IBinder token,
10718 Intent service, String resolvedType,
10719 IServiceConnection connection, int flags) {
10720 // Refuse possible leaked file descriptors
10721 if (service != null && service.hasFileDescriptors() == true) {
10722 throw new IllegalArgumentException("File descriptors passed in Intent");
10723 }
10724
10725 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010726 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010727 + " type=" + resolvedType + " conn=" + connection.asBinder()
10728 + " flags=0x" + Integer.toHexString(flags));
10729 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10730 if (callerApp == null) {
10731 throw new SecurityException(
10732 "Unable to find app for caller " + caller
10733 + " (pid=" + Binder.getCallingPid()
10734 + ") when binding service " + service);
10735 }
10736
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010737 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010738 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010739 activity = mMainStack.isInStackLocked(token);
10740 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010741 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010742 return 0;
10743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010744 }
10745
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010746 int clientLabel = 0;
10747 PendingIntent clientIntent = null;
10748
10749 if (callerApp.info.uid == Process.SYSTEM_UID) {
10750 // Hacky kind of thing -- allow system stuff to tell us
10751 // what they are, so we can report this elsewhere for
10752 // others to know why certain services are running.
10753 try {
10754 clientIntent = (PendingIntent)service.getParcelableExtra(
10755 Intent.EXTRA_CLIENT_INTENT);
10756 } catch (RuntimeException e) {
10757 }
10758 if (clientIntent != null) {
10759 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10760 if (clientLabel != 0) {
10761 // There are no useful extras in the intent, trash them.
10762 // System code calling with this stuff just needs to know
10763 // this will happen.
10764 service = service.cloneFilter();
10765 }
10766 }
10767 }
10768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 ServiceLookupResult res =
10770 retrieveServiceLocked(service, resolvedType,
10771 Binder.getCallingPid(), Binder.getCallingUid());
10772 if (res == null) {
10773 return 0;
10774 }
10775 if (res.record == null) {
10776 return -1;
10777 }
10778 ServiceRecord s = res.record;
10779
10780 final long origId = Binder.clearCallingIdentity();
10781
10782 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010783 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010784 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010785 }
10786
10787 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10788 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010789 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010790
10791 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010792 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10793 if (clist == null) {
10794 clist = new ArrayList<ConnectionRecord>();
10795 s.connections.put(binder, clist);
10796 }
10797 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010798 b.connections.add(c);
10799 if (activity != null) {
10800 if (activity.connections == null) {
10801 activity.connections = new HashSet<ConnectionRecord>();
10802 }
10803 activity.connections.add(c);
10804 }
10805 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010806 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10807 b.client.hasAboveClient = true;
10808 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010809 clist = mServiceConnections.get(binder);
10810 if (clist == null) {
10811 clist = new ArrayList<ConnectionRecord>();
10812 mServiceConnections.put(binder, clist);
10813 }
10814 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010815
10816 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10817 s.lastActivity = SystemClock.uptimeMillis();
10818 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10819 return 0;
10820 }
10821 }
10822
10823 if (s.app != null) {
10824 // This could have made the service more important.
10825 updateOomAdjLocked(s.app);
10826 }
10827
Joe Onorato8a9b2202010-02-26 18:56:32 -080010828 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 + ": received=" + b.intent.received
10830 + " apps=" + b.intent.apps.size()
10831 + " doRebind=" + b.intent.doRebind);
10832
10833 if (s.app != null && b.intent.received) {
10834 // Service is already running, so we can immediately
10835 // publish the connection.
10836 try {
10837 c.conn.connected(s.name, b.intent.binder);
10838 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010839 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010840 + " to connection " + c.conn.asBinder()
10841 + " (in " + c.binding.client.processName + ")", e);
10842 }
10843
10844 // If this is the first app connected back to this binding,
10845 // and the service had previously asked to be told when
10846 // rebound, then do so.
10847 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10848 requestServiceBindingLocked(s, b.intent, true);
10849 }
10850 } else if (!b.intent.requested) {
10851 requestServiceBindingLocked(s, b.intent, false);
10852 }
10853
10854 Binder.restoreCallingIdentity(origId);
10855 }
10856
10857 return 1;
10858 }
10859
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010860 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010861 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010862 IBinder binder = c.conn.asBinder();
10863 AppBindRecord b = c.binding;
10864 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010865 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10866 if (clist != null) {
10867 clist.remove(c);
10868 if (clist.size() == 0) {
10869 s.connections.remove(binder);
10870 }
10871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010872 b.connections.remove(c);
10873 if (c.activity != null && c.activity != skipAct) {
10874 if (c.activity.connections != null) {
10875 c.activity.connections.remove(c);
10876 }
10877 }
10878 if (b.client != skipApp) {
10879 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010880 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10881 b.client.updateHasAboveClientLocked();
10882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010883 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010884 clist = mServiceConnections.get(binder);
10885 if (clist != null) {
10886 clist.remove(c);
10887 if (clist.size() == 0) {
10888 mServiceConnections.remove(binder);
10889 }
10890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010891
10892 if (b.connections.size() == 0) {
10893 b.intent.apps.remove(b.client);
10894 }
10895
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010896 if (!c.serviceDead) {
10897 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10898 + ": shouldUnbind=" + b.intent.hasBound);
10899 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10900 && b.intent.hasBound) {
10901 try {
10902 bumpServiceExecutingLocked(s, "unbind");
10903 updateOomAdjLocked(s.app);
10904 b.intent.hasBound = false;
10905 // Assume the client doesn't want to know about a rebind;
10906 // we will deal with that later if it asks for one.
10907 b.intent.doRebind = false;
10908 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10909 } catch (Exception e) {
10910 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10911 serviceDoneExecutingLocked(s, true);
10912 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010913 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010914
10915 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10916 bringDownServiceLocked(s, false);
10917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918 }
10919 }
10920
10921 public boolean unbindService(IServiceConnection connection) {
10922 synchronized (this) {
10923 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010924 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010925 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10926 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010927 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010928 + connection.asBinder());
10929 return false;
10930 }
10931
10932 final long origId = Binder.clearCallingIdentity();
10933
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010934 while (clist.size() > 0) {
10935 ConnectionRecord r = clist.get(0);
10936 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010937
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010938 if (r.binding.service.app != null) {
10939 // This could have made the service less important.
10940 updateOomAdjLocked(r.binding.service.app);
10941 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010942 }
10943
10944 Binder.restoreCallingIdentity(origId);
10945 }
10946
10947 return true;
10948 }
10949
10950 public void publishService(IBinder token, Intent intent, IBinder service) {
10951 // Refuse possible leaked file descriptors
10952 if (intent != null && intent.hasFileDescriptors() == true) {
10953 throw new IllegalArgumentException("File descriptors passed in Intent");
10954 }
10955
10956 synchronized(this) {
10957 if (!(token instanceof ServiceRecord)) {
10958 throw new IllegalArgumentException("Invalid service token");
10959 }
10960 ServiceRecord r = (ServiceRecord)token;
10961
10962 final long origId = Binder.clearCallingIdentity();
10963
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010964 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010965 + " " + intent + ": " + service);
10966 if (r != null) {
10967 Intent.FilterComparison filter
10968 = new Intent.FilterComparison(intent);
10969 IntentBindRecord b = r.bindings.get(filter);
10970 if (b != null && !b.received) {
10971 b.binder = service;
10972 b.requested = true;
10973 b.received = true;
10974 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010975 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 = r.connections.values().iterator();
10977 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010978 ArrayList<ConnectionRecord> clist = it.next();
10979 for (int i=0; i<clist.size(); i++) {
10980 ConnectionRecord c = clist.get(i);
10981 if (!filter.equals(c.binding.intent.intent)) {
10982 if (DEBUG_SERVICE) Slog.v(
10983 TAG, "Not publishing to: " + c);
10984 if (DEBUG_SERVICE) Slog.v(
10985 TAG, "Bound intent: " + c.binding.intent.intent);
10986 if (DEBUG_SERVICE) Slog.v(
10987 TAG, "Published intent: " + intent);
10988 continue;
10989 }
10990 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10991 try {
10992 c.conn.connected(r.name, service);
10993 } catch (Exception e) {
10994 Slog.w(TAG, "Failure sending service " + r.name +
10995 " to connection " + c.conn.asBinder() +
10996 " (in " + c.binding.client.processName + ")", e);
10997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010998 }
10999 }
11000 }
11001 }
11002
11003 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11004
11005 Binder.restoreCallingIdentity(origId);
11006 }
11007 }
11008 }
11009
11010 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11011 // Refuse possible leaked file descriptors
11012 if (intent != null && intent.hasFileDescriptors() == true) {
11013 throw new IllegalArgumentException("File descriptors passed in Intent");
11014 }
11015
11016 synchronized(this) {
11017 if (!(token instanceof ServiceRecord)) {
11018 throw new IllegalArgumentException("Invalid service token");
11019 }
11020 ServiceRecord r = (ServiceRecord)token;
11021
11022 final long origId = Binder.clearCallingIdentity();
11023
11024 if (r != null) {
11025 Intent.FilterComparison filter
11026 = new Intent.FilterComparison(intent);
11027 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011028 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011029 + " at " + b + ": apps="
11030 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011031
11032 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011034 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 // Applications have already bound since the last
11036 // unbind, so just rebind right here.
11037 requestServiceBindingLocked(r, b, true);
11038 } else {
11039 // Note to tell the service the next time there is
11040 // a new client.
11041 b.doRebind = true;
11042 }
11043 }
11044
Per Edelberg78f9fff2010-08-30 20:01:35 +020011045 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046
11047 Binder.restoreCallingIdentity(origId);
11048 }
11049 }
11050 }
11051
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011052 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011053 synchronized(this) {
11054 if (!(token instanceof ServiceRecord)) {
11055 throw new IllegalArgumentException("Invalid service token");
11056 }
11057 ServiceRecord r = (ServiceRecord)token;
11058 boolean inStopping = mStoppingServices.contains(token);
11059 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011060 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011061 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 + " with incorrect token: given " + token
11063 + ", expected " + r);
11064 return;
11065 }
11066
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011067 if (type == 1) {
11068 // This is a call from a service start... take care of
11069 // book-keeping.
11070 r.callStart = true;
11071 switch (res) {
11072 case Service.START_STICKY_COMPATIBILITY:
11073 case Service.START_STICKY: {
11074 // We are done with the associated start arguments.
11075 r.findDeliveredStart(startId, true);
11076 // Don't stop if killed.
11077 r.stopIfKilled = false;
11078 break;
11079 }
11080 case Service.START_NOT_STICKY: {
11081 // We are done with the associated start arguments.
11082 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011083 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011084 // There is no more work, and this service
11085 // doesn't want to hang around if killed.
11086 r.stopIfKilled = true;
11087 }
11088 break;
11089 }
11090 case Service.START_REDELIVER_INTENT: {
11091 // We'll keep this item until they explicitly
11092 // call stop for it, but keep track of the fact
11093 // that it was delivered.
11094 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11095 if (si != null) {
11096 si.deliveryCount = 0;
11097 si.doneExecutingCount++;
11098 // Don't stop if killed.
11099 r.stopIfKilled = true;
11100 }
11101 break;
11102 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011103 case Service.START_TASK_REMOVED_COMPLETE: {
11104 // Special processing for onTaskRemoved(). Don't
11105 // impact normal onStartCommand() processing.
11106 r.findDeliveredStart(startId, true);
11107 break;
11108 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011109 default:
11110 throw new IllegalArgumentException(
11111 "Unknown service start result: " + res);
11112 }
11113 if (res == Service.START_STICKY_COMPATIBILITY) {
11114 r.callStart = false;
11115 }
11116 }
11117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011118 final long origId = Binder.clearCallingIdentity();
11119 serviceDoneExecutingLocked(r, inStopping);
11120 Binder.restoreCallingIdentity(origId);
11121 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011122 Slog.w(TAG, "Done executing unknown service from pid "
11123 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011124 }
11125 }
11126 }
11127
11128 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011129 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11130 + ": nesting=" + r.executeNesting
11131 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011132 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011133 r.executeNesting--;
11134 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011135 if (DEBUG_SERVICE) Slog.v(TAG,
11136 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011137 r.app.executingServices.remove(r);
11138 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011139 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11140 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011141 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11142 }
11143 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011144 if (DEBUG_SERVICE) Slog.v(TAG,
11145 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011146 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011147 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011148 }
11149 updateOomAdjLocked(r.app);
11150 }
11151 }
11152
11153 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011154 String anrMessage = null;
11155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011156 synchronized(this) {
11157 if (proc.executingServices.size() == 0 || proc.thread == null) {
11158 return;
11159 }
11160 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11161 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11162 ServiceRecord timeout = null;
11163 long nextTime = 0;
11164 while (it.hasNext()) {
11165 ServiceRecord sr = it.next();
11166 if (sr.executingStart < maxTime) {
11167 timeout = sr;
11168 break;
11169 }
11170 if (sr.executingStart > nextTime) {
11171 nextTime = sr.executingStart;
11172 }
11173 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011174 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011175 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011176 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011177 } else {
11178 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11179 msg.obj = proc;
11180 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11181 }
11182 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011183
11184 if (anrMessage != null) {
11185 appNotResponding(proc, null, null, anrMessage);
11186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011187 }
11188
11189 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011190 // BACKUP AND RESTORE
11191 // =========================================================
11192
11193 // Cause the target app to be launched if necessary and its backup agent
11194 // instantiated. The backup agent will invoke backupAgentCreated() on the
11195 // activity manager to announce its creation.
11196 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011197 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011198 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11199
11200 synchronized(this) {
11201 // !!! TODO: currently no check here that we're already bound
11202 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11203 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11204 synchronized (stats) {
11205 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11206 }
11207
Dianne Hackborne7f97212011-02-24 14:40:20 -080011208 // Backup agent is now in use, its package can't be stopped.
11209 try {
11210 AppGlobals.getPackageManager().setPackageStoppedState(
11211 app.packageName, false);
11212 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011213 } catch (IllegalArgumentException e) {
11214 Slog.w(TAG, "Failed trying to unstop package "
11215 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011216 }
11217
Christopher Tate181fafa2009-05-14 11:12:14 -070011218 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011219 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11220 ? new ComponentName(app.packageName, app.backupAgentName)
11221 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011222 // startProcessLocked() returns existing proc's record if it's already running
11223 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011224 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011225 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011226 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011227 return false;
11228 }
11229
11230 r.app = proc;
11231 mBackupTarget = r;
11232 mBackupAppName = app.packageName;
11233
Christopher Tate6fa95972009-06-05 18:43:55 -070011234 // Try not to kill the process during backup
11235 updateOomAdjLocked(proc);
11236
Christopher Tate181fafa2009-05-14 11:12:14 -070011237 // If the process is already attached, schedule the creation of the backup agent now.
11238 // If it is not yet live, this will be done when it attaches to the framework.
11239 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011240 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011241 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011242 proc.thread.scheduleCreateBackupAgent(app,
11243 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011244 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011245 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011246 }
11247 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011248 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011249 }
11250 // Invariants: at this point, the target app process exists and the application
11251 // is either already running or in the process of coming up. mBackupTarget and
11252 // mBackupAppName describe the app, so that when it binds back to the AM we
11253 // know that it's scheduled for a backup-agent operation.
11254 }
11255
11256 return true;
11257 }
11258
11259 // A backup agent has just come up
11260 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011261 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011262 + " = " + agent);
11263
11264 synchronized(this) {
11265 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011266 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011267 return;
11268 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011269 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011270
Dianne Hackborn06740692010-09-22 22:46:21 -070011271 long oldIdent = Binder.clearCallingIdentity();
11272 try {
11273 IBackupManager bm = IBackupManager.Stub.asInterface(
11274 ServiceManager.getService(Context.BACKUP_SERVICE));
11275 bm.agentConnected(agentPackageName, agent);
11276 } catch (RemoteException e) {
11277 // can't happen; the backup manager service is local
11278 } catch (Exception e) {
11279 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11280 e.printStackTrace();
11281 } finally {
11282 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011283 }
11284 }
11285
11286 // done with this agent
11287 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011288 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011289 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011290 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011291 return;
11292 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011293
11294 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011295 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011296 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011297 return;
11298 }
11299
Christopher Tate181fafa2009-05-14 11:12:14 -070011300 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011301 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011302 return;
11303 }
11304
Christopher Tate6fa95972009-06-05 18:43:55 -070011305 ProcessRecord proc = mBackupTarget.app;
11306 mBackupTarget = null;
11307 mBackupAppName = null;
11308
11309 // Not backing this app up any more; reset its OOM adjustment
11310 updateOomAdjLocked(proc);
11311
Christopher Tatec7b31e32009-06-10 15:49:30 -070011312 // If the app crashed during backup, 'thread' will be null here
11313 if (proc.thread != null) {
11314 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011315 proc.thread.scheduleDestroyBackupAgent(appInfo,
11316 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011317 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011318 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011319 e.printStackTrace();
11320 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011321 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011322 }
11323 }
11324 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011325 // BROADCASTS
11326 // =========================================================
11327
Josh Bartel7f208742010-02-25 11:01:44 -060011328 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011329 List cur) {
11330 final ContentResolver resolver = mContext.getContentResolver();
11331 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11332 if (list == null) {
11333 return cur;
11334 }
11335 int N = list.size();
11336 for (int i=0; i<N; i++) {
11337 Intent intent = list.get(i);
11338 if (filter.match(resolver, intent, true, TAG) >= 0) {
11339 if (cur == null) {
11340 cur = new ArrayList<Intent>();
11341 }
11342 cur.add(intent);
11343 }
11344 }
11345 return cur;
11346 }
11347
11348 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011349 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011350 + mBroadcastsScheduled);
11351
11352 if (mBroadcastsScheduled) {
11353 return;
11354 }
11355 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11356 mBroadcastsScheduled = true;
11357 }
11358
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011359 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 IIntentReceiver receiver, IntentFilter filter, String permission) {
11361 synchronized(this) {
11362 ProcessRecord callerApp = null;
11363 if (caller != null) {
11364 callerApp = getRecordForAppLocked(caller);
11365 if (callerApp == null) {
11366 throw new SecurityException(
11367 "Unable to find app for caller " + caller
11368 + " (pid=" + Binder.getCallingPid()
11369 + ") when registering receiver " + receiver);
11370 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011371 if (callerApp.info.uid != Process.SYSTEM_UID &&
11372 !callerApp.pkgList.contains(callerPackage)) {
11373 throw new SecurityException("Given caller package " + callerPackage
11374 + " is not running in process " + callerApp);
11375 }
11376 } else {
11377 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 }
11379
11380 List allSticky = null;
11381
11382 // Look for any matching sticky broadcasts...
11383 Iterator actions = filter.actionsIterator();
11384 if (actions != null) {
11385 while (actions.hasNext()) {
11386 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011387 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011388 }
11389 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011390 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391 }
11392
11393 // The first sticky in the list is returned directly back to
11394 // the client.
11395 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11396
Joe Onorato8a9b2202010-02-26 18:56:32 -080011397 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011398 + ": " + sticky);
11399
11400 if (receiver == null) {
11401 return sticky;
11402 }
11403
11404 ReceiverList rl
11405 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11406 if (rl == null) {
11407 rl = new ReceiverList(this, callerApp,
11408 Binder.getCallingPid(),
11409 Binder.getCallingUid(), receiver);
11410 if (rl.app != null) {
11411 rl.app.receivers.add(rl);
11412 } else {
11413 try {
11414 receiver.asBinder().linkToDeath(rl, 0);
11415 } catch (RemoteException e) {
11416 return sticky;
11417 }
11418 rl.linkedToDeath = true;
11419 }
11420 mRegisteredReceivers.put(receiver.asBinder(), rl);
11421 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011422 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011423 rl.add(bf);
11424 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011425 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011426 }
11427 mReceiverResolver.addFilter(bf);
11428
11429 // Enqueue broadcasts for all existing stickies that match
11430 // this filter.
11431 if (allSticky != null) {
11432 ArrayList receivers = new ArrayList();
11433 receivers.add(bf);
11434
11435 int N = allSticky.size();
11436 for (int i=0; i<N; i++) {
11437 Intent intent = (Intent)allSticky.get(i);
11438 BroadcastRecord r = new BroadcastRecord(intent, null,
11439 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011440 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011441 if (mParallelBroadcasts.size() == 0) {
11442 scheduleBroadcastsLocked();
11443 }
11444 mParallelBroadcasts.add(r);
11445 }
11446 }
11447
11448 return sticky;
11449 }
11450 }
11451
11452 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011453 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011454
11455 boolean doNext = false;
11456
11457 synchronized(this) {
11458 ReceiverList rl
11459 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11460 if (rl != null) {
11461 if (rl.curBroadcast != null) {
11462 BroadcastRecord r = rl.curBroadcast;
11463 doNext = finishReceiverLocked(
11464 receiver.asBinder(), r.resultCode, r.resultData,
11465 r.resultExtras, r.resultAbort, true);
11466 }
11467
11468 if (rl.app != null) {
11469 rl.app.receivers.remove(rl);
11470 }
11471 removeReceiverLocked(rl);
11472 if (rl.linkedToDeath) {
11473 rl.linkedToDeath = false;
11474 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11475 }
11476 }
11477 }
11478
11479 if (!doNext) {
11480 return;
11481 }
11482
11483 final long origId = Binder.clearCallingIdentity();
11484 processNextBroadcast(false);
11485 trimApplications();
11486 Binder.restoreCallingIdentity(origId);
11487 }
11488
11489 void removeReceiverLocked(ReceiverList rl) {
11490 mRegisteredReceivers.remove(rl.receiver.asBinder());
11491 int N = rl.size();
11492 for (int i=0; i<N; i++) {
11493 mReceiverResolver.removeFilter(rl.get(i));
11494 }
11495 }
11496
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011497 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11498 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11499 ProcessRecord r = mLruProcesses.get(i);
11500 if (r.thread != null) {
11501 try {
11502 r.thread.dispatchPackageBroadcast(cmd, packages);
11503 } catch (RemoteException ex) {
11504 }
11505 }
11506 }
11507 }
11508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011509 private final int broadcastIntentLocked(ProcessRecord callerApp,
11510 String callerPackage, Intent intent, String resolvedType,
11511 IIntentReceiver resultTo, int resultCode, String resultData,
11512 Bundle map, String requiredPermission,
11513 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11514 intent = new Intent(intent);
11515
Dianne Hackborne7f97212011-02-24 14:40:20 -080011516 // By default broadcasts do not go to stopped apps.
11517 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11518
Joe Onorato8a9b2202010-02-26 18:56:32 -080011519 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011520 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11521 + " ordered=" + ordered);
11522 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011523 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524 }
11525
11526 // Handle special intents: if this broadcast is from the package
11527 // manager about a package being removed, we need to remove all of
11528 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011529 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011530 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011531 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11532 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011533 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011534 || uidRemoved) {
11535 if (checkComponentPermission(
11536 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011537 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011538 == PackageManager.PERMISSION_GRANTED) {
11539 if (uidRemoved) {
11540 final Bundle intentExtras = intent.getExtras();
11541 final int uid = intentExtras != null
11542 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11543 if (uid >= 0) {
11544 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11545 synchronized (bs) {
11546 bs.removeUidStatsLocked(uid);
11547 }
11548 }
11549 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011550 // If resources are unvailble just force stop all
11551 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011552 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011553 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11554 if (list != null && (list.length > 0)) {
11555 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011556 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011557 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011558 sendPackageBroadcastLocked(
11559 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011560 }
11561 } else {
11562 Uri data = intent.getData();
11563 String ssp;
11564 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11565 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11566 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011567 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011568 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011569 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011570 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11571 new String[] {ssp});
11572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011573 }
11574 }
11575 }
11576 } else {
11577 String msg = "Permission Denial: " + intent.getAction()
11578 + " broadcast from " + callerPackage + " (pid=" + callingPid
11579 + ", uid=" + callingUid + ")"
11580 + " requires "
11581 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011582 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583 throw new SecurityException(msg);
11584 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011585
11586 // Special case for adding a package: by default turn on compatibility
11587 // mode.
11588 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011589 Uri data = intent.getData();
11590 String ssp;
11591 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11592 mCompatModePackages.handlePackageAddedLocked(ssp,
11593 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011595 }
11596
11597 /*
11598 * If this is the time zone changed action, queue up a message that will reset the timezone
11599 * of all currently running processes. This message will get queued up before the broadcast
11600 * happens.
11601 */
11602 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11603 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11604 }
11605
Robert Greenwalt03595d02010-11-02 14:08:23 -070011606 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11607 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11608 }
11609
Robert Greenwalt434203a2010-10-11 16:00:27 -070011610 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11611 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11612 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11613 }
11614
Dianne Hackborn854060af2009-07-09 18:14:31 -070011615 /*
11616 * Prevent non-system code (defined here to be non-persistent
11617 * processes) from sending protected broadcasts.
11618 */
11619 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11620 || callingUid == Process.SHELL_UID || callingUid == 0) {
11621 // Always okay.
11622 } else if (callerApp == null || !callerApp.persistent) {
11623 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011624 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011625 intent.getAction())) {
11626 String msg = "Permission Denial: not allowed to send broadcast "
11627 + intent.getAction() + " from pid="
11628 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011629 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011630 throw new SecurityException(msg);
11631 }
11632 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011633 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011634 return BROADCAST_SUCCESS;
11635 }
11636 }
11637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011638 // Add to the sticky list if requested.
11639 if (sticky) {
11640 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11641 callingPid, callingUid)
11642 != PackageManager.PERMISSION_GRANTED) {
11643 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11644 + callingPid + ", uid=" + callingUid
11645 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011646 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011647 throw new SecurityException(msg);
11648 }
11649 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011650 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011651 + " and enforce permission " + requiredPermission);
11652 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11653 }
11654 if (intent.getComponent() != null) {
11655 throw new SecurityException(
11656 "Sticky broadcasts can't target a specific component");
11657 }
11658 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11659 if (list == null) {
11660 list = new ArrayList<Intent>();
11661 mStickyBroadcasts.put(intent.getAction(), list);
11662 }
11663 int N = list.size();
11664 int i;
11665 for (i=0; i<N; i++) {
11666 if (intent.filterEquals(list.get(i))) {
11667 // This sticky already exists, replace it.
11668 list.set(i, new Intent(intent));
11669 break;
11670 }
11671 }
11672 if (i >= N) {
11673 list.add(new Intent(intent));
11674 }
11675 }
11676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 // Figure out who all will receive this broadcast.
11678 List receivers = null;
11679 List<BroadcastFilter> registeredReceivers = null;
11680 try {
11681 if (intent.getComponent() != null) {
11682 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011683 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011684 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011685 if (ai != null) {
11686 receivers = new ArrayList();
11687 ResolveInfo ri = new ResolveInfo();
11688 ri.activityInfo = ai;
11689 receivers.add(ri);
11690 }
11691 } else {
11692 // Need to resolve the intent to interested receivers...
11693 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11694 == 0) {
11695 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011696 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011697 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011698 }
Mihai Preda074edef2009-05-18 17:13:31 +020011699 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011700 }
11701 } catch (RemoteException ex) {
11702 // pm is in same process, this will never happen.
11703 }
11704
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011705 final boolean replacePending =
11706 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11707
Joe Onorato8a9b2202010-02-26 18:56:32 -080011708 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011709 + " replacePending=" + replacePending);
11710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011711 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11712 if (!ordered && NR > 0) {
11713 // If we are not serializing this broadcast, then send the
11714 // registered receivers separately so they don't wait for the
11715 // components to be launched.
11716 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11717 callerPackage, callingPid, callingUid, requiredPermission,
11718 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011719 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011720 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721 TAG, "Enqueueing parallel broadcast " + r
11722 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011723 boolean replaced = false;
11724 if (replacePending) {
11725 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11726 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011727 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011728 "***** DROPPING PARALLEL: " + intent);
11729 mParallelBroadcasts.set(i, r);
11730 replaced = true;
11731 break;
11732 }
11733 }
11734 }
11735 if (!replaced) {
11736 mParallelBroadcasts.add(r);
11737 scheduleBroadcastsLocked();
11738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011739 registeredReceivers = null;
11740 NR = 0;
11741 }
11742
11743 // Merge into one list.
11744 int ir = 0;
11745 if (receivers != null) {
11746 // A special case for PACKAGE_ADDED: do not allow the package
11747 // being added to see this broadcast. This prevents them from
11748 // using this as a back door to get run as soon as they are
11749 // installed. Maybe in the future we want to have a special install
11750 // broadcast or such for apps, but we'd like to deliberately make
11751 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011752 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011753 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11754 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11755 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011756 Uri data = intent.getData();
11757 if (data != null) {
11758 String pkgName = data.getSchemeSpecificPart();
11759 if (pkgName != null) {
11760 skipPackages = new String[] { pkgName };
11761 }
11762 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011763 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011764 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011765 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011766 if (skipPackages != null && (skipPackages.length > 0)) {
11767 for (String skipPackage : skipPackages) {
11768 if (skipPackage != null) {
11769 int NT = receivers.size();
11770 for (int it=0; it<NT; it++) {
11771 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11772 if (curt.activityInfo.packageName.equals(skipPackage)) {
11773 receivers.remove(it);
11774 it--;
11775 NT--;
11776 }
11777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 }
11779 }
11780 }
11781
11782 int NT = receivers != null ? receivers.size() : 0;
11783 int it = 0;
11784 ResolveInfo curt = null;
11785 BroadcastFilter curr = null;
11786 while (it < NT && ir < NR) {
11787 if (curt == null) {
11788 curt = (ResolveInfo)receivers.get(it);
11789 }
11790 if (curr == null) {
11791 curr = registeredReceivers.get(ir);
11792 }
11793 if (curr.getPriority() >= curt.priority) {
11794 // Insert this broadcast record into the final list.
11795 receivers.add(it, curr);
11796 ir++;
11797 curr = null;
11798 it++;
11799 NT++;
11800 } else {
11801 // Skip to the next ResolveInfo in the final list.
11802 it++;
11803 curt = null;
11804 }
11805 }
11806 }
11807 while (ir < NR) {
11808 if (receivers == null) {
11809 receivers = new ArrayList();
11810 }
11811 receivers.add(registeredReceivers.get(ir));
11812 ir++;
11813 }
11814
11815 if ((receivers != null && receivers.size() > 0)
11816 || resultTo != null) {
11817 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11818 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011819 receivers, resultTo, resultCode, resultData, map, ordered,
11820 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011821 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011822 TAG, "Enqueueing ordered broadcast " + r
11823 + ": prev had " + mOrderedBroadcasts.size());
11824 if (DEBUG_BROADCAST) {
11825 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011826 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011827 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011828 boolean replaced = false;
11829 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011830 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011831 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011832 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011833 "***** DROPPING ORDERED: " + intent);
11834 mOrderedBroadcasts.set(i, r);
11835 replaced = true;
11836 break;
11837 }
11838 }
11839 }
11840 if (!replaced) {
11841 mOrderedBroadcasts.add(r);
11842 scheduleBroadcastsLocked();
11843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011844 }
11845
11846 return BROADCAST_SUCCESS;
11847 }
11848
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011849 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 // Refuse possible leaked file descriptors
11851 if (intent != null && intent.hasFileDescriptors() == true) {
11852 throw new IllegalArgumentException("File descriptors passed in Intent");
11853 }
11854
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011855 int flags = intent.getFlags();
11856
11857 if (!mProcessesReady) {
11858 // if the caller really truly claims to know what they're doing, go
11859 // ahead and allow the broadcast without launching any receivers
11860 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11861 intent = new Intent(intent);
11862 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11863 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11864 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11865 + " before boot completion");
11866 throw new IllegalStateException("Cannot broadcast before boot completed");
11867 }
11868 }
11869
11870 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11871 throw new IllegalArgumentException(
11872 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11873 }
11874
11875 return intent;
11876 }
11877
11878 public final int broadcastIntent(IApplicationThread caller,
11879 Intent intent, String resolvedType, IIntentReceiver resultTo,
11880 int resultCode, String resultData, Bundle map,
11881 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011882 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011883 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011885 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11886 final int callingPid = Binder.getCallingPid();
11887 final int callingUid = Binder.getCallingUid();
11888 final long origId = Binder.clearCallingIdentity();
11889 int res = broadcastIntentLocked(callerApp,
11890 callerApp != null ? callerApp.info.packageName : null,
11891 intent, resolvedType, resultTo,
11892 resultCode, resultData, map, requiredPermission, serialized,
11893 sticky, callingPid, callingUid);
11894 Binder.restoreCallingIdentity(origId);
11895 return res;
11896 }
11897 }
11898
11899 int broadcastIntentInPackage(String packageName, int uid,
11900 Intent intent, String resolvedType, IIntentReceiver resultTo,
11901 int resultCode, String resultData, Bundle map,
11902 String requiredPermission, boolean serialized, boolean sticky) {
11903 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011904 intent = verifyBroadcastLocked(intent);
11905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011906 final long origId = Binder.clearCallingIdentity();
11907 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11908 resultTo, resultCode, resultData, map, requiredPermission,
11909 serialized, sticky, -1, uid);
11910 Binder.restoreCallingIdentity(origId);
11911 return res;
11912 }
11913 }
11914
11915 public final void unbroadcastIntent(IApplicationThread caller,
11916 Intent intent) {
11917 // Refuse possible leaked file descriptors
11918 if (intent != null && intent.hasFileDescriptors() == true) {
11919 throw new IllegalArgumentException("File descriptors passed in Intent");
11920 }
11921
11922 synchronized(this) {
11923 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11924 != PackageManager.PERMISSION_GRANTED) {
11925 String msg = "Permission Denial: unbroadcastIntent() from pid="
11926 + Binder.getCallingPid()
11927 + ", uid=" + Binder.getCallingUid()
11928 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011929 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011930 throw new SecurityException(msg);
11931 }
11932 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11933 if (list != null) {
11934 int N = list.size();
11935 int i;
11936 for (i=0; i<N; i++) {
11937 if (intent.filterEquals(list.get(i))) {
11938 list.remove(i);
11939 break;
11940 }
11941 }
11942 }
11943 }
11944 }
11945
11946 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11947 String resultData, Bundle resultExtras, boolean resultAbort,
11948 boolean explicit) {
11949 if (mOrderedBroadcasts.size() == 0) {
11950 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011951 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011952 }
11953 return false;
11954 }
11955 BroadcastRecord r = mOrderedBroadcasts.get(0);
11956 if (r.receiver == null) {
11957 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011958 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011959 }
11960 return false;
11961 }
11962 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011963 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 return false;
11965 }
11966 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011967 r.state = BroadcastRecord.IDLE;
11968 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011969 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011970 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011971 }
11972 }
11973 r.receiver = null;
11974 r.intent.setComponent(null);
11975 if (r.curApp != null) {
11976 r.curApp.curReceiver = null;
11977 }
11978 if (r.curFilter != null) {
11979 r.curFilter.receiverList.curBroadcast = null;
11980 }
11981 r.curFilter = null;
11982 r.curApp = null;
11983 r.curComponent = null;
11984 r.curReceiver = null;
11985 mPendingBroadcast = null;
11986
11987 r.resultCode = resultCode;
11988 r.resultData = resultData;
11989 r.resultExtras = resultExtras;
11990 r.resultAbort = resultAbort;
11991
11992 // We will process the next receiver right now if this is finishing
11993 // an app receiver (which is always asynchronous) or after we have
11994 // come back from calling a receiver.
11995 return state == BroadcastRecord.APP_RECEIVE
11996 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11997 }
11998
11999 public void finishReceiver(IBinder who, int resultCode, String resultData,
12000 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012001 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002
12003 // Refuse possible leaked file descriptors
12004 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12005 throw new IllegalArgumentException("File descriptors passed in Bundle");
12006 }
12007
12008 boolean doNext;
12009
12010 final long origId = Binder.clearCallingIdentity();
12011
12012 synchronized(this) {
12013 doNext = finishReceiverLocked(
12014 who, resultCode, resultData, resultExtras, resultAbort, true);
12015 }
12016
12017 if (doNext) {
12018 processNextBroadcast(false);
12019 }
12020 trimApplications();
12021
12022 Binder.restoreCallingIdentity(origId);
12023 }
12024
Jeff Brown4d94a762010-09-23 11:33:28 -070012025 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 if (r.nextReceiver > 0) {
12027 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12028 if (curReceiver instanceof BroadcastFilter) {
12029 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012030 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012031 System.identityHashCode(r),
12032 r.intent.getAction(),
12033 r.nextReceiver - 1,
12034 System.identityHashCode(bf));
12035 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012036 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012037 System.identityHashCode(r),
12038 r.intent.getAction(),
12039 r.nextReceiver - 1,
12040 ((ResolveInfo)curReceiver).toString());
12041 }
12042 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012043 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012044 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012045 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012046 System.identityHashCode(r),
12047 r.intent.getAction(),
12048 r.nextReceiver,
12049 "NONE");
12050 }
12051 }
12052
Jeff Brown4d94a762010-09-23 11:33:28 -070012053 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12054 if (! mPendingBroadcastTimeoutMessage) {
12055 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12056 mHandler.sendMessageAtTime(msg, timeoutTime);
12057 mPendingBroadcastTimeoutMessage = true;
12058 }
12059 }
12060
12061 private final void cancelBroadcastTimeoutLocked() {
12062 if (mPendingBroadcastTimeoutMessage) {
12063 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12064 mPendingBroadcastTimeoutMessage = false;
12065 }
12066 }
12067
12068 private final void broadcastTimeoutLocked(boolean fromMsg) {
12069 if (fromMsg) {
12070 mPendingBroadcastTimeoutMessage = false;
12071 }
12072
12073 if (mOrderedBroadcasts.size() == 0) {
12074 return;
12075 }
12076
12077 long now = SystemClock.uptimeMillis();
12078 BroadcastRecord r = mOrderedBroadcasts.get(0);
12079 if (fromMsg) {
12080 if (mDidDexOpt) {
12081 // Delay timeouts until dexopt finishes.
12082 mDidDexOpt = false;
12083 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12084 setBroadcastTimeoutLocked(timeoutTime);
12085 return;
12086 }
12087 if (! mProcessesReady) {
12088 // Only process broadcast timeouts if the system is ready. That way
12089 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12090 // to do heavy lifting for system up.
12091 return;
12092 }
12093
12094 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12095 if (timeoutTime > now) {
12096 // We can observe premature timeouts because we do not cancel and reset the
12097 // broadcast timeout message after each receiver finishes. Instead, we set up
12098 // an initial timeout then kick it down the road a little further as needed
12099 // when it expires.
12100 if (DEBUG_BROADCAST) Slog.v(TAG,
12101 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12102 + timeoutTime);
12103 setBroadcastTimeoutLocked(timeoutTime);
12104 return;
12105 }
12106 }
12107
12108 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12109 + ", started " + (now - r.receiverTime) + "ms ago");
12110 r.receiverTime = now;
12111 r.anrCount++;
12112
12113 // Current receiver has passed its expiration date.
12114 if (r.nextReceiver <= 0) {
12115 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12116 return;
12117 }
12118
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012119 ProcessRecord app = null;
12120 String anrMessage = null;
12121
Jeff Brown4d94a762010-09-23 11:33:28 -070012122 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12123 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12124 logBroadcastReceiverDiscardLocked(r);
12125 if (curReceiver instanceof BroadcastFilter) {
12126 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12127 if (bf.receiverList.pid != 0
12128 && bf.receiverList.pid != MY_PID) {
12129 synchronized (this.mPidsSelfLocked) {
12130 app = this.mPidsSelfLocked.get(
12131 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012134 } else {
12135 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012136 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012137
Jeff Brown4d94a762010-09-23 11:33:28 -070012138 if (app != null) {
12139 anrMessage = "Broadcast of " + r.intent.toString();
12140 }
12141
12142 if (mPendingBroadcast == r) {
12143 mPendingBroadcast = null;
12144 }
12145
12146 // Move on to the next receiver.
12147 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12148 r.resultExtras, r.resultAbort, true);
12149 scheduleBroadcastsLocked();
12150
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012151 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012152 // Post the ANR to the handler since we do not want to process ANRs while
12153 // potentially holding our lock.
12154 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012156 }
12157
12158 private final void processCurBroadcastLocked(BroadcastRecord r,
12159 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012160 if (DEBUG_BROADCAST) Slog.v(TAG,
12161 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012162 if (app.thread == null) {
12163 throw new RemoteException();
12164 }
12165 r.receiver = app.thread.asBinder();
12166 r.curApp = app;
12167 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012168 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012169
12170 // Tell the application to launch this receiver.
12171 r.intent.setComponent(r.curComponent);
12172
12173 boolean started = false;
12174 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012175 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012176 "Delivering to component " + r.curComponent
12177 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012178 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012179 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012180 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012181 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012182 if (DEBUG_BROADCAST) Slog.v(TAG,
12183 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012184 started = true;
12185 } finally {
12186 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012187 if (DEBUG_BROADCAST) Slog.v(TAG,
12188 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012189 r.receiver = null;
12190 r.curApp = null;
12191 app.curReceiver = null;
12192 }
12193 }
12194
12195 }
12196
Jeff Brown4d94a762010-09-23 11:33:28 -070012197 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012198 Intent intent, int resultCode, String data, Bundle extras,
12199 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012200 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 if (app != null && app.thread != null) {
12202 // If we have an app thread, do the call through that so it is
12203 // correctly ordered with other one-way calls.
12204 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012205 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012206 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012207 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012208 }
12209 }
12210
Jeff Brown4d94a762010-09-23 11:33:28 -070012211 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012212 BroadcastFilter filter, boolean ordered) {
12213 boolean skip = false;
12214 if (filter.requiredPermission != null) {
12215 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012216 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012217 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012218 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012219 + r.intent.toString()
12220 + " from " + r.callerPackage + " (pid="
12221 + r.callingPid + ", uid=" + r.callingUid + ")"
12222 + " requires " + filter.requiredPermission
12223 + " due to registered receiver " + filter);
12224 skip = true;
12225 }
12226 }
12227 if (r.requiredPermission != null) {
12228 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012229 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012230 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012231 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012232 + r.intent.toString()
12233 + " to " + filter.receiverList.app
12234 + " (pid=" + filter.receiverList.pid
12235 + ", uid=" + filter.receiverList.uid + ")"
12236 + " requires " + r.requiredPermission
12237 + " due to sender " + r.callerPackage
12238 + " (uid " + r.callingUid + ")");
12239 skip = true;
12240 }
12241 }
12242
12243 if (!skip) {
12244 // If this is not being sent as an ordered broadcast, then we
12245 // don't want to touch the fields that keep track of the current
12246 // state of ordered broadcasts.
12247 if (ordered) {
12248 r.receiver = filter.receiverList.receiver.asBinder();
12249 r.curFilter = filter;
12250 filter.receiverList.curBroadcast = r;
12251 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012252 if (filter.receiverList.app != null) {
12253 // Bump hosting application to no longer be in background
12254 // scheduling class. Note that we can't do that if there
12255 // isn't an app... but we can only be in that case for
12256 // things that directly call the IActivityManager API, which
12257 // are already core system stuff so don't matter for this.
12258 r.curApp = filter.receiverList.app;
12259 filter.receiverList.app.curReceiver = r;
12260 updateOomAdjLocked();
12261 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012262 }
12263 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012264 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012266 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012267 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012269 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012270 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012271 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012272 if (ordered) {
12273 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12274 }
12275 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012276 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012277 if (ordered) {
12278 r.receiver = null;
12279 r.curFilter = null;
12280 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012281 if (filter.receiverList.app != null) {
12282 filter.receiverList.app.curReceiver = null;
12283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 }
12285 }
12286 }
12287 }
12288
Dianne Hackborn12527f92009-11-11 17:39:50 -080012289 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12290 if (r.callingUid < 0) {
12291 // This was from a registerReceiver() call; ignore it.
12292 return;
12293 }
12294 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12295 MAX_BROADCAST_HISTORY-1);
12296 r.finishTime = SystemClock.uptimeMillis();
12297 mBroadcastHistory[0] = r;
12298 }
12299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012300 private final void processNextBroadcast(boolean fromMsg) {
12301 synchronized(this) {
12302 BroadcastRecord r;
12303
Joe Onorato8a9b2202010-02-26 18:56:32 -080012304 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012305 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012306 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012307
12308 updateCpuStats();
12309
12310 if (fromMsg) {
12311 mBroadcastsScheduled = false;
12312 }
12313
12314 // First, deliver any non-serialized broadcasts right away.
12315 while (mParallelBroadcasts.size() > 0) {
12316 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012317 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012318 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012319 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012320 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012321 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012322 for (int i=0; i<N; i++) {
12323 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012324 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012325 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012326 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012327 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012328 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012329 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012330 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012331 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 }
12333
12334 // Now take care of the next serialized one...
12335
12336 // If we are waiting for a process to come up to handle the next
12337 // broadcast, then do nothing at this point. Just in case, we
12338 // check that the process we're waiting for still exists.
12339 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012340 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012341 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012342 + mPendingBroadcast.curApp);
12343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012344
12345 boolean isDead;
12346 synchronized (mPidsSelfLocked) {
12347 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12348 }
12349 if (!isDead) {
12350 // It's still alive, so keep waiting
12351 return;
12352 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012353 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012354 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012355 mPendingBroadcast.state = BroadcastRecord.IDLE;
12356 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012357 mPendingBroadcast = null;
12358 }
12359 }
12360
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012361 boolean looped = false;
12362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012363 do {
12364 if (mOrderedBroadcasts.size() == 0) {
12365 // No more broadcasts pending, so all done!
12366 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012367 if (looped) {
12368 // If we had finished the last ordered broadcast, then
12369 // make sure all processes have correct oom and sched
12370 // adjustments.
12371 updateOomAdjLocked();
12372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012373 return;
12374 }
12375 r = mOrderedBroadcasts.get(0);
12376 boolean forceReceive = false;
12377
12378 // Ensure that even if something goes awry with the timeout
12379 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012380 // and continue to make progress.
12381 //
12382 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012383 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012384 // one time heavy lifting after system upgrades and can take
12385 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012386 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012387 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012388 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012389 if ((numReceivers > 0) &&
12390 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012391 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012392 + " now=" + now
12393 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012394 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012395 + " intent=" + r.intent
12396 + " numReceivers=" + numReceivers
12397 + " nextReceiver=" + r.nextReceiver
12398 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012399 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012400 forceReceive = true;
12401 r.state = BroadcastRecord.IDLE;
12402 }
12403 }
12404
12405 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012406 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012407 "processNextBroadcast() called when not idle (state="
12408 + r.state + ")");
12409 return;
12410 }
12411
12412 if (r.receivers == null || r.nextReceiver >= numReceivers
12413 || r.resultAbort || forceReceive) {
12414 // No more receivers for this broadcast! Send the final
12415 // result if requested...
12416 if (r.resultTo != null) {
12417 try {
12418 if (DEBUG_BROADCAST) {
12419 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012420 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012421 + " seq=" + seq + " app=" + r.callerApp);
12422 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012423 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012424 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012425 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012426 // Set this to null so that the reference
12427 // (local and remote) isnt kept in the mBroadcastHistory.
12428 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012429 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012430 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012431 }
12432 }
12433
Joe Onorato8a9b2202010-02-26 18:56:32 -080012434 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012435 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012436
Joe Onorato8a9b2202010-02-26 18:56:32 -080012437 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012438 + r);
12439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012441 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012442 mOrderedBroadcasts.remove(0);
12443 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012444 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012445 continue;
12446 }
12447 } while (r == null);
12448
12449 // Get the next receiver...
12450 int recIdx = r.nextReceiver++;
12451
12452 // Keep track of when this receiver started, and make sure there
12453 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012454 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012455 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012456 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012457 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012458 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012459 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012460 }
12461 if (! mPendingBroadcastTimeoutMessage) {
12462 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012463 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012464 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12465 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012466 }
12467
12468 Object nextReceiver = r.receivers.get(recIdx);
12469 if (nextReceiver instanceof BroadcastFilter) {
12470 // Simple case: this is a registered receiver who gets
12471 // a direct call.
12472 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012473 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012474 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012475 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012476 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012477 if (r.receiver == null || !r.ordered) {
12478 // The receiver has already finished, so schedule to
12479 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012480 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12481 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012482 r.state = BroadcastRecord.IDLE;
12483 scheduleBroadcastsLocked();
12484 }
12485 return;
12486 }
12487
12488 // Hard case: need to instantiate the receiver, possibly
12489 // starting its application process to host it.
12490
12491 ResolveInfo info =
12492 (ResolveInfo)nextReceiver;
12493
12494 boolean skip = false;
12495 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012496 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12497 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012498 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012499 if (!info.activityInfo.exported) {
12500 Slog.w(TAG, "Permission Denial: broadcasting "
12501 + r.intent.toString()
12502 + " from " + r.callerPackage + " (pid=" + r.callingPid
12503 + ", uid=" + r.callingUid + ")"
12504 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12505 + " due to receiver " + info.activityInfo.packageName
12506 + "/" + info.activityInfo.name);
12507 } else {
12508 Slog.w(TAG, "Permission Denial: broadcasting "
12509 + r.intent.toString()
12510 + " from " + r.callerPackage + " (pid=" + r.callingPid
12511 + ", uid=" + r.callingUid + ")"
12512 + " requires " + info.activityInfo.permission
12513 + " due to receiver " + info.activityInfo.packageName
12514 + "/" + info.activityInfo.name);
12515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012516 skip = true;
12517 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012518 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012519 r.requiredPermission != null) {
12520 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012521 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012522 checkPermission(r.requiredPermission,
12523 info.activityInfo.applicationInfo.packageName);
12524 } catch (RemoteException e) {
12525 perm = PackageManager.PERMISSION_DENIED;
12526 }
12527 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012528 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012529 + r.intent + " to "
12530 + info.activityInfo.applicationInfo.packageName
12531 + " requires " + r.requiredPermission
12532 + " due to sender " + r.callerPackage
12533 + " (uid " + r.callingUid + ")");
12534 skip = true;
12535 }
12536 }
12537 if (r.curApp != null && r.curApp.crashing) {
12538 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012539 if (DEBUG_BROADCAST) Slog.v(TAG,
12540 "Skipping deliver ordered " + r + " to " + r.curApp
12541 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012542 skip = true;
12543 }
12544
12545 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012546 if (DEBUG_BROADCAST) Slog.v(TAG,
12547 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 r.receiver = null;
12549 r.curFilter = null;
12550 r.state = BroadcastRecord.IDLE;
12551 scheduleBroadcastsLocked();
12552 return;
12553 }
12554
12555 r.state = BroadcastRecord.APP_RECEIVE;
12556 String targetProcess = info.activityInfo.processName;
12557 r.curComponent = new ComponentName(
12558 info.activityInfo.applicationInfo.packageName,
12559 info.activityInfo.name);
12560 r.curReceiver = info.activityInfo;
12561
Dianne Hackborne7f97212011-02-24 14:40:20 -080012562 // Broadcast is being executed, its package can't be stopped.
12563 try {
12564 AppGlobals.getPackageManager().setPackageStoppedState(
12565 r.curComponent.getPackageName(), false);
12566 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012567 } catch (IllegalArgumentException e) {
12568 Slog.w(TAG, "Failed trying to unstop package "
12569 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012570 }
12571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012572 // Is this receiver's application already running?
12573 ProcessRecord app = getProcessRecordLocked(targetProcess,
12574 info.activityInfo.applicationInfo.uid);
12575 if (app != null && app.thread != null) {
12576 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012577 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012578 processCurBroadcastLocked(r, app);
12579 return;
12580 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012581 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012582 + r.curComponent, e);
12583 }
12584
12585 // If a dead object exception was thrown -- fall through to
12586 // restart the application.
12587 }
12588
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012589 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012590 if (DEBUG_BROADCAST) Slog.v(TAG,
12591 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012592 if ((r.curApp=startProcessLocked(targetProcess,
12593 info.activityInfo.applicationInfo, true,
12594 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012595 "broadcast", r.curComponent,
12596 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12597 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012598 // Ah, this recipient is unavailable. Finish it if necessary,
12599 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012600 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012601 + info.activityInfo.applicationInfo.packageName + "/"
12602 + info.activityInfo.applicationInfo.uid + " for broadcast "
12603 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012604 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012605 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12606 r.resultExtras, r.resultAbort, true);
12607 scheduleBroadcastsLocked();
12608 r.state = BroadcastRecord.IDLE;
12609 return;
12610 }
12611
12612 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012613 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012614 }
12615 }
12616
12617 // =========================================================
12618 // INSTRUMENTATION
12619 // =========================================================
12620
12621 public boolean startInstrumentation(ComponentName className,
12622 String profileFile, int flags, Bundle arguments,
12623 IInstrumentationWatcher watcher) {
12624 // Refuse possible leaked file descriptors
12625 if (arguments != null && arguments.hasFileDescriptors()) {
12626 throw new IllegalArgumentException("File descriptors passed in Bundle");
12627 }
12628
12629 synchronized(this) {
12630 InstrumentationInfo ii = null;
12631 ApplicationInfo ai = null;
12632 try {
12633 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012634 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012635 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012636 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012637 } catch (PackageManager.NameNotFoundException e) {
12638 }
12639 if (ii == null) {
12640 reportStartInstrumentationFailure(watcher, className,
12641 "Unable to find instrumentation info for: " + className);
12642 return false;
12643 }
12644 if (ai == null) {
12645 reportStartInstrumentationFailure(watcher, className,
12646 "Unable to find instrumentation target package: " + ii.targetPackage);
12647 return false;
12648 }
12649
12650 int match = mContext.getPackageManager().checkSignatures(
12651 ii.targetPackage, ii.packageName);
12652 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12653 String msg = "Permission Denial: starting instrumentation "
12654 + className + " from pid="
12655 + Binder.getCallingPid()
12656 + ", uid=" + Binder.getCallingPid()
12657 + " not allowed because package " + ii.packageName
12658 + " does not have a signature matching the target "
12659 + ii.targetPackage;
12660 reportStartInstrumentationFailure(watcher, className, msg);
12661 throw new SecurityException(msg);
12662 }
12663
12664 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012665 // Instrumentation can kill and relaunch even persistent processes
12666 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012667 ProcessRecord app = addAppLocked(ai);
12668 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012669 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012670 app.instrumentationProfileFile = profileFile;
12671 app.instrumentationArguments = arguments;
12672 app.instrumentationWatcher = watcher;
12673 app.instrumentationResultClass = className;
12674 Binder.restoreCallingIdentity(origId);
12675 }
12676
12677 return true;
12678 }
12679
12680 /**
12681 * Report errors that occur while attempting to start Instrumentation. Always writes the
12682 * error to the logs, but if somebody is watching, send the report there too. This enables
12683 * the "am" command to report errors with more information.
12684 *
12685 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12686 * @param cn The component name of the instrumentation.
12687 * @param report The error report.
12688 */
12689 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12690 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012691 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012692 try {
12693 if (watcher != null) {
12694 Bundle results = new Bundle();
12695 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12696 results.putString("Error", report);
12697 watcher.instrumentationStatus(cn, -1, results);
12698 }
12699 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012700 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012701 }
12702 }
12703
12704 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12705 if (app.instrumentationWatcher != null) {
12706 try {
12707 // NOTE: IInstrumentationWatcher *must* be oneway here
12708 app.instrumentationWatcher.instrumentationFinished(
12709 app.instrumentationClass,
12710 resultCode,
12711 results);
12712 } catch (RemoteException e) {
12713 }
12714 }
12715 app.instrumentationWatcher = null;
12716 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012717 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012718 app.instrumentationProfileFile = null;
12719 app.instrumentationArguments = null;
12720
Christopher Tate3dacd842011-08-19 14:56:15 -070012721 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012722 }
12723
12724 public void finishInstrumentation(IApplicationThread target,
12725 int resultCode, Bundle results) {
12726 // Refuse possible leaked file descriptors
12727 if (results != null && results.hasFileDescriptors()) {
12728 throw new IllegalArgumentException("File descriptors passed in Intent");
12729 }
12730
12731 synchronized(this) {
12732 ProcessRecord app = getRecordForAppLocked(target);
12733 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012734 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012735 return;
12736 }
12737 final long origId = Binder.clearCallingIdentity();
12738 finishInstrumentationLocked(app, resultCode, results);
12739 Binder.restoreCallingIdentity(origId);
12740 }
12741 }
12742
12743 // =========================================================
12744 // CONFIGURATION
12745 // =========================================================
12746
12747 public ConfigurationInfo getDeviceConfigurationInfo() {
12748 ConfigurationInfo config = new ConfigurationInfo();
12749 synchronized (this) {
12750 config.reqTouchScreen = mConfiguration.touchscreen;
12751 config.reqKeyboardType = mConfiguration.keyboard;
12752 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012753 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12754 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012755 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12756 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012757 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12758 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012759 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12760 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012761 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 }
12763 return config;
12764 }
12765
12766 public Configuration getConfiguration() {
12767 Configuration ci;
12768 synchronized(this) {
12769 ci = new Configuration(mConfiguration);
12770 }
12771 return ci;
12772 }
12773
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012774 public void updatePersistentConfiguration(Configuration values) {
12775 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12776 "updateConfiguration()");
12777 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12778 "updateConfiguration()");
12779 if (values == null) {
12780 throw new NullPointerException("Configuration must not be null");
12781 }
12782
12783 synchronized(this) {
12784 final long origId = Binder.clearCallingIdentity();
12785 updateConfigurationLocked(values, null, true);
12786 Binder.restoreCallingIdentity(origId);
12787 }
12788 }
12789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012790 public void updateConfiguration(Configuration values) {
12791 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12792 "updateConfiguration()");
12793
12794 synchronized(this) {
12795 if (values == null && mWindowManager != null) {
12796 // sentinel: fetch the current configuration from the window manager
12797 values = mWindowManager.computeNewConfiguration();
12798 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012799
12800 if (mWindowManager != null) {
12801 mProcessList.applyDisplaySize(mWindowManager);
12802 }
12803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012804 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012805 if (values != null) {
12806 Settings.System.clearConfiguration(values);
12807 }
12808 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 Binder.restoreCallingIdentity(origId);
12810 }
12811 }
12812
12813 /**
12814 * Do either or both things: (1) change the current configuration, and (2)
12815 * make sure the given activity is running with the (now) current
12816 * configuration. Returns true if the activity has been left running, or
12817 * false if <var>starting</var> is being destroyed to match the new
12818 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012819 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012820 */
12821 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012822 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012823 int changes = 0;
12824
12825 boolean kept = true;
12826
12827 if (values != null) {
12828 Configuration newConfig = new Configuration(mConfiguration);
12829 changes = newConfig.updateFrom(values);
12830 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012831 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012832 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012833 }
12834
Doug Zongker2bec3d42009-12-04 12:52:44 -080012835 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012836
12837 if (values.locale != null) {
12838 saveLocaleLocked(values.locale,
12839 !values.locale.equals(mConfiguration.locale),
12840 values.userSetLocale);
12841 }
12842
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012843 mConfigurationSeq++;
12844 if (mConfigurationSeq <= 0) {
12845 mConfigurationSeq = 1;
12846 }
12847 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012848 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012849 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012850
12851 AttributeCache ac = AttributeCache.instance();
12852 if (ac != null) {
12853 ac.updateConfiguration(mConfiguration);
12854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012855
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012856 // Make sure all resources in our process are updated
12857 // right now, so that anyone who is going to retrieve
12858 // resource values after we return will be sure to get
12859 // the new ones. This is especially important during
12860 // boot, where the first config change needs to guarantee
12861 // all resources have that config before following boot
12862 // code is executed.
12863 mSystemThread.applyConfigurationToResources(newConfig);
12864
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012865 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012866 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12867 msg.obj = new Configuration(mConfiguration);
12868 mHandler.sendMessage(msg);
12869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012870
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012871 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12872 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012873 try {
12874 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012875 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012876 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012877 app.thread.scheduleConfigurationChanged(mConfiguration);
12878 }
12879 } catch (Exception e) {
12880 }
12881 }
12882 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012883 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12884 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012885 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12886 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012887 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12888 broadcastIntentLocked(null, null,
12889 new Intent(Intent.ACTION_LOCALE_CHANGED),
12890 null, null, 0, null, null,
12891 null, false, false, MY_PID, Process.SYSTEM_UID);
12892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012893 }
12894 }
12895
12896 if (changes != 0 && starting == null) {
12897 // If the configuration changed, and the caller is not already
12898 // in the process of starting an activity, then find the top
12899 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012900 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012901 }
12902
12903 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012904 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012905 // And we need to make sure at this point that all other activities
12906 // are made visible with the correct configuration.
12907 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012908 }
12909
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012910 if (values != null && mWindowManager != null) {
12911 mWindowManager.setNewConfiguration(mConfiguration);
12912 }
12913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012914 return kept;
12915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012916
12917 /**
12918 * Save the locale. You must be inside a synchronized (this) block.
12919 */
12920 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12921 if(isDiff) {
12922 SystemProperties.set("user.language", l.getLanguage());
12923 SystemProperties.set("user.region", l.getCountry());
12924 }
12925
12926 if(isPersist) {
12927 SystemProperties.set("persist.sys.language", l.getLanguage());
12928 SystemProperties.set("persist.sys.country", l.getCountry());
12929 SystemProperties.set("persist.sys.localevar", l.getVariant());
12930 }
12931 }
12932
12933 // =========================================================
12934 // LIFETIME MANAGEMENT
12935 // =========================================================
12936
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012937 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12938 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012939 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012940 // This adjustment has already been computed. If we are calling
12941 // from the top, we may have already computed our adjustment with
12942 // an earlier hidden adjustment that isn't really for us... if
12943 // so, use the new hidden adjustment.
12944 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012945 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012946 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012947 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012948 }
12949
12950 if (app.thread == null) {
12951 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012952 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012953 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012954 }
12955
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012956 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12957 app.adjSource = null;
12958 app.adjTarget = null;
12959 app.empty = false;
12960 app.hidden = false;
12961
12962 final int activitiesSize = app.activities.size();
12963
Dianne Hackborn7d608422011-08-07 16:24:18 -070012964 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012965 // The max adjustment doesn't allow this app to be anything
12966 // below foreground, so it is not worth doing work for it.
12967 app.adjType = "fixed";
12968 app.adjSeq = mAdjSeq;
12969 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012970 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012971 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012972 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012973 // System process can do UI, and when they do we want to have
12974 // them trim their memory after the user leaves the UI. To
12975 // facilitate this, here we need to determine whether or not it
12976 // is currently showing UI.
12977 app.systemNoUi = true;
12978 if (app == TOP_APP) {
12979 app.systemNoUi = false;
12980 } else if (activitiesSize > 0) {
12981 for (int j = 0; j < activitiesSize; j++) {
12982 final ActivityRecord r = app.activities.get(j);
12983 if (r.visible) {
12984 app.systemNoUi = false;
12985 break;
12986 }
12987 }
12988 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012989 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012990 }
12991
12992 final boolean hadForegroundActivities = app.foregroundActivities;
12993
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012994 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012995 app.keeping = false;
12996 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012997
The Android Open Source Project4df24232009-03-05 14:34:35 -080012998 // Determine the importance of the process, starting with most
12999 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013000 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013001 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013002 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013003 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013004 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013005 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013006 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013007 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013008 } else if (app.instrumentationClass != null) {
13009 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013010 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013011 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013012 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013013 } else if (app.curReceiver != null ||
13014 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13015 // An app that is currently receiving a broadcast also
13016 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013017 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013018 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013019 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013020 } else if (app.executingServices.size() > 0) {
13021 // An app that is currently executing a service callback also
13022 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013023 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013024 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013025 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013026 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013027 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013028 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013029 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013030 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013031 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013032 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013033 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013034 // A very not-needed process. If this is lower in the lru list,
13035 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013036 adj = hiddenAdj;
13037 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013038 app.hidden = true;
13039 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013040 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013041 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013042
13043 // Examine all activities if not already foreground.
13044 if (!app.foregroundActivities && activitiesSize > 0) {
13045 for (int j = 0; j < activitiesSize; j++) {
13046 final ActivityRecord r = app.activities.get(j);
13047 if (r.visible) {
13048 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013049 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13050 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013051 app.adjType = "visible";
13052 }
13053 schedGroup = Process.THREAD_GROUP_DEFAULT;
13054 app.hidden = false;
13055 app.foregroundActivities = true;
13056 break;
13057 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13058 || r.state == ActivityState.STOPPING) {
13059 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013060 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13061 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013062 app.adjType = "stopping";
13063 }
13064 app.foregroundActivities = true;
13065 }
13066 }
13067 }
13068
Dianne Hackborn7d608422011-08-07 16:24:18 -070013069 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013070 if (app.foregroundServices) {
13071 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013072 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013073 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013074 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013075 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013076 } else if (app.forcingToForeground != null) {
13077 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013078 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013079 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013080 app.adjType = "force-foreground";
13081 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013082 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013083 }
13084 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013085
Dianne Hackborn7d608422011-08-07 16:24:18 -070013086 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013087 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013088 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013089 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013090 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013091 app.adjType = "heavy";
13092 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013093
Dianne Hackborn7d608422011-08-07 16:24:18 -070013094 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013095 // This process is hosting what we currently consider to be the
13096 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013097 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013098 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013099 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013100 app.adjType = "home";
13101 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013102
13103 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13104 + " reason=" + app.adjType);
13105
The Android Open Source Project4df24232009-03-05 14:34:35 -080013106 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013107 // there are applications dependent on our services or providers, but
13108 // this gives us a baseline and makes sure we don't get into an
13109 // infinite recursion.
13110 app.adjSeq = mAdjSeq;
13111 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013112
Christopher Tate6fa95972009-06-05 18:43:55 -070013113 if (mBackupTarget != null && app == mBackupTarget.app) {
13114 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013115 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013116 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013117 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013118 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013119 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013120 }
13121 }
13122
Dianne Hackborn7d608422011-08-07 16:24:18 -070013123 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013124 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013125 final long now = SystemClock.uptimeMillis();
13126 // This process is more important if the top activity is
13127 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013128 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013129 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013130 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013131 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013132 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013133 // If this process has shown some UI, let it immediately
13134 // go to the LRU list because it may be pretty heavy with
13135 // UI stuff. We'll tag it with a label just to help
13136 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013137 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013138 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013139 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013140 } else {
13141 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13142 // This service has seen some activity within
13143 // recent memory, so we will keep its process ahead
13144 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013145 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13146 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013147 app.adjType = "started-services";
13148 app.hidden = false;
13149 }
13150 }
13151 // If we have let the service slide into the background
13152 // state, still have some text describing what it is doing
13153 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013154 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013155 app.adjType = "started-bg-services";
13156 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013157 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013158 // Don't kill this process because it is doing work; it
13159 // has said it is doing work.
13160 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013161 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013162 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013163 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013164 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013165 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013166 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013167 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013168 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013169 // XXX should compute this based on the max of
13170 // all connected clients.
13171 ConnectionRecord cr = clist.get(i);
13172 if (cr.binding.client == app) {
13173 // Binding to ourself is not interesting.
13174 continue;
13175 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013176 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013177 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013178 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013179 int myHiddenAdj = hiddenAdj;
13180 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013181 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013182 myHiddenAdj = client.hiddenAdj;
13183 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013184 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013185 }
13186 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013187 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013188 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013189 String adjType = null;
13190 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13191 // Not doing bind OOM management, so treat
13192 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013193 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013194 // If this process has shown some UI, let it immediately
13195 // go to the LRU list because it may be pretty heavy with
13196 // UI stuff. We'll tag it with a label just to help
13197 // debug and understand what is going on.
13198 if (adj > clientAdj) {
13199 adjType = "bound-bg-ui-services";
13200 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013201 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013202 clientAdj = adj;
13203 } else {
13204 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13205 // This service has not seen activity within
13206 // recent memory, so allow it to drop to the
13207 // LRU list if there is no other reason to keep
13208 // it around. We'll also tag it with a label just
13209 // to help debug and undertand what is going on.
13210 if (adj > clientAdj) {
13211 adjType = "bound-bg-services";
13212 }
13213 clientAdj = adj;
13214 }
13215 }
13216 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013217 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013218 // If this process has recently shown UI, and
13219 // the process that is binding to it is less
13220 // important than being visible, then we don't
13221 // care about the binding as much as we care
13222 // about letting this process get into the LRU
13223 // list to be killed and restarted if needed for
13224 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013225 if (app.hasShownUi && app != mHomeProcess
13226 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013227 adjType = "bound-bg-ui-services";
13228 } else {
13229 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13230 |Context.BIND_IMPORTANT)) != 0) {
13231 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013232 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013233 adj = clientAdj;
13234 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013235 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013236 }
13237 if (!client.hidden) {
13238 app.hidden = false;
13239 }
13240 if (client.keeping) {
13241 app.keeping = true;
13242 }
13243 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013244 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013245 }
13246 if (adjType != null) {
13247 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013248 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13249 .REASON_SERVICE_IN_USE;
13250 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013251 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013252 app.adjTarget = s.name;
13253 }
13254 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13255 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13256 schedGroup = Process.THREAD_GROUP_DEFAULT;
13257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013258 }
13259 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013260 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13261 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013262 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013263 (a.visible || a.state == ActivityState.RESUMED
13264 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013265 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013266 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13267 schedGroup = Process.THREAD_GROUP_DEFAULT;
13268 }
13269 app.hidden = false;
13270 app.adjType = "service";
13271 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13272 .REASON_SERVICE_IN_USE;
13273 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013274 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013275 app.adjTarget = s.name;
13276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 }
13279 }
13280 }
13281 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013282
Dianne Hackborn287952c2010-09-22 22:34:31 -070013283 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013284 // would like to avoid killing it unless it would prevent the current
13285 // application from running. By default we put the process in
13286 // with the rest of the background processes; as we scan through
13287 // its services we may bump it up from there.
13288 if (adj > hiddenAdj) {
13289 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013290 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013291 app.adjType = "bg-services";
13292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013293 }
13294
Dianne Hackborn7d608422011-08-07 16:24:18 -070013295 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013296 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013297 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013298 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013299 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013300 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013301 if (cpr.clients.size() != 0) {
13302 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013303 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013304 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013305 if (client == app) {
13306 // Being our own client is not interesting.
13307 continue;
13308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013309 int myHiddenAdj = hiddenAdj;
13310 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013311 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013312 myHiddenAdj = client.hiddenAdj;
13313 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013314 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013315 }
13316 }
13317 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013318 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013319 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013320 if (app.hasShownUi && app != mHomeProcess
13321 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013322 app.adjType = "bg-ui-provider";
13323 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013324 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13325 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013326 app.adjType = "provider";
13327 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013328 if (!client.hidden) {
13329 app.hidden = false;
13330 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013331 if (client.keeping) {
13332 app.keeping = true;
13333 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013334 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13335 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013336 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013337 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013338 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013339 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013340 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13341 schedGroup = Process.THREAD_GROUP_DEFAULT;
13342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013343 }
13344 }
13345 // If the provider has external (non-framework) process
13346 // dependencies, ensure that its adjustment is at least
13347 // FOREGROUND_APP_ADJ.
13348 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013349 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13350 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013351 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013352 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013353 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013354 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013355 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013356 }
13357 }
13358 }
13359 }
13360
13361 app.curRawAdj = adj;
13362
Joe Onorato8a9b2202010-02-26 18:56:32 -080013363 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013364 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13365 if (adj > app.maxAdj) {
13366 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013367 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013368 schedGroup = Process.THREAD_GROUP_DEFAULT;
13369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013370 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013371 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013372 app.keeping = true;
13373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013374
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013375 if (app.hasAboveClient) {
13376 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13377 // then we need to drop its adjustment to be lower than the service's
13378 // in order to honor the request. We want to drop it by one adjustment
13379 // level... but there is special meaning applied to various levels so
13380 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013381 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013382 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013383 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13384 adj = ProcessList.VISIBLE_APP_ADJ;
13385 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13386 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13387 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13388 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13389 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013390 adj++;
13391 }
13392 }
13393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013395 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013396
13397 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013398 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13399 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013400 }
13401
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013402 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013403 }
13404
13405 /**
13406 * Ask a given process to GC right now.
13407 */
13408 final void performAppGcLocked(ProcessRecord app) {
13409 try {
13410 app.lastRequestedGc = SystemClock.uptimeMillis();
13411 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013412 if (app.reportLowMemory) {
13413 app.reportLowMemory = false;
13414 app.thread.scheduleLowMemory();
13415 } else {
13416 app.thread.processInBackground();
13417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013418 }
13419 } catch (Exception e) {
13420 // whatever.
13421 }
13422 }
13423
13424 /**
13425 * Returns true if things are idle enough to perform GCs.
13426 */
Josh Bartel7f208742010-02-25 11:01:44 -060013427 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013428 return mParallelBroadcasts.size() == 0
13429 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013430 && (mSleeping || (mMainStack.mResumedActivity != null &&
13431 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013432 }
13433
13434 /**
13435 * Perform GCs on all processes that are waiting for it, but only
13436 * if things are idle.
13437 */
13438 final void performAppGcsLocked() {
13439 final int N = mProcessesToGc.size();
13440 if (N <= 0) {
13441 return;
13442 }
Josh Bartel7f208742010-02-25 11:01:44 -060013443 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013444 while (mProcessesToGc.size() > 0) {
13445 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013446 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013447 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13448 <= SystemClock.uptimeMillis()) {
13449 // To avoid spamming the system, we will GC processes one
13450 // at a time, waiting a few seconds between each.
13451 performAppGcLocked(proc);
13452 scheduleAppGcsLocked();
13453 return;
13454 } else {
13455 // It hasn't been long enough since we last GCed this
13456 // process... put it in the list to wait for its time.
13457 addProcessToGcListLocked(proc);
13458 break;
13459 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013460 }
13461 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013462
13463 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013464 }
13465 }
13466
13467 /**
13468 * If all looks good, perform GCs on all processes waiting for them.
13469 */
13470 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013471 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013472 performAppGcsLocked();
13473 return;
13474 }
13475 // Still not idle, wait some more.
13476 scheduleAppGcsLocked();
13477 }
13478
13479 /**
13480 * Schedule the execution of all pending app GCs.
13481 */
13482 final void scheduleAppGcsLocked() {
13483 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013484
13485 if (mProcessesToGc.size() > 0) {
13486 // Schedule a GC for the time to the next process.
13487 ProcessRecord proc = mProcessesToGc.get(0);
13488 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13489
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013490 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013491 long now = SystemClock.uptimeMillis();
13492 if (when < (now+GC_TIMEOUT)) {
13493 when = now + GC_TIMEOUT;
13494 }
13495 mHandler.sendMessageAtTime(msg, when);
13496 }
13497 }
13498
13499 /**
13500 * Add a process to the array of processes waiting to be GCed. Keeps the
13501 * list in sorted order by the last GC time. The process can't already be
13502 * on the list.
13503 */
13504 final void addProcessToGcListLocked(ProcessRecord proc) {
13505 boolean added = false;
13506 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13507 if (mProcessesToGc.get(i).lastRequestedGc <
13508 proc.lastRequestedGc) {
13509 added = true;
13510 mProcessesToGc.add(i+1, proc);
13511 break;
13512 }
13513 }
13514 if (!added) {
13515 mProcessesToGc.add(0, proc);
13516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 }
13518
13519 /**
13520 * Set up to ask a process to GC itself. This will either do it
13521 * immediately, or put it on the list of processes to gc the next
13522 * time things are idle.
13523 */
13524 final void scheduleAppGcLocked(ProcessRecord app) {
13525 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013526 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013527 return;
13528 }
13529 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013530 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 scheduleAppGcsLocked();
13532 }
13533 }
13534
Dianne Hackborn287952c2010-09-22 22:34:31 -070013535 final void checkExcessivePowerUsageLocked(boolean doKills) {
13536 updateCpuStatsNow();
13537
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013538 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013539 boolean doWakeKills = doKills;
13540 boolean doCpuKills = doKills;
13541 if (mLastPowerCheckRealtime == 0) {
13542 doWakeKills = false;
13543 }
13544 if (mLastPowerCheckUptime == 0) {
13545 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013546 }
13547 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013548 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013549 }
13550 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013551 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13552 final long curUptime = SystemClock.uptimeMillis();
13553 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13554 mLastPowerCheckRealtime = curRealtime;
13555 mLastPowerCheckUptime = curUptime;
13556 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13557 doWakeKills = false;
13558 }
13559 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13560 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013561 }
13562 int i = mLruProcesses.size();
13563 while (i > 0) {
13564 i--;
13565 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013566 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013567 long wtime;
13568 synchronized (stats) {
13569 wtime = stats.getProcessWakeTime(app.info.uid,
13570 app.pid, curRealtime);
13571 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013572 long wtimeUsed = wtime - app.lastWakeTime;
13573 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13574 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013575 StringBuilder sb = new StringBuilder(128);
13576 sb.append("Wake for ");
13577 app.toShortString(sb);
13578 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013579 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013580 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013581 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013582 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013583 sb.append((wtimeUsed*100)/realtimeSince);
13584 sb.append("%)");
13585 Slog.i(TAG, sb.toString());
13586 sb.setLength(0);
13587 sb.append("CPU for ");
13588 app.toShortString(sb);
13589 sb.append(": over ");
13590 TimeUtils.formatDuration(uptimeSince, sb);
13591 sb.append(" used ");
13592 TimeUtils.formatDuration(cputimeUsed, sb);
13593 sb.append(" (");
13594 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013595 sb.append("%)");
13596 Slog.i(TAG, sb.toString());
13597 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013598 // If a process has held a wake lock for more
13599 // than 50% of the time during this period,
13600 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013601 if (doWakeKills && realtimeSince > 0
13602 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13603 synchronized (stats) {
13604 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13605 realtimeSince, wtimeUsed);
13606 }
13607 Slog.w(TAG, "Excessive wake lock in " + app.processName
13608 + " (pid " + app.pid + "): held " + wtimeUsed
13609 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013610 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13611 app.processName, app.setAdj, "excessive wake lock");
13612 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013613 } else if (doCpuKills && uptimeSince > 0
13614 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13615 synchronized (stats) {
13616 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13617 uptimeSince, cputimeUsed);
13618 }
13619 Slog.w(TAG, "Excessive CPU in " + app.processName
13620 + " (pid " + app.pid + "): used " + cputimeUsed
13621 + " during " + uptimeSince);
13622 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13623 app.processName, app.setAdj, "excessive cpu");
13624 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013625 } else {
13626 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013627 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013628 }
13629 }
13630 }
13631 }
13632
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013633 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013634 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013635 app.hiddenAdj = hiddenAdj;
13636
13637 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013638 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013639 }
13640
Dianne Hackborn287952c2010-09-22 22:34:31 -070013641 final boolean wasKeeping = app.keeping;
13642
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013643 boolean success = true;
13644
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013645 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013646
Jeff Brown10e89712011-07-08 18:52:57 -070013647 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013648 if (false) {
13649 // Removing for now. Forcing GCs is not so useful anymore
13650 // with Dalvik, and the new memory level hint facility is
13651 // better for what we need to do these days.
13652 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13653 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13654 // If this app is transitioning from foreground to
13655 // non-foreground, have it do a gc.
13656 scheduleAppGcLocked(app);
13657 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13658 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13659 // Likewise do a gc when an app is moving in to the
13660 // background (such as a service stopping).
13661 scheduleAppGcLocked(app);
13662 }
Jeff Brown10e89712011-07-08 18:52:57 -070013663 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013664
Jeff Brown10e89712011-07-08 18:52:57 -070013665 if (wasKeeping && !app.keeping) {
13666 // This app is no longer something we want to keep. Note
13667 // its current wake lock time to later know to kill it if
13668 // it is not behaving well.
13669 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13670 synchronized (stats) {
13671 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13672 app.pid, SystemClock.elapsedRealtime());
13673 }
13674 app.lastCpuTime = app.curCpuTime;
13675 }
13676
13677 app.setRawAdj = app.curRawAdj;
13678 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013679 if (app.curAdj != app.setAdj) {
13680 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013681 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13682 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013683 " oom adj to " + app.curAdj + " because " + app.adjType);
13684 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013685 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013686 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013687 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013688 }
13689 }
13690 if (app.setSchedGroup != app.curSchedGroup) {
13691 app.setSchedGroup = app.curSchedGroup;
13692 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13693 "Setting process group of " + app.processName
13694 + " to " + app.curSchedGroup);
13695 if (app.waitingToKill != null &&
13696 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13697 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13698 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13699 app.processName, app.setAdj, app.waitingToKill);
13700 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013701 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013702 } else {
13703 if (true) {
13704 long oldId = Binder.clearCallingIdentity();
13705 try {
13706 Process.setProcessGroup(app.pid, app.curSchedGroup);
13707 } catch (Exception e) {
13708 Slog.w(TAG, "Failed setting process group of " + app.pid
13709 + " to " + app.curSchedGroup);
13710 e.printStackTrace();
13711 } finally {
13712 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013713 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013714 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013715 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013716 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013717 app.thread.setSchedulingGroup(app.curSchedGroup);
13718 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013719 }
13720 }
13721 }
13722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013723 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013724 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013725 }
13726
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013727 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013728 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013729 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013730 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013731 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013732 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013733 }
13734 }
13735 return resumedActivity;
13736 }
13737
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013738 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013739 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013740 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13741 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013742 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13743 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013744
13745 mAdjSeq++;
13746
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013747 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013748 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13749 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013750 if (nowHidden != wasHidden) {
13751 // Changed to/from hidden state, so apps after it in the LRU
13752 // list may also be changed.
13753 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013754 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013755 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013756 }
13757
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013758 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013759 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013760 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13761
13762 if (false) {
13763 RuntimeException e = new RuntimeException();
13764 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013765 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013766 }
13767
13768 mAdjSeq++;
13769
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013770 // Let's determine how many processes we have running vs.
13771 // how many slots we have for background processes; we may want
13772 // to put multiple processes in a slot of there are enough of
13773 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013774 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013775 int factor = (mLruProcesses.size()-4)/numSlots;
13776 if (factor < 1) factor = 1;
13777 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013778 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013779
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013780 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013781 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013782 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013783 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013784 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013785 while (i > 0) {
13786 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013787 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013788 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013789 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013790 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013791 && app.curAdj == curHiddenAdj) {
13792 step++;
13793 if (step >= factor) {
13794 step = 0;
13795 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013796 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013797 }
13798 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013799 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013800 numHidden++;
13801 if (numHidden > mProcessLimit) {
13802 Slog.i(TAG, "No longer want " + app.processName
13803 + " (pid " + app.pid + "): hidden #" + numHidden);
13804 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13805 app.processName, app.setAdj, "too many background");
13806 app.killedBackground = true;
13807 Process.killProcessQuiet(app.pid);
13808 } else {
13809 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013810 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013811 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013812 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013814 }
13815 }
13816
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013817 // Now determine the memory trimming level of background processes.
13818 // Unfortunately we need to start at the back of the list to do this
13819 // properly. We only do this if the number of background apps we
13820 // are managing to keep around is less than half the maximum we desire;
13821 // if we are keeping a good number around, we'll let them use whatever
13822 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013823 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013824 final int N = mLruProcesses.size();
13825 factor = numBg/3;
13826 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013827 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013828 for (i=0; i<N; i++) {
13829 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013830 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013831 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13832 try {
13833 app.thread.scheduleTrimMemory(curLevel);
13834 } catch (RemoteException e) {
13835 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013836 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013837 // For these apps we will also finish their activities
13838 // to help them free memory.
13839 mMainStack.destroyActivitiesLocked(app, false);
13840 }
13841 }
13842 app.trimMemoryLevel = curLevel;
13843 step++;
13844 if (step >= factor) {
13845 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013846 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13847 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013848 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013849 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13850 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013851 break;
13852 }
13853 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013854 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013855 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013856 && app.thread != null) {
13857 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013858 app.thread.scheduleTrimMemory(
13859 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013860 } catch (RemoteException e) {
13861 }
13862 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013863 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013864 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013865 && app.pendingUiClean) {
13866 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13867 && app.thread != null) {
13868 try {
13869 app.thread.scheduleTrimMemory(
13870 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13871 } catch (RemoteException e) {
13872 }
13873 }
13874 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13875 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013876 } else {
13877 app.trimMemoryLevel = 0;
13878 }
13879 }
13880 } else {
13881 final int N = mLruProcesses.size();
13882 for (i=0; i<N; i++) {
13883 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013884 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013885 && app.pendingUiClean) {
13886 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13887 && app.thread != null) {
13888 try {
13889 app.thread.scheduleTrimMemory(
13890 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13891 } catch (RemoteException e) {
13892 }
13893 }
13894 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13895 app.pendingUiClean = false;
13896 } else {
13897 app.trimMemoryLevel = 0;
13898 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013899 }
13900 }
13901
13902 if (mAlwaysFinishActivities) {
13903 mMainStack.destroyActivitiesLocked(null, false);
13904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013905 }
13906
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013907 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013908 synchronized (this) {
13909 int i;
13910
13911 // First remove any unused application processes whose package
13912 // has been removed.
13913 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13914 final ProcessRecord app = mRemovedProcesses.get(i);
13915 if (app.activities.size() == 0
13916 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013917 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013918 TAG, "Exiting empty application process "
13919 + app.processName + " ("
13920 + (app.thread != null ? app.thread.asBinder() : null)
13921 + ")\n");
13922 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013923 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13924 app.processName, app.setAdj, "empty");
13925 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013926 } else {
13927 try {
13928 app.thread.scheduleExit();
13929 } catch (Exception e) {
13930 // Ignore exceptions.
13931 }
13932 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013933 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013934 mRemovedProcesses.remove(i);
13935
13936 if (app.persistent) {
13937 if (app.persistent) {
13938 addAppLocked(app.info);
13939 }
13940 }
13941 }
13942 }
13943
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013944 // Now update the oom adj for all processes.
13945 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013946 }
13947 }
13948
13949 /** This method sends the specified signal to each of the persistent apps */
13950 public void signalPersistentProcesses(int sig) throws RemoteException {
13951 if (sig != Process.SIGNAL_USR1) {
13952 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13953 }
13954
13955 synchronized (this) {
13956 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13957 != PackageManager.PERMISSION_GRANTED) {
13958 throw new SecurityException("Requires permission "
13959 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13960 }
13961
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013962 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13963 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013964 if (r.thread != null && r.persistent) {
13965 Process.sendSignal(r.pid, sig);
13966 }
13967 }
13968 }
13969 }
13970
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013971 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13972 if (proc == null || proc == mProfileProc) {
13973 proc = mProfileProc;
13974 path = mProfileFile;
13975 profileType = mProfileType;
13976 clearProfilerLocked();
13977 }
13978 if (proc == null) {
13979 return;
13980 }
13981 try {
13982 proc.thread.profilerControl(false, path, null, profileType);
13983 } catch (RemoteException e) {
13984 throw new IllegalStateException("Process disappeared");
13985 }
13986 }
13987
13988 private void clearProfilerLocked() {
13989 if (mProfileFd != null) {
13990 try {
13991 mProfileFd.close();
13992 } catch (IOException e) {
13993 }
13994 }
13995 mProfileApp = null;
13996 mProfileProc = null;
13997 mProfileFile = null;
13998 mProfileType = 0;
13999 mAutoStopProfiler = false;
14000 }
14001
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014002 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014003 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014004
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014005 try {
14006 synchronized (this) {
14007 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14008 // its own permission.
14009 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14010 != PackageManager.PERMISSION_GRANTED) {
14011 throw new SecurityException("Requires permission "
14012 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014013 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014014
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014015 if (start && fd == null) {
14016 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014017 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014018
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014019 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014020 if (process != null) {
14021 try {
14022 int pid = Integer.parseInt(process);
14023 synchronized (mPidsSelfLocked) {
14024 proc = mPidsSelfLocked.get(pid);
14025 }
14026 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014027 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014028
14029 if (proc == null) {
14030 HashMap<String, SparseArray<ProcessRecord>> all
14031 = mProcessNames.getMap();
14032 SparseArray<ProcessRecord> procs = all.get(process);
14033 if (procs != null && procs.size() > 0) {
14034 proc = procs.valueAt(0);
14035 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014036 }
14037 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014038
14039 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014040 throw new IllegalArgumentException("Unknown process: " + process);
14041 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014042
14043 if (start) {
14044 stopProfilerLocked(null, null, 0);
14045 setProfileApp(proc.info, proc.processName, path, fd, false);
14046 mProfileProc = proc;
14047 mProfileType = profileType;
14048 try {
14049 fd = fd.dup();
14050 } catch (IOException e) {
14051 fd = null;
14052 }
14053 proc.thread.profilerControl(start, path, fd, profileType);
14054 fd = null;
14055 mProfileFd = null;
14056 } else {
14057 stopProfilerLocked(proc, path, profileType);
14058 if (fd != null) {
14059 try {
14060 fd.close();
14061 } catch (IOException e) {
14062 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014063 }
14064 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014065
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014066 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014067 }
14068 } catch (RemoteException e) {
14069 throw new IllegalStateException("Process disappeared");
14070 } finally {
14071 if (fd != null) {
14072 try {
14073 fd.close();
14074 } catch (IOException e) {
14075 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014076 }
14077 }
14078 }
Andy McFadden824c5102010-07-09 16:26:57 -070014079
14080 public boolean dumpHeap(String process, boolean managed,
14081 String path, ParcelFileDescriptor fd) throws RemoteException {
14082
14083 try {
14084 synchronized (this) {
14085 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14086 // its own permission (same as profileControl).
14087 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14088 != PackageManager.PERMISSION_GRANTED) {
14089 throw new SecurityException("Requires permission "
14090 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14091 }
14092
14093 if (fd == null) {
14094 throw new IllegalArgumentException("null fd");
14095 }
14096
14097 ProcessRecord proc = null;
14098 try {
14099 int pid = Integer.parseInt(process);
14100 synchronized (mPidsSelfLocked) {
14101 proc = mPidsSelfLocked.get(pid);
14102 }
14103 } catch (NumberFormatException e) {
14104 }
14105
14106 if (proc == null) {
14107 HashMap<String, SparseArray<ProcessRecord>> all
14108 = mProcessNames.getMap();
14109 SparseArray<ProcessRecord> procs = all.get(process);
14110 if (procs != null && procs.size() > 0) {
14111 proc = procs.valueAt(0);
14112 }
14113 }
14114
14115 if (proc == null || proc.thread == null) {
14116 throw new IllegalArgumentException("Unknown process: " + process);
14117 }
14118
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014119 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14120 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014121 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14122 throw new SecurityException("Process not debuggable: " + proc);
14123 }
14124 }
14125
14126 proc.thread.dumpHeap(managed, path, fd);
14127 fd = null;
14128 return true;
14129 }
14130 } catch (RemoteException e) {
14131 throw new IllegalStateException("Process disappeared");
14132 } finally {
14133 if (fd != null) {
14134 try {
14135 fd.close();
14136 } catch (IOException e) {
14137 }
14138 }
14139 }
14140 }
14141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014142 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14143 public void monitor() {
14144 synchronized (this) { }
14145 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014146
14147 public void onCoreSettingsChange(Bundle settings) {
14148 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14149 ProcessRecord processRecord = mLruProcesses.get(i);
14150 try {
14151 if (processRecord.thread != null) {
14152 processRecord.thread.setCoreSettings(settings);
14153 }
14154 } catch (RemoteException re) {
14155 /* ignore */
14156 }
14157 }
14158 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014159
14160 // Multi-user methods
14161
14162 public boolean switchUser(int userid) {
14163 // TODO
14164 return true;
14165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014166}