blob: 04bbc1192199a3952824baf57004a152d5f4615a [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 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700724 * Keep track of the number of service processes we last found, to
725 * determine on the next iteration which should be B services.
726 */
727 int mNumServiceProcs = 0;
728 int mNewNumServiceProcs = 0;
729
730 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 * System monitoring: number of processes that died since the last
732 * N procs were started.
733 */
734 int[] mProcDeaths = new int[20];
735
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700736 /**
737 * This is set if we had to do a delayed dexopt of an app before launching
738 * it, to increasing the ANR timeouts in that case.
739 */
740 boolean mDidDexOpt;
741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 String mDebugApp = null;
743 boolean mWaitForDebugger = false;
744 boolean mDebugTransient = false;
745 String mOrigDebugApp = null;
746 boolean mOrigWaitForDebugger = false;
747 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700748 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700749 String mProfileApp = null;
750 ProcessRecord mProfileProc = null;
751 String mProfileFile;
752 ParcelFileDescriptor mProfileFd;
753 int mProfileType = 0;
754 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700756 final RemoteCallbackList<IActivityWatcher> mWatchers
757 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700758
759 final RemoteCallbackList<IProcessObserver> mProcessObservers
760 = new RemoteCallbackList<IProcessObserver>();
761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 /**
763 * Callback of last caller to {@link #requestPss}.
764 */
765 Runnable mRequestPssCallback;
766
767 /**
768 * Remaining processes for which we are waiting results from the last
769 * call to {@link #requestPss}.
770 */
771 final ArrayList<ProcessRecord> mRequestPssList
772 = new ArrayList<ProcessRecord>();
773
774 /**
775 * Runtime statistics collection thread. This object's lock is used to
776 * protect all related state.
777 */
778 final Thread mProcessStatsThread;
779
780 /**
781 * Used to collect process stats when showing not responding dialog.
782 * Protected by mProcessStatsThread.
783 */
784 final ProcessStats mProcessStats = new ProcessStats(
785 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700786 final AtomicLong mLastCpuTime = new AtomicLong(0);
787 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 long mLastWriteTime = 0;
790
791 /**
792 * Set to true after the system has finished booting.
793 */
794 boolean mBooted = false;
795
Dianne Hackborn7d608422011-08-07 16:24:18 -0700796 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700797 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798
799 WindowManagerService mWindowManager;
800
801 static ActivityManagerService mSelf;
802 static ActivityThread mSystemThread;
803
804 private final class AppDeathRecipient implements IBinder.DeathRecipient {
805 final ProcessRecord mApp;
806 final int mPid;
807 final IApplicationThread mAppThread;
808
809 AppDeathRecipient(ProcessRecord app, int pid,
810 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800811 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 TAG, "New death recipient " + this
813 + " for thread " + thread.asBinder());
814 mApp = app;
815 mPid = pid;
816 mAppThread = thread;
817 }
818
819 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 TAG, "Death received in " + this
822 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 synchronized(ActivityManagerService.this) {
824 appDiedLocked(mApp, mPid, mAppThread);
825 }
826 }
827 }
828
829 static final int SHOW_ERROR_MSG = 1;
830 static final int SHOW_NOT_RESPONDING_MSG = 2;
831 static final int SHOW_FACTORY_ERROR_MSG = 3;
832 static final int UPDATE_CONFIGURATION_MSG = 4;
833 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
834 static final int WAIT_FOR_DEBUGGER_MSG = 6;
835 static final int BROADCAST_INTENT_MSG = 7;
836 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 static final int SERVICE_TIMEOUT_MSG = 12;
838 static final int UPDATE_TIME_ZONE = 13;
839 static final int SHOW_UID_ERROR_MSG = 14;
840 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700842 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700843 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800844 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700845 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
846 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700847 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700848 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700849 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700850 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700851 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700852 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
853 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854
855 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700856 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857
858 final Handler mHandler = new Handler() {
859 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800860 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 //}
862
863 public void handleMessage(Message msg) {
864 switch (msg.what) {
865 case SHOW_ERROR_MSG: {
866 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 synchronized (ActivityManagerService.this) {
868 ProcessRecord proc = (ProcessRecord)data.get("app");
869 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800870 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 return;
872 }
873 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700874 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800875 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 d.show();
877 proc.crashDialog = d;
878 } else {
879 // The device is asleep, so just pretend that the user
880 // saw a crash dialog and hit "force quit".
881 res.set(0);
882 }
883 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700884
885 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 } break;
887 case SHOW_NOT_RESPONDING_MSG: {
888 synchronized (ActivityManagerService.this) {
889 HashMap data = (HashMap) msg.obj;
890 ProcessRecord proc = (ProcessRecord)data.get("app");
891 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800892 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 return;
894 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800895
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700896 Intent intent = new Intent("android.intent.action.ANR");
897 if (!mProcessesReady) {
898 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
899 }
900 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800901 null, null, 0, null, null, null,
902 false, false, MY_PID, Process.SYSTEM_UID);
903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700905 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 d.show();
907 proc.anrDialog = d;
908 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700909
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700910 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700912 case SHOW_STRICT_MODE_VIOLATION_MSG: {
913 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
914 synchronized (ActivityManagerService.this) {
915 ProcessRecord proc = (ProcessRecord) data.get("app");
916 if (proc == null) {
917 Slog.e(TAG, "App not found when showing strict mode dialog.");
918 break;
919 }
920 if (proc.crashDialog != null) {
921 Slog.e(TAG, "App already has strict mode dialog: " + proc);
922 return;
923 }
924 AppErrorResult res = (AppErrorResult) data.get("result");
925 if (!mSleeping && !mShuttingDown) {
926 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
927 d.show();
928 proc.crashDialog = d;
929 } else {
930 // The device is asleep, so just pretend that the user
931 // saw a crash dialog and hit "force quit".
932 res.set(0);
933 }
934 }
935 ensureBootCompleted();
936 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 case SHOW_FACTORY_ERROR_MSG: {
938 Dialog d = new FactoryErrorDialog(
939 mContext, msg.getData().getCharSequence("msg"));
940 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700941 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 } break;
943 case UPDATE_CONFIGURATION_MSG: {
944 final ContentResolver resolver = mContext.getContentResolver();
945 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
946 } break;
947 case GC_BACKGROUND_PROCESSES_MSG: {
948 synchronized (ActivityManagerService.this) {
949 performAppGcsIfAppropriateLocked();
950 }
951 } break;
952 case WAIT_FOR_DEBUGGER_MSG: {
953 synchronized (ActivityManagerService.this) {
954 ProcessRecord app = (ProcessRecord)msg.obj;
955 if (msg.arg1 != 0) {
956 if (!app.waitedForDebugger) {
957 Dialog d = new AppWaitingForDebuggerDialog(
958 ActivityManagerService.this,
959 mContext, app);
960 app.waitDialog = d;
961 app.waitedForDebugger = true;
962 d.show();
963 }
964 } else {
965 if (app.waitDialog != null) {
966 app.waitDialog.dismiss();
967 app.waitDialog = null;
968 }
969 }
970 }
971 } break;
972 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800973 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 TAG, "Received BROADCAST_INTENT_MSG");
975 processNextBroadcast(true);
976 } break;
977 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700978 synchronized (ActivityManagerService.this) {
979 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500980 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700983 if (mDidDexOpt) {
984 mDidDexOpt = false;
985 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
986 nmsg.obj = msg.obj;
987 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
988 return;
989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 serviceTimeout((ProcessRecord)msg.obj);
991 } break;
992 case UPDATE_TIME_ZONE: {
993 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800994 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
995 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 if (r.thread != null) {
997 try {
998 r.thread.updateTimeZone();
999 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001000 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 }
1002 }
1003 }
1004 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001005 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001006 case CLEAR_DNS_CACHE: {
1007 synchronized (ActivityManagerService.this) {
1008 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1009 ProcessRecord r = mLruProcesses.get(i);
1010 if (r.thread != null) {
1011 try {
1012 r.thread.clearDnsCache();
1013 } catch (RemoteException ex) {
1014 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1015 }
1016 }
1017 }
1018 }
1019 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001020 case UPDATE_HTTP_PROXY: {
1021 ProxyProperties proxy = (ProxyProperties)msg.obj;
1022 String host = "";
1023 String port = "";
1024 String exclList = "";
1025 if (proxy != null) {
1026 host = proxy.getHost();
1027 port = Integer.toString(proxy.getPort());
1028 exclList = proxy.getExclusionList();
1029 }
1030 synchronized (ActivityManagerService.this) {
1031 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1032 ProcessRecord r = mLruProcesses.get(i);
1033 if (r.thread != null) {
1034 try {
1035 r.thread.setHttpProxy(host, port, exclList);
1036 } catch (RemoteException ex) {
1037 Slog.w(TAG, "Failed to update http proxy for: " +
1038 r.info.processName);
1039 }
1040 }
1041 }
1042 }
1043 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 case SHOW_UID_ERROR_MSG: {
1045 // XXX This is a temporary dialog, no need to localize.
1046 AlertDialog d = new BaseErrorDialog(mContext);
1047 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1048 d.setCancelable(false);
1049 d.setTitle("System UIDs Inconsistent");
1050 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 +02001051 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1053 mUidAlert = d;
1054 d.show();
1055 } break;
1056 case IM_FEELING_LUCKY_MSG: {
1057 if (mUidAlert != null) {
1058 mUidAlert.dismiss();
1059 mUidAlert = null;
1060 }
1061 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001063 if (mDidDexOpt) {
1064 mDidDexOpt = false;
1065 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1066 nmsg.obj = msg.obj;
1067 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1068 return;
1069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 ProcessRecord app = (ProcessRecord)msg.obj;
1071 synchronized (ActivityManagerService.this) {
1072 processStartTimedOutLocked(app);
1073 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001074 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001075 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1076 synchronized (ActivityManagerService.this) {
1077 doPendingActivityLaunchesLocked(true);
1078 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001079 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001080 case KILL_APPLICATION_MSG: {
1081 synchronized (ActivityManagerService.this) {
1082 int uid = msg.arg1;
1083 boolean restart = (msg.arg2 == 1);
1084 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001085 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001086 }
1087 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001088 case FINALIZE_PENDING_INTENT_MSG: {
1089 ((PendingIntentRecord)msg.obj).completeFinalize();
1090 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001091 case POST_HEAVY_NOTIFICATION_MSG: {
1092 INotificationManager inm = NotificationManager.getService();
1093 if (inm == null) {
1094 return;
1095 }
1096
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001097 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001098 ProcessRecord process = root.app;
1099 if (process == null) {
1100 return;
1101 }
1102
1103 try {
1104 Context context = mContext.createPackageContext(process.info.packageName, 0);
1105 String text = mContext.getString(R.string.heavy_weight_notification,
1106 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1107 Notification notification = new Notification();
1108 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1109 notification.when = 0;
1110 notification.flags = Notification.FLAG_ONGOING_EVENT;
1111 notification.tickerText = text;
1112 notification.defaults = 0; // please be quiet
1113 notification.sound = null;
1114 notification.vibrate = null;
1115 notification.setLatestEventInfo(context, text,
1116 mContext.getText(R.string.heavy_weight_notification_detail),
1117 PendingIntent.getActivity(mContext, 0, root.intent,
1118 PendingIntent.FLAG_CANCEL_CURRENT));
1119
1120 try {
1121 int[] outId = new int[1];
1122 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1123 notification, outId);
1124 } catch (RuntimeException e) {
1125 Slog.w(ActivityManagerService.TAG,
1126 "Error showing notification for heavy-weight app", e);
1127 } catch (RemoteException e) {
1128 }
1129 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001130 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001131 }
1132 } break;
1133 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1134 INotificationManager inm = NotificationManager.getService();
1135 if (inm == null) {
1136 return;
1137 }
1138 try {
1139 inm.cancelNotification("android",
1140 R.string.heavy_weight_notification);
1141 } catch (RuntimeException e) {
1142 Slog.w(ActivityManagerService.TAG,
1143 "Error canceling notification for service", e);
1144 } catch (RemoteException e) {
1145 }
1146 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001147 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1148 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001149 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001150 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001151 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1152 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001153 }
1154 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001155 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1156 synchronized (ActivityManagerService.this) {
1157 ActivityRecord ar = (ActivityRecord)msg.obj;
1158 if (mCompatModeDialog != null) {
1159 if (mCompatModeDialog.mAppInfo.packageName.equals(
1160 ar.info.applicationInfo.packageName)) {
1161 return;
1162 }
1163 mCompatModeDialog.dismiss();
1164 mCompatModeDialog = null;
1165 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001166 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001167 if (mCompatModePackages.getPackageAskCompatModeLocked(
1168 ar.packageName)) {
1169 int mode = mCompatModePackages.computeCompatModeLocked(
1170 ar.info.applicationInfo);
1171 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1172 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1173 mCompatModeDialog = new CompatModeDialog(
1174 ActivityManagerService.this, mContext,
1175 ar.info.applicationInfo);
1176 mCompatModeDialog.show();
1177 }
1178 }
1179 }
1180 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001181 break;
1182 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001183 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001184 final int pid = msg.arg1;
1185 final int uid = msg.arg2;
1186 final boolean foregroundActivities = (Boolean) msg.obj;
1187 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001188 break;
1189 }
1190 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001191 final int pid = msg.arg1;
1192 final int uid = msg.arg2;
1193 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001194 break;
1195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 }
1197 }
1198 };
1199
1200 public static void setSystemProcess() {
1201 try {
1202 ActivityManagerService m = mSelf;
1203
1204 ServiceManager.addService("activity", m);
1205 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001206 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 if (MONITOR_CPU_USAGE) {
1208 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1209 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 ServiceManager.addService("permission", new PermissionController(m));
1211
1212 ApplicationInfo info =
1213 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001214 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001215 mSystemThread.installSystemApplicationInfo(info);
1216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 synchronized (mSelf) {
1218 ProcessRecord app = mSelf.newProcessRecordLocked(
1219 mSystemThread.getApplicationThread(), info,
1220 info.processName);
1221 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001222 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001223 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1225 synchronized (mSelf.mPidsSelfLocked) {
1226 mSelf.mPidsSelfLocked.put(app.pid, app);
1227 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001228 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 }
1230 } catch (PackageManager.NameNotFoundException e) {
1231 throw new RuntimeException(
1232 "Unable to find android system package", e);
1233 }
1234 }
1235
1236 public void setWindowManager(WindowManagerService wm) {
1237 mWindowManager = wm;
1238 }
1239
1240 public static final Context main(int factoryTest) {
1241 AThread thr = new AThread();
1242 thr.start();
1243
1244 synchronized (thr) {
1245 while (thr.mService == null) {
1246 try {
1247 thr.wait();
1248 } catch (InterruptedException e) {
1249 }
1250 }
1251 }
1252
1253 ActivityManagerService m = thr.mService;
1254 mSelf = m;
1255 ActivityThread at = ActivityThread.systemMain();
1256 mSystemThread = at;
1257 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001258 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 m.mContext = context;
1260 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001261 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262
1263 m.mBatteryStatsService.publish(context);
1264 m.mUsageStatsService.publish(context);
1265
1266 synchronized (thr) {
1267 thr.mReady = true;
1268 thr.notifyAll();
1269 }
1270
1271 m.startRunning(null, null, null, null);
1272
1273 return context;
1274 }
1275
1276 public static ActivityManagerService self() {
1277 return mSelf;
1278 }
1279
1280 static class AThread extends Thread {
1281 ActivityManagerService mService;
1282 boolean mReady = false;
1283
1284 public AThread() {
1285 super("ActivityManager");
1286 }
1287
1288 public void run() {
1289 Looper.prepare();
1290
1291 android.os.Process.setThreadPriority(
1292 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001293 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294
1295 ActivityManagerService m = new ActivityManagerService();
1296
1297 synchronized (this) {
1298 mService = m;
1299 notifyAll();
1300 }
1301
1302 synchronized (this) {
1303 while (!mReady) {
1304 try {
1305 wait();
1306 } catch (InterruptedException e) {
1307 }
1308 }
1309 }
1310
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001311 // For debug builds, log event loop stalls to dropbox for analysis.
1312 if (StrictMode.conditionallyEnableDebugLogging()) {
1313 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1314 }
1315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 Looper.loop();
1317 }
1318 }
1319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 static class MemBinder extends Binder {
1321 ActivityManagerService mActivityManagerService;
1322 MemBinder(ActivityManagerService activityManagerService) {
1323 mActivityManagerService = activityManagerService;
1324 }
1325
1326 @Override
1327 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001328 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1329 != PackageManager.PERMISSION_GRANTED) {
1330 pw.println("Permission Denial: can't dump meminfo from from pid="
1331 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1332 + " without permission " + android.Manifest.permission.DUMP);
1333 return;
1334 }
1335
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001336 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 }
1338 }
1339
Chet Haase9c1e23b2011-03-24 10:51:31 -07001340 static class GraphicsBinder extends Binder {
1341 ActivityManagerService mActivityManagerService;
1342 GraphicsBinder(ActivityManagerService activityManagerService) {
1343 mActivityManagerService = activityManagerService;
1344 }
1345
1346 @Override
1347 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001348 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1349 != PackageManager.PERMISSION_GRANTED) {
1350 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1351 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1352 + " without permission " + android.Manifest.permission.DUMP);
1353 return;
1354 }
1355
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001356 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001357 }
1358 }
1359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 static class CpuBinder extends Binder {
1361 ActivityManagerService mActivityManagerService;
1362 CpuBinder(ActivityManagerService activityManagerService) {
1363 mActivityManagerService = activityManagerService;
1364 }
1365
1366 @Override
1367 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001368 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1369 != PackageManager.PERMISSION_GRANTED) {
1370 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1371 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1372 + " without permission " + android.Manifest.permission.DUMP);
1373 return;
1374 }
1375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001377 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1378 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1379 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 }
1381 }
1382 }
1383
1384 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001385 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 File dataDir = Environment.getDataDirectory();
1388 File systemDir = new File(dataDir, "system");
1389 systemDir.mkdirs();
1390 mBatteryStatsService = new BatteryStatsService(new File(
1391 systemDir, "batterystats.bin").toString());
1392 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001393 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001394 mOnBattery = DEBUG_POWER ? true
1395 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001396 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001398 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001399 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400
Jack Palevichb90d28c2009-07-22 15:35:24 -07001401 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1402 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1403
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001404 mConfiguration.setToDefaults();
1405 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 mProcessStats.init();
1407
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001408 mCompatModePackages = new CompatModePackages(this, systemDir);
1409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 // Add ourself to the Watchdog monitors.
1411 Watchdog.getInstance().addMonitor(this);
1412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 mProcessStatsThread = new Thread("ProcessStats") {
1414 public void run() {
1415 while (true) {
1416 try {
1417 try {
1418 synchronized(this) {
1419 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001420 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 // + ", write delay=" + nextWriteDelay);
1424 if (nextWriteDelay < nextCpuDelay) {
1425 nextCpuDelay = nextWriteDelay;
1426 }
1427 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001428 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 this.wait(nextCpuDelay);
1430 }
1431 }
1432 } catch (InterruptedException e) {
1433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 updateCpuStatsNow();
1435 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001436 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 }
1438 }
1439 }
1440 };
1441 mProcessStatsThread.start();
1442 }
1443
1444 @Override
1445 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1446 throws RemoteException {
1447 try {
1448 return super.onTransact(code, data, reply, flags);
1449 } catch (RuntimeException e) {
1450 // The activity manager only throws security exceptions, so let's
1451 // log all others.
1452 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001453 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 }
1455 throw e;
1456 }
1457 }
1458
1459 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001460 final long now = SystemClock.uptimeMillis();
1461 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1462 return;
1463 }
1464 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1465 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 mProcessStatsThread.notify();
1467 }
1468 }
1469 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 void updateCpuStatsNow() {
1472 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001473 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 final long now = SystemClock.uptimeMillis();
1475 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001478 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1479 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 haveNewCpuStats = true;
1481 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001482 //Slog.i(TAG, mProcessStats.printCurrentState());
1483 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 // + mProcessStats.getTotalCpuPercent() + "%");
1485
Joe Onorato8a9b2202010-02-26 18:56:32 -08001486 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 if ("true".equals(SystemProperties.get("events.cpu"))) {
1488 int user = mProcessStats.getLastUserTime();
1489 int system = mProcessStats.getLastSystemTime();
1490 int iowait = mProcessStats.getLastIoWaitTime();
1491 int irq = mProcessStats.getLastIrqTime();
1492 int softIrq = mProcessStats.getLastSoftIrqTime();
1493 int idle = mProcessStats.getLastIdleTime();
1494
1495 int total = user + system + iowait + irq + softIrq + idle;
1496 if (total == 0) total = 1;
1497
Doug Zongker2bec3d42009-12-04 12:52:44 -08001498 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 ((user+system+iowait+irq+softIrq) * 100) / total,
1500 (user * 100) / total,
1501 (system * 100) / total,
1502 (iowait * 100) / total,
1503 (irq * 100) / total,
1504 (softIrq * 100) / total);
1505 }
1506 }
1507
Amith Yamasanie43530a2009-08-21 13:11:37 -07001508 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001509 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001510 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 synchronized(mPidsSelfLocked) {
1512 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001513 if (mOnBattery) {
1514 int perc = bstats.startAddingCpuLocked();
1515 int totalUTime = 0;
1516 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001517 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001519 ProcessStats.Stats st = mProcessStats.getStats(i);
1520 if (!st.working) {
1521 continue;
1522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001524 int otherUTime = (st.rel_utime*perc)/100;
1525 int otherSTime = (st.rel_stime*perc)/100;
1526 totalUTime += otherUTime;
1527 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 if (pr != null) {
1529 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001530 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1531 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001532 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001533 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001534 } else {
1535 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001536 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001537 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001538 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1539 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001540 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 }
1543 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001544 bstats.finishAddingCpuLocked(perc, totalUTime,
1545 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547 }
1548 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1551 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001552 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 }
1554 }
1555 }
1556 }
1557
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001558 @Override
1559 public void batteryNeedsCpuUpdate() {
1560 updateCpuStatsNow();
1561 }
1562
1563 @Override
1564 public void batteryPowerChanged(boolean onBattery) {
1565 // When plugging in, update the CPU stats first before changing
1566 // the plug state.
1567 updateCpuStatsNow();
1568 synchronized (this) {
1569 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001570 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001571 }
1572 }
1573 }
1574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 /**
1576 * Initialize the application bind args. These are passed to each
1577 * process when the bindApplication() IPC is sent to the process. They're
1578 * lazily setup to make sure the services are running when they're asked for.
1579 */
1580 private HashMap<String, IBinder> getCommonServicesLocked() {
1581 if (mAppBindArgs == null) {
1582 mAppBindArgs = new HashMap<String, IBinder>();
1583
1584 // Setup the application init args
1585 mAppBindArgs.put("package", ServiceManager.getService("package"));
1586 mAppBindArgs.put("window", ServiceManager.getService("window"));
1587 mAppBindArgs.put(Context.ALARM_SERVICE,
1588 ServiceManager.getService(Context.ALARM_SERVICE));
1589 }
1590 return mAppBindArgs;
1591 }
1592
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001593 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 if (mFocusedActivity != r) {
1595 mFocusedActivity = r;
1596 mWindowManager.setFocusedApp(r, true);
1597 }
1598 }
1599
Dianne Hackborn906497c2010-05-10 15:57:38 -07001600 private final void updateLruProcessInternalLocked(ProcessRecord app,
1601 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001603 int lrui = mLruProcesses.indexOf(app);
1604 if (lrui >= 0) mLruProcesses.remove(lrui);
1605
1606 int i = mLruProcesses.size()-1;
1607 int skipTop = 0;
1608
Dianne Hackborn906497c2010-05-10 15:57:38 -07001609 app.lruSeq = mLruSeq;
1610
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001611 // compute the new weight for this process.
1612 if (updateActivityTime) {
1613 app.lastActivityTime = SystemClock.uptimeMillis();
1614 }
1615 if (app.activities.size() > 0) {
1616 // If this process has activities, we more strongly want to keep
1617 // it around.
1618 app.lruWeight = app.lastActivityTime;
1619 } else if (app.pubProviders.size() > 0) {
1620 // If this process contains content providers, we want to keep
1621 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001622 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_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 } else {
1626 // If this process doesn't have activities, we less strongly
1627 // want to keep it around, and generally want to avoid getting
1628 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001629 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001630 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001631 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001632 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001633
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001634 while (i >= 0) {
1635 ProcessRecord p = mLruProcesses.get(i);
1636 // If this app shouldn't be in front of the first N background
1637 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001638 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001639 skipTop--;
1640 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001641 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001642 mLruProcesses.add(i+1, app);
1643 break;
1644 }
1645 i--;
1646 }
1647 if (i < 0) {
1648 mLruProcesses.add(0, app);
1649 }
1650
Dianne Hackborn906497c2010-05-10 15:57:38 -07001651 // If the app is currently using a content provider or service,
1652 // bump those processes as well.
1653 if (app.connections.size() > 0) {
1654 for (ConnectionRecord cr : app.connections) {
1655 if (cr.binding != null && cr.binding.service != null
1656 && cr.binding.service.app != null
1657 && cr.binding.service.app.lruSeq != mLruSeq) {
1658 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1659 updateActivityTime, i+1);
1660 }
1661 }
1662 }
1663 if (app.conProviders.size() > 0) {
1664 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001665 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1666 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001667 updateActivityTime, i+1);
1668 }
1669 }
1670 }
1671
Joe Onorato8a9b2202010-02-26 18:56:32 -08001672 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 if (oomAdj) {
1674 updateOomAdjLocked();
1675 }
1676 }
1677
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001678 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001679 boolean oomAdj, boolean updateActivityTime) {
1680 mLruSeq++;
1681 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1682 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 String processName, int uid) {
1686 if (uid == Process.SYSTEM_UID) {
1687 // The system gets to run in any process. If there are multiple
1688 // processes with the same uid, just pick the first (this
1689 // should never happen).
1690 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1691 processName);
1692 return procs != null ? procs.valueAt(0) : null;
1693 }
1694 ProcessRecord proc = mProcessNames.get(processName, uid);
1695 return proc;
1696 }
1697
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001698 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001699 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001700 try {
1701 if (pm.performDexOpt(packageName)) {
1702 mDidDexOpt = true;
1703 }
1704 } catch (RemoteException e) {
1705 }
1706 }
1707
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001708 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 int transit = mWindowManager.getPendingAppTransition();
1710 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1711 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1712 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1713 }
1714
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001715 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001717 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001718 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1719 // We don't have to do anything more if:
1720 // (1) There is an existing application record; and
1721 // (2) The caller doesn't think it is dead, OR there is no thread
1722 // object attached to it so we know it couldn't have crashed; and
1723 // (3) There is a pid assigned to it, so it is either starting or
1724 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001725 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 + " app=" + app + " knownToBeDead=" + knownToBeDead
1727 + " thread=" + (app != null ? app.thread : null)
1728 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001729 if (app != null && app.pid > 0) {
1730 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001731 // We already have the app running, or are waiting for it to
1732 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001733 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001734 // If this is a new package in the process, add the package to the list
1735 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001736 return app;
1737 } else {
1738 // An application record is attached to a previous process,
1739 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001740 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001741 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001745 String hostingNameStr = hostingName != null
1746 ? hostingName.flattenToShortString() : null;
1747
1748 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1749 // If we are in the background, then check to see if this process
1750 // is bad. If so, we will just silently fail.
1751 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001752 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1753 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 return null;
1755 }
1756 } else {
1757 // When the user is explicitly starting a process, then clear its
1758 // crash count so that we won't make it bad until they see at
1759 // least one crash dialog again, and make the process good again
1760 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001761 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1762 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763 mProcessCrashTimes.remove(info.processName, info.uid);
1764 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001765 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 info.processName);
1767 mBadProcesses.remove(info.processName, info.uid);
1768 if (app != null) {
1769 app.bad = false;
1770 }
1771 }
1772 }
1773
1774 if (app == null) {
1775 app = newProcessRecordLocked(null, info, processName);
1776 mProcessNames.put(processName, info.uid, app);
1777 } else {
1778 // If this is a new package in the process, add the package to the list
1779 app.addPackage(info.packageName);
1780 }
1781
1782 // If the system is not ready yet, then hold off on starting this
1783 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001784 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001785 && !isAllowedWhileBooting(info)
1786 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 if (!mProcessesOnHold.contains(app)) {
1788 mProcessesOnHold.add(app);
1789 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001790 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 return app;
1792 }
1793
1794 startProcessLocked(app, hostingType, hostingNameStr);
1795 return (app.pid != 0) ? app : null;
1796 }
1797
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001798 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1799 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1800 }
1801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 private final void startProcessLocked(ProcessRecord app,
1803 String hostingType, String hostingNameStr) {
1804 if (app.pid > 0 && app.pid != MY_PID) {
1805 synchronized (mPidsSelfLocked) {
1806 mPidsSelfLocked.remove(app.pid);
1807 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1808 }
1809 app.pid = 0;
1810 }
1811
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001812 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1813 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 mProcessesOnHold.remove(app);
1815
1816 updateCpuStats();
1817
1818 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1819 mProcDeaths[0] = 0;
1820
1821 try {
1822 int uid = app.info.uid;
1823 int[] gids = null;
1824 try {
1825 gids = mContext.getPackageManager().getPackageGids(
1826 app.info.packageName);
1827 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 }
1830 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1831 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1832 && mTopComponent != null
1833 && app.processName.equals(mTopComponent.getPackageName())) {
1834 uid = 0;
1835 }
1836 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1837 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1838 uid = 0;
1839 }
1840 }
1841 int debugFlags = 0;
1842 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1843 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001844 // Also turn on CheckJNI for debuggable apps. It's quite
1845 // awkward to turn on otherwise.
1846 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001848 // Run the app in safe mode if its manifest requests so or the
1849 // system is booted in safe mode.
1850 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1851 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001852 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001854 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1855 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1856 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001857 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1858 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 if ("1".equals(SystemProperties.get("debug.assert"))) {
1861 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1862 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001863
1864 // Start the process. It will either succeed and return a result containing
1865 // the PID of the new process, or else throw a RuntimeException.
1866 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001867 app.processName, uid, uid, gids, debugFlags,
1868 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001870 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1871 synchronized (bs) {
1872 if (bs.isOnBattery()) {
1873 app.batteryStats.incStartsLocked();
1874 }
1875 }
1876
Jeff Brown3f9dd282011-07-08 20:02:19 -07001877 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 app.processName, hostingType,
1879 hostingNameStr != null ? hostingNameStr : "");
1880
1881 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001882 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 }
1884
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001885 StringBuilder buf = mStringBuilder;
1886 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 buf.append("Start proc ");
1888 buf.append(app.processName);
1889 buf.append(" for ");
1890 buf.append(hostingType);
1891 if (hostingNameStr != null) {
1892 buf.append(" ");
1893 buf.append(hostingNameStr);
1894 }
1895 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001896 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001897 buf.append(" uid=");
1898 buf.append(uid);
1899 buf.append(" gids={");
1900 if (gids != null) {
1901 for (int gi=0; gi<gids.length; gi++) {
1902 if (gi != 0) buf.append(", ");
1903 buf.append(gids[gi]);
1904
1905 }
1906 }
1907 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001908 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001909 app.pid = startResult.pid;
1910 app.usingWrapper = startResult.usingWrapper;
1911 app.removed = false;
1912 synchronized (mPidsSelfLocked) {
1913 this.mPidsSelfLocked.put(startResult.pid, app);
1914 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1915 msg.obj = app;
1916 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1917 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 }
1919 } catch (RuntimeException e) {
1920 // XXX do better error recovery.
1921 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001922 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 }
1924 }
1925
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001926 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001927 if (resumed) {
1928 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1929 } else {
1930 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1931 }
1932 }
1933
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001934 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001935 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1936 && mTopAction == null) {
1937 // We are running in factory test mode, but unable to find
1938 // the factory test app, so just sit around displaying the
1939 // error message and don't try to start anything.
1940 return false;
1941 }
1942 Intent intent = new Intent(
1943 mTopAction,
1944 mTopData != null ? Uri.parse(mTopData) : null);
1945 intent.setComponent(mTopComponent);
1946 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1947 intent.addCategory(Intent.CATEGORY_HOME);
1948 }
1949 ActivityInfo aInfo =
1950 intent.resolveActivityInfo(mContext.getPackageManager(),
1951 STOCK_PM_FLAGS);
1952 if (aInfo != null) {
1953 intent.setComponent(new ComponentName(
1954 aInfo.applicationInfo.packageName, aInfo.name));
1955 // Don't do this if the home app is currently being
1956 // instrumented.
1957 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1958 aInfo.applicationInfo.uid);
1959 if (app == null || app.instrumentationClass == null) {
1960 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001961 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001962 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001963 }
1964 }
1965
1966
1967 return true;
1968 }
1969
1970 /**
1971 * Starts the "new version setup screen" if appropriate.
1972 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001973 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001974 // Only do this once per boot.
1975 if (mCheckedForSetup) {
1976 return;
1977 }
1978
1979 // We will show this screen if the current one is a different
1980 // version than the last one shown, and we are not running in
1981 // low-level factory test mode.
1982 final ContentResolver resolver = mContext.getContentResolver();
1983 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1984 Settings.Secure.getInt(resolver,
1985 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1986 mCheckedForSetup = true;
1987
1988 // See if we should be showing the platform update setup UI.
1989 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1990 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1991 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1992
1993 // We don't allow third party apps to replace this.
1994 ResolveInfo ri = null;
1995 for (int i=0; ris != null && i<ris.size(); i++) {
1996 if ((ris.get(i).activityInfo.applicationInfo.flags
1997 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1998 ri = ris.get(i);
1999 break;
2000 }
2001 }
2002
2003 if (ri != null) {
2004 String vers = ri.activityInfo.metaData != null
2005 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2006 : null;
2007 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2008 vers = ri.activityInfo.applicationInfo.metaData.getString(
2009 Intent.METADATA_SETUP_VERSION);
2010 }
2011 String lastVers = Settings.Secure.getString(
2012 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2013 if (vers != null && !vers.equals(lastVers)) {
2014 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2015 intent.setComponent(new ComponentName(
2016 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002017 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002018 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002019 }
2020 }
2021 }
2022 }
2023
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002024 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002025 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002026 }
2027
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002028 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002029 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002030 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2031 }
2032 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002033
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002034 public void setFrontActivityScreenCompatMode(int mode) {
2035 synchronized (this) {
2036 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2037 }
2038 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002039
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002040 public int getPackageScreenCompatMode(String packageName) {
2041 synchronized (this) {
2042 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2043 }
2044 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002045
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002046 public void setPackageScreenCompatMode(String packageName, int mode) {
2047 synchronized (this) {
2048 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002049 }
2050 }
2051
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002052 public boolean getPackageAskScreenCompat(String packageName) {
2053 synchronized (this) {
2054 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2055 }
2056 }
2057
2058 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2059 synchronized (this) {
2060 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2061 }
2062 }
2063
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002064 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002065 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002066
2067 final int identHash = System.identityHashCode(r);
2068 updateUsageStats(r, true);
2069
2070 int i = mWatchers.beginBroadcast();
2071 while (i > 0) {
2072 i--;
2073 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2074 if (w != null) {
2075 try {
2076 w.activityResuming(identHash);
2077 } catch (RemoteException e) {
2078 }
2079 }
2080 }
2081 mWatchers.finishBroadcast();
2082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083
Jeff Sharkeya4620792011-05-20 15:29:23 -07002084 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2085 int i = mProcessObservers.beginBroadcast();
2086 while (i > 0) {
2087 i--;
2088 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2089 if (observer != null) {
2090 try {
2091 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2092 } catch (RemoteException e) {
2093 }
2094 }
2095 }
2096 mProcessObservers.finishBroadcast();
2097 }
2098
2099 private void dispatchProcessDied(int pid, int uid) {
2100 int i = mProcessObservers.beginBroadcast();
2101 while (i > 0) {
2102 i--;
2103 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2104 if (observer != null) {
2105 try {
2106 observer.onProcessDied(pid, uid);
2107 } catch (RemoteException e) {
2108 }
2109 }
2110 }
2111 mProcessObservers.finishBroadcast();
2112 }
2113
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002114 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002115 final int N = mPendingActivityLaunches.size();
2116 if (N <= 0) {
2117 return;
2118 }
2119 for (int i=0; i<N; i++) {
2120 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002121 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002122 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2123 doResume && i == (N-1));
2124 }
2125 mPendingActivityLaunches.clear();
2126 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002127
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002128 public final int startActivity(IApplicationThread caller,
2129 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2130 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002131 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2132 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002133 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002134 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002135 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2136 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002137 }
2138
2139 public final WaitResult startActivityAndWait(IApplicationThread caller,
2140 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2141 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002142 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2143 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002144 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002145 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002146 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002147 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2148 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002149 return res;
2150 }
2151
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002152 public final int startActivityWithConfig(IApplicationThread caller,
2153 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2154 int grantedMode, IBinder resultTo,
2155 String resultWho, int requestCode, boolean onlyIfNeeded,
2156 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002157 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002158 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002159 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002160 }
2161
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002162 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002163 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002164 IBinder resultTo, String resultWho, int requestCode,
2165 int flagsMask, int flagsValues) {
2166 // Refuse possible leaked file descriptors
2167 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2168 throw new IllegalArgumentException("File descriptors passed in Intent");
2169 }
2170
2171 IIntentSender sender = intent.getTarget();
2172 if (!(sender instanceof PendingIntentRecord)) {
2173 throw new IllegalArgumentException("Bad PendingIntent object");
2174 }
2175
2176 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002177
2178 synchronized (this) {
2179 // If this is coming from the currently resumed activity, it is
2180 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002181 if (mMainStack.mResumedActivity != null
2182 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002183 Binder.getCallingUid()) {
2184 mAppSwitchesAllowedTime = 0;
2185 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002186 }
2187
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002188 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002189 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2190 }
2191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 public boolean startNextMatchingActivity(IBinder callingActivity,
2193 Intent intent) {
2194 // Refuse possible leaked file descriptors
2195 if (intent != null && intent.hasFileDescriptors() == true) {
2196 throw new IllegalArgumentException("File descriptors passed in Intent");
2197 }
2198
2199 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002200 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2201 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002202 return false;
2203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204 if (r.app == null || r.app.thread == null) {
2205 // The caller is not running... d'oh!
2206 return false;
2207 }
2208 intent = new Intent(intent);
2209 // The caller is not allowed to change the data.
2210 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2211 // And we are resetting to find the next component...
2212 intent.setComponent(null);
2213
2214 ActivityInfo aInfo = null;
2215 try {
2216 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002217 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002219 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220
2221 // Look for the original activity in the list...
2222 final int N = resolves != null ? resolves.size() : 0;
2223 for (int i=0; i<N; i++) {
2224 ResolveInfo rInfo = resolves.get(i);
2225 if (rInfo.activityInfo.packageName.equals(r.packageName)
2226 && rInfo.activityInfo.name.equals(r.info.name)) {
2227 // We found the current one... the next matching is
2228 // after it.
2229 i++;
2230 if (i<N) {
2231 aInfo = resolves.get(i).activityInfo;
2232 }
2233 break;
2234 }
2235 }
2236 } catch (RemoteException e) {
2237 }
2238
2239 if (aInfo == null) {
2240 // Nobody who is next!
2241 return false;
2242 }
2243
2244 intent.setComponent(new ComponentName(
2245 aInfo.applicationInfo.packageName, aInfo.name));
2246 intent.setFlags(intent.getFlags()&~(
2247 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2248 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2249 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2250 Intent.FLAG_ACTIVITY_NEW_TASK));
2251
2252 // Okay now we need to start the new activity, replacing the
2253 // currently running activity. This is a little tricky because
2254 // we want to start the new one as if the current one is finished,
2255 // but not finish the current one first so that there is no flicker.
2256 // And thus...
2257 final boolean wasFinishing = r.finishing;
2258 r.finishing = true;
2259
2260 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002261 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 final String resultWho = r.resultWho;
2263 final int requestCode = r.requestCode;
2264 r.resultTo = null;
2265 if (resultTo != null) {
2266 resultTo.removeResultsLocked(r, resultWho, requestCode);
2267 }
2268
2269 final long origId = Binder.clearCallingIdentity();
2270 // XXX we are not dealing with propagating grantedUriPermissions...
2271 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002272 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002274 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 Binder.restoreCallingIdentity(origId);
2276
2277 r.finishing = wasFinishing;
2278 if (res != START_SUCCESS) {
2279 return false;
2280 }
2281 return true;
2282 }
2283 }
2284
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002285 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 Intent intent, String resolvedType, IBinder resultTo,
2287 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002288
2289 // This is so super not safe, that only the system (or okay root)
2290 // can do it.
2291 final int callingUid = Binder.getCallingUid();
2292 if (callingUid != 0 && callingUid != Process.myUid()) {
2293 throw new SecurityException(
2294 "startActivityInPackage only available to the system");
2295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002297 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002298 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2299 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002300 }
2301
2302 public final int startActivities(IApplicationThread caller,
2303 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2304 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2305 }
2306
2307 public final int startActivitiesInPackage(int uid,
2308 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2309
2310 // This is so super not safe, that only the system (or okay root)
2311 // can do it.
2312 final int callingUid = Binder.getCallingUid();
2313 if (callingUid != 0 && callingUid != Process.myUid()) {
2314 throw new SecurityException(
2315 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 }
2317
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002318 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 }
2320
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002321 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002323 // Quick case: check if the top-most recent task is the same.
2324 if (N > 0 && mRecentTasks.get(0) == task) {
2325 return;
2326 }
2327 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 for (int i=0; i<N; i++) {
2329 TaskRecord tr = mRecentTasks.get(i);
2330 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2331 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2332 mRecentTasks.remove(i);
2333 i--;
2334 N--;
2335 if (task.intent == null) {
2336 // If the new recent task we are adding is not fully
2337 // specified, then replace it with the existing recent task.
2338 task = tr;
2339 }
2340 }
2341 }
2342 if (N >= MAX_RECENT_TASKS) {
2343 mRecentTasks.remove(N-1);
2344 }
2345 mRecentTasks.add(0, task);
2346 }
2347
2348 public void setRequestedOrientation(IBinder token,
2349 int requestedOrientation) {
2350 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002351 ActivityRecord r = mMainStack.isInStackLocked(token);
2352 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353 return;
2354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002355 final long origId = Binder.clearCallingIdentity();
2356 mWindowManager.setAppOrientation(r, requestedOrientation);
2357 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002358 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 r.mayFreezeScreenLocked(r.app) ? r : null);
2360 if (config != null) {
2361 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002362 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002363 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 }
2365 }
2366 Binder.restoreCallingIdentity(origId);
2367 }
2368 }
2369
2370 public int getRequestedOrientation(IBinder token) {
2371 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002372 ActivityRecord r = mMainStack.isInStackLocked(token);
2373 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 return mWindowManager.getAppOrientation(r);
2377 }
2378 }
2379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 /**
2381 * This is the internal entry point for handling Activity.finish().
2382 *
2383 * @param token The Binder token referencing the Activity we want to finish.
2384 * @param resultCode Result code, if any, from this Activity.
2385 * @param resultData Result data (Intent), if any, from this Activity.
2386 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002387 * @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 -08002388 */
2389 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2390 // Refuse possible leaked file descriptors
2391 if (resultData != null && resultData.hasFileDescriptors() == true) {
2392 throw new IllegalArgumentException("File descriptors passed in Intent");
2393 }
2394
2395 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002396 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002398 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 if (next != null) {
2400 // ask watcher if this is allowed
2401 boolean resumeOK = true;
2402 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002403 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002405 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 }
2407
2408 if (!resumeOK) {
2409 return false;
2410 }
2411 }
2412 }
2413 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002414 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 resultData, "app-request");
2416 Binder.restoreCallingIdentity(origId);
2417 return res;
2418 }
2419 }
2420
Dianne Hackborn860755f2010-06-03 18:47:52 -07002421 public final void finishHeavyWeightApp() {
2422 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2423 != PackageManager.PERMISSION_GRANTED) {
2424 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2425 + Binder.getCallingPid()
2426 + ", uid=" + Binder.getCallingUid()
2427 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2428 Slog.w(TAG, msg);
2429 throw new SecurityException(msg);
2430 }
2431
2432 synchronized(this) {
2433 if (mHeavyWeightProcess == null) {
2434 return;
2435 }
2436
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002437 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002438 mHeavyWeightProcess.activities);
2439 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002440 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002441 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002442 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002443 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002444 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002445 null, "finish-heavy");
2446 }
2447 }
2448 }
2449
2450 mHeavyWeightProcess = null;
2451 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2452 }
2453 }
2454
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002455 public void crashApplication(int uid, int initialPid, String packageName,
2456 String message) {
2457 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2458 != PackageManager.PERMISSION_GRANTED) {
2459 String msg = "Permission Denial: crashApplication() from pid="
2460 + Binder.getCallingPid()
2461 + ", uid=" + Binder.getCallingUid()
2462 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2463 Slog.w(TAG, msg);
2464 throw new SecurityException(msg);
2465 }
2466
2467 synchronized(this) {
2468 ProcessRecord proc = null;
2469
2470 // Figure out which process to kill. We don't trust that initialPid
2471 // still has any relation to current pids, so must scan through the
2472 // list.
2473 synchronized (mPidsSelfLocked) {
2474 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2475 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2476 if (p.info.uid != uid) {
2477 continue;
2478 }
2479 if (p.pid == initialPid) {
2480 proc = p;
2481 break;
2482 }
2483 for (String str : p.pkgList) {
2484 if (str.equals(packageName)) {
2485 proc = p;
2486 }
2487 }
2488 }
2489 }
2490
2491 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002492 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002493 + " initialPid=" + initialPid
2494 + " packageName=" + packageName);
2495 return;
2496 }
2497
2498 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002499 if (proc.pid == Process.myPid()) {
2500 Log.w(TAG, "crashApplication: trying to crash self!");
2501 return;
2502 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002503 long ident = Binder.clearCallingIdentity();
2504 try {
2505 proc.thread.scheduleCrash(message);
2506 } catch (RemoteException e) {
2507 }
2508 Binder.restoreCallingIdentity(ident);
2509 }
2510 }
2511 }
2512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 public final void finishSubActivity(IBinder token, String resultWho,
2514 int requestCode) {
2515 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002516 ActivityRecord self = mMainStack.isInStackLocked(token);
2517 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 return;
2519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520
2521 final long origId = Binder.clearCallingIdentity();
2522
2523 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002524 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2525 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 if (r.resultTo == self && r.requestCode == requestCode) {
2527 if ((r.resultWho == null && resultWho == null) ||
2528 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002529 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 Activity.RESULT_CANCELED, null, "request-sub");
2531 }
2532 }
2533 }
2534
2535 Binder.restoreCallingIdentity(origId);
2536 }
2537 }
2538
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002539 public boolean willActivityBeVisible(IBinder token) {
2540 synchronized(this) {
2541 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002542 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2543 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002544 if (r == token) {
2545 return true;
2546 }
2547 if (r.fullscreen && !r.finishing) {
2548 return false;
2549 }
2550 }
2551 return true;
2552 }
2553 }
2554
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002555 public void overridePendingTransition(IBinder token, String packageName,
2556 int enterAnim, int exitAnim) {
2557 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002558 ActivityRecord self = mMainStack.isInStackLocked(token);
2559 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002560 return;
2561 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002562
2563 final long origId = Binder.clearCallingIdentity();
2564
2565 if (self.state == ActivityState.RESUMED
2566 || self.state == ActivityState.PAUSING) {
2567 mWindowManager.overridePendingAppTransition(packageName,
2568 enterAnim, exitAnim);
2569 }
2570
2571 Binder.restoreCallingIdentity(origId);
2572 }
2573 }
2574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 * Main function for removing an existing process from the activity manager
2577 * as a result of that process going away. Clears out all connections
2578 * to the process.
2579 */
2580 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002581 boolean restarting, boolean allowRestart) {
2582 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002584 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 }
2586
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002587 if (mProfileProc == app) {
2588 clearProfilerLocked();
2589 }
2590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002592 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2593 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2594 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2597 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 }
2599
2600 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002601 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602
2603 boolean atTop = true;
2604 boolean hasVisibleActivities = false;
2605
2606 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002607 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002608 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 TAG, "Removing app " + app + " from history with " + i + " entries");
2610 while (i > 0) {
2611 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002612 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002613 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2615 if (r.app == app) {
2616 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002617 if (ActivityStack.DEBUG_ADD_REMOVE) {
2618 RuntimeException here = new RuntimeException("here");
2619 here.fillInStackTrace();
2620 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2621 + ": haveState=" + r.haveState
2622 + " stateNotNeeded=" + r.stateNotNeeded
2623 + " finishing=" + r.finishing
2624 + " state=" + r.state, here);
2625 }
2626 if (!r.finishing) {
2627 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2628 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002629 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002630 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002631 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 mWindowManager.removeAppToken(r);
2633 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002634 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002635 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637
2638 } else {
2639 // We have the current state for this activity, so
2640 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002641 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002642 TAG, "Keeping entry, setting app to null");
2643 if (r.visible) {
2644 hasVisibleActivities = true;
2645 }
2646 r.app = null;
2647 r.nowVisible = false;
2648 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002649 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2650 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 r.icicle = null;
2652 }
2653 }
2654
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002655 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 }
2657 atTop = false;
2658 }
2659
2660 app.activities.clear();
2661
2662 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002663 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 + " running instrumentation " + app.instrumentationClass);
2665 Bundle info = new Bundle();
2666 info.putString("shortMsg", "Process crashed.");
2667 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2668 }
2669
2670 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002671 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 // If there was nothing to resume, and we are not already
2673 // restarting this process, but there is a visible activity that
2674 // is hosted by the process... then make sure all visible
2675 // activities are running, taking care of restarting this
2676 // process.
2677 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002678 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 }
2680 }
2681 }
2682 }
2683
2684 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2685 IBinder threadBinder = thread.asBinder();
2686
2687 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002688 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2689 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2691 return i;
2692 }
2693 }
2694 return -1;
2695 }
2696
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002697 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 IApplicationThread thread) {
2699 if (thread == null) {
2700 return null;
2701 }
2702
2703 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002704 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705 }
2706
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002707 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 IApplicationThread thread) {
2709
2710 mProcDeaths[0]++;
2711
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002712 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2713 synchronized (stats) {
2714 stats.noteProcessDiedLocked(app.info.uid, pid);
2715 }
2716
Magnus Edlund7bb25812010-02-24 15:45:06 +01002717 // Clean up already done if the process has been re-started.
2718 if (app.pid == pid && app.thread != null &&
2719 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002720 if (!app.killedBackground) {
2721 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2722 + ") has died.");
2723 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002724 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002725 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 TAG, "Dying app: " + app + ", pid: " + pid
2727 + ", thread: " + thread.asBinder());
2728 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002729 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730
2731 if (doLowMem) {
2732 // If there are no longer any background processes running,
2733 // and the app that died was not running instrumentation,
2734 // then tell everyone we are now low on memory.
2735 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002736 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2737 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002738 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 haveBg = true;
2740 break;
2741 }
2742 }
2743
2744 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002745 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002746 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002747 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2748 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002749 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002750 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2751 // The low memory report is overriding any current
2752 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002753 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002754 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002755 rec.lastRequestedGc = 0;
2756 } else {
2757 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002759 rec.reportLowMemory = true;
2760 rec.lastLowMemory = now;
2761 mProcessesToGc.remove(rec);
2762 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 }
2764 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002765 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002766 }
2767 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002768 } else if (app.pid != pid) {
2769 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002770 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002771 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002772 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002773 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002774 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 + thread.asBinder());
2776 }
2777 }
2778
Dan Egnor42471dd2010-01-07 17:25:22 -08002779 /**
2780 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002781 * @param clearTraces causes the dump file to be erased prior to the new
2782 * traces being written, if true; when false, the new traces will be
2783 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002784 * @param firstPids of dalvik VM processes to dump stack traces for first
2785 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002786 * @return file containing stack traces, or null if no dump file is configured
2787 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002788 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2789 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002790 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2791 if (tracesPath == null || tracesPath.length() == 0) {
2792 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002794
2795 File tracesFile = new File(tracesPath);
2796 try {
2797 File tracesDir = tracesFile.getParentFile();
2798 if (!tracesDir.exists()) tracesFile.mkdirs();
2799 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2800
Christopher Tate6ee412d2010-05-28 12:01:56 -07002801 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002802 tracesFile.createNewFile();
2803 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2804 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002805 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002806 return null;
2807 }
2808
2809 // Use a FileObserver to detect when traces finish writing.
2810 // The order of traces is considered important to maintain for legibility.
2811 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2812 public synchronized void onEvent(int event, String path) { notify(); }
2813 };
2814
2815 try {
2816 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002817
2818 // First collect all of the stacks of the most important pids.
2819 try {
2820 int num = firstPids.size();
2821 for (int i = 0; i < num; i++) {
2822 synchronized (observer) {
2823 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2824 observer.wait(200); // Wait for write-close, give up after 200msec
2825 }
2826 }
2827 } catch (InterruptedException e) {
2828 Log.wtf(TAG, e);
2829 }
2830
2831 // Next measure CPU usage.
2832 if (processStats != null) {
2833 processStats.init();
2834 System.gc();
2835 processStats.update();
2836 try {
2837 synchronized (processStats) {
2838 processStats.wait(500); // measure over 1/2 second.
2839 }
2840 } catch (InterruptedException e) {
2841 }
2842 processStats.update();
2843
2844 // We'll take the stack crawls of just the top apps using CPU.
2845 final int N = processStats.countWorkingStats();
2846 int numProcs = 0;
2847 for (int i=0; i<N && numProcs<5; i++) {
2848 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2849 if (lastPids.indexOfKey(stats.pid) >= 0) {
2850 numProcs++;
2851 try {
2852 synchronized (observer) {
2853 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2854 observer.wait(200); // Wait for write-close, give up after 200msec
2855 }
2856 } catch (InterruptedException e) {
2857 Log.wtf(TAG, e);
2858 }
2859
2860 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002861 }
2862 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002863
2864 return tracesFile;
2865
Dan Egnor42471dd2010-01-07 17:25:22 -08002866 } finally {
2867 observer.stopWatching();
2868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002869 }
2870
Jeff Brown4d94a762010-09-23 11:33:28 -07002871 private final class AppNotResponding implements Runnable {
2872 private final ProcessRecord mApp;
2873 private final String mAnnotation;
2874
2875 public AppNotResponding(ProcessRecord app, String annotation) {
2876 mApp = app;
2877 mAnnotation = annotation;
2878 }
2879
2880 @Override
2881 public void run() {
2882 appNotResponding(mApp, null, null, mAnnotation);
2883 }
2884 }
2885
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002886 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2887 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002888 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2889 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2890
Dianne Hackborn287952c2010-09-22 22:34:31 -07002891 if (mController != null) {
2892 try {
2893 // 0 == continue, -1 = kill process immediately
2894 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2895 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2896 } catch (RemoteException e) {
2897 mController = null;
2898 }
2899 }
2900
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002901 long anrTime = SystemClock.uptimeMillis();
2902 if (MONITOR_CPU_USAGE) {
2903 updateCpuStatsNow();
2904 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905
2906 synchronized (this) {
2907 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2908 if (mShuttingDown) {
2909 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2910 return;
2911 } else if (app.notResponding) {
2912 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2913 return;
2914 } else if (app.crashing) {
2915 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2916 return;
2917 }
2918
2919 // In case we come through here for the same app before completing
2920 // this one, mark as anring now so we will bail out.
2921 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002922
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002923 // Log the ANR to the event log.
2924 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2925 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002926
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002927 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002928 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002929
2930 int parentPid = app.pid;
2931 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002935
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002936 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2937 ProcessRecord r = mLruProcesses.get(i);
2938 if (r != null && r.thread != null) {
2939 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002940 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2941 if (r.persistent) {
2942 firstPids.add(pid);
2943 } else {
2944 lastPids.put(pid, Boolean.TRUE);
2945 }
2946 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 }
2949 }
2950
Dan Egnor42471dd2010-01-07 17:25:22 -08002951 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002952 StringBuilder info = mStringBuilder;
2953 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002954 info.append("ANR in ").append(app.processName);
2955 if (activity != null && activity.shortComponentName != null) {
2956 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002957 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002958 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002960 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002962 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002963 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965
Dianne Hackborn287952c2010-09-22 22:34:31 -07002966 final ProcessStats processStats = new ProcessStats(true);
2967
2968 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2969
Dan Egnor42471dd2010-01-07 17:25:22 -08002970 String cpuInfo = null;
2971 if (MONITOR_CPU_USAGE) {
2972 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002973 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002974 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002975 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002976 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002977 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002978 }
2979
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002980 info.append(processStats.printCurrentState(anrTime));
2981
Joe Onorato8a9b2202010-02-26 18:56:32 -08002982 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002983 if (tracesFile == null) {
2984 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2985 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2986 }
2987
Jeff Sharkeya353d262011-10-28 11:12:06 -07002988 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
2989 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08002990
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002991 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002993 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2994 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002996 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2997 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 }
2999 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003000 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 }
3002 }
3003
Dan Egnor42471dd2010-01-07 17:25:22 -08003004 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3005 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3006 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003007
3008 synchronized (this) {
3009 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003010 Slog.w(TAG, "Killing " + app + ": background ANR");
3011 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3012 app.processName, app.setAdj, "background ANR");
3013 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003014 return;
3015 }
3016
3017 // Set the app's notResponding state, and look up the errorReportReceiver
3018 makeAppNotRespondingLocked(app,
3019 activity != null ? activity.shortComponentName : null,
3020 annotation != null ? "ANR " + annotation : "ANR",
3021 info.toString());
3022
3023 // Bring up the infamous App Not Responding dialog
3024 Message msg = Message.obtain();
3025 HashMap map = new HashMap();
3026 msg.what = SHOW_NOT_RESPONDING_MSG;
3027 msg.obj = map;
3028 map.put("app", app);
3029 if (activity != null) {
3030 map.put("activity", activity);
3031 }
3032
3033 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 }
3036
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003037 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3038 if (!mLaunchWarningShown) {
3039 mLaunchWarningShown = true;
3040 mHandler.post(new Runnable() {
3041 @Override
3042 public void run() {
3043 synchronized (ActivityManagerService.this) {
3044 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3045 d.show();
3046 mHandler.postDelayed(new Runnable() {
3047 @Override
3048 public void run() {
3049 synchronized (ActivityManagerService.this) {
3050 d.dismiss();
3051 mLaunchWarningShown = false;
3052 }
3053 }
3054 }, 4000);
3055 }
3056 }
3057 });
3058 }
3059 }
3060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 public boolean clearApplicationUserData(final String packageName,
3062 final IPackageDataObserver observer) {
3063 int uid = Binder.getCallingUid();
3064 int pid = Binder.getCallingPid();
3065 long callingId = Binder.clearCallingIdentity();
3066 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003067 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003068 int pkgUid = -1;
3069 synchronized(this) {
3070 try {
3071 pkgUid = pm.getPackageUid(packageName);
3072 } catch (RemoteException e) {
3073 }
3074 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003075 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 return false;
3077 }
3078 if (uid == pkgUid || checkComponentPermission(
3079 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003080 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003081 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003082 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003083 } else {
3084 throw new SecurityException(pid+" does not have permission:"+
3085 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3086 "for process:"+packageName);
3087 }
3088 }
3089
3090 try {
3091 //clear application user data
3092 pm.clearApplicationUserData(packageName, observer);
3093 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3094 Uri.fromParts("package", packageName, null));
3095 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003096 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3097 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 } catch (RemoteException e) {
3099 }
3100 } finally {
3101 Binder.restoreCallingIdentity(callingId);
3102 }
3103 return true;
3104 }
3105
Dianne Hackborn03abb812010-01-04 18:43:19 -08003106 public void killBackgroundProcesses(final String packageName) {
3107 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3108 != PackageManager.PERMISSION_GRANTED &&
3109 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3110 != PackageManager.PERMISSION_GRANTED) {
3111 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 + Binder.getCallingPid()
3113 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003114 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003115 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003116 throw new SecurityException(msg);
3117 }
3118
3119 long callingId = Binder.clearCallingIdentity();
3120 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003121 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003122 int pkgUid = -1;
3123 synchronized(this) {
3124 try {
3125 pkgUid = pm.getPackageUid(packageName);
3126 } catch (RemoteException e) {
3127 }
3128 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003129 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003130 return;
3131 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003132 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne02c88a2011-10-28 13:58:15 -07003133 ProcessList.SERVICE_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003134 }
3135 } finally {
3136 Binder.restoreCallingIdentity(callingId);
3137 }
3138 }
3139
3140 public void forceStopPackage(final String packageName) {
3141 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3142 != PackageManager.PERMISSION_GRANTED) {
3143 String msg = "Permission Denial: forceStopPackage() from pid="
3144 + Binder.getCallingPid()
3145 + ", uid=" + Binder.getCallingUid()
3146 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003147 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003148 throw new SecurityException(msg);
3149 }
3150
3151 long callingId = Binder.clearCallingIdentity();
3152 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003153 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003154 int pkgUid = -1;
3155 synchronized(this) {
3156 try {
3157 pkgUid = pm.getPackageUid(packageName);
3158 } catch (RemoteException e) {
3159 }
3160 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003161 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003162 return;
3163 }
3164 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003165 try {
3166 pm.setPackageStoppedState(packageName, true);
3167 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003168 } catch (IllegalArgumentException e) {
3169 Slog.w(TAG, "Failed trying to unstop package "
3170 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003172 }
3173 } finally {
3174 Binder.restoreCallingIdentity(callingId);
3175 }
3176 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003177
3178 /*
3179 * The pkg name and uid have to be specified.
3180 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3181 */
3182 public void killApplicationWithUid(String pkg, int uid) {
3183 if (pkg == null) {
3184 return;
3185 }
3186 // Make sure the uid is valid.
3187 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003188 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003189 return;
3190 }
3191 int callerUid = Binder.getCallingUid();
3192 // Only the system server can kill an application
3193 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003194 // Post an aysnc message to kill the application
3195 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3196 msg.arg1 = uid;
3197 msg.arg2 = 0;
3198 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003199 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003200 } else {
3201 throw new SecurityException(callerUid + " cannot kill pkg: " +
3202 pkg);
3203 }
3204 }
3205
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003206 public void closeSystemDialogs(String reason) {
3207 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003208 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003209 if (reason != null) {
3210 intent.putExtra("reason", reason);
3211 }
3212
3213 final int uid = Binder.getCallingUid();
3214 final long origId = Binder.clearCallingIdentity();
3215 synchronized (this) {
3216 int i = mWatchers.beginBroadcast();
3217 while (i > 0) {
3218 i--;
3219 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3220 if (w != null) {
3221 try {
3222 w.closingSystemDialogs(reason);
3223 } catch (RemoteException e) {
3224 }
3225 }
3226 }
3227 mWatchers.finishBroadcast();
3228
Dianne Hackbornffa42482009-09-23 22:20:11 -07003229 mWindowManager.closeSystemDialogs(reason);
3230
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003231 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3232 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003233 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003234 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003235 Activity.RESULT_CANCELED, null, "close-sys");
3236 }
3237 }
3238
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003239 broadcastIntentLocked(null, null, intent, null,
3240 null, 0, null, null, null, false, false, -1, uid);
3241 }
3242 Binder.restoreCallingIdentity(origId);
3243 }
3244
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003245 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003246 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003247 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3248 for (int i=pids.length-1; i>=0; i--) {
3249 infos[i] = new Debug.MemoryInfo();
3250 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003251 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003252 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003253 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003254
Dianne Hackbornb437e092011-08-05 17:50:29 -07003255 public long[] getProcessPss(int[] pids) throws RemoteException {
3256 long[] pss = new long[pids.length];
3257 for (int i=pids.length-1; i>=0; i--) {
3258 pss[i] = Debug.getPss(pids[i]);
3259 }
3260 return pss;
3261 }
3262
Christopher Tate5e1ab332009-09-01 20:32:49 -07003263 public void killApplicationProcess(String processName, int uid) {
3264 if (processName == null) {
3265 return;
3266 }
3267
3268 int callerUid = Binder.getCallingUid();
3269 // Only the system server can kill an application
3270 if (callerUid == Process.SYSTEM_UID) {
3271 synchronized (this) {
3272 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003273 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003274 try {
3275 app.thread.scheduleSuicide();
3276 } catch (RemoteException e) {
3277 // If the other end already died, then our work here is done.
3278 }
3279 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003280 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003281 + processName + " / " + uid);
3282 }
3283 }
3284 } else {
3285 throw new SecurityException(callerUid + " cannot kill app process: " +
3286 processName);
3287 }
3288 }
3289
Dianne Hackborn03abb812010-01-04 18:43:19 -08003290 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003291 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3293 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003294 if (!mProcessesReady) {
3295 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003297 intent.putExtra(Intent.EXTRA_UID, uid);
3298 broadcastIntentLocked(null, null, intent,
3299 null, null, 0, null, null, null,
3300 false, false, MY_PID, Process.SYSTEM_UID);
3301 }
3302
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003303 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003304 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3305 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003306 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307
Dianne Hackborn03abb812010-01-04 18:43:19 -08003308 // Remove all processes this package may have touched: all with the
3309 // same UID (except for the system or root user), and all whose name
3310 // matches the package name.
3311 final String procNamePrefix = packageName + ":";
3312 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3313 final int NA = apps.size();
3314 for (int ia=0; ia<NA; ia++) {
3315 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003316 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003317 // we don't kill persistent processes
3318 continue;
3319 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003320 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003321 if (doit) {
3322 procs.add(app);
3323 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003324 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3325 || app.processName.equals(packageName)
3326 || app.processName.startsWith(procNamePrefix)) {
3327 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003328 if (!doit) {
3329 return true;
3330 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003331 app.removed = true;
3332 procs.add(app);
3333 }
3334 }
3335 }
3336 }
3337
3338 int N = procs.size();
3339 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003340 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003341 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003342 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003343 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003344
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003345 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003346 boolean callerWillRestart, boolean purgeCache, boolean doit,
3347 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003348 int i;
3349 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 if (uid < 0) {
3352 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003353 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 } catch (RemoteException e) {
3355 }
3356 }
3357
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003358 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003359 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003360
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003361 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3362 while (badApps.hasNext()) {
3363 SparseArray<Long> ba = badApps.next();
3364 if (ba.get(uid) != null) {
3365 badApps.remove();
3366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003367 }
3368 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003369
3370 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003371 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003372
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003373 TaskRecord lastTask = null;
3374 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003375 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003376 final boolean samePackage = r.packageName.equals(name);
3377 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003378 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003379 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003380 if (r.finishing) {
3381 // If this activity is just finishing, then it is not
3382 // interesting as far as something to stop.
3383 continue;
3384 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003385 return true;
3386 }
3387 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003388 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003389 if (samePackage) {
3390 if (r.app != null) {
3391 r.app.removed = true;
3392 }
3393 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003395 lastTask = r.task;
3396 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3397 null, "force-stop")) {
3398 i--;
3399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 }
3401 }
3402
3403 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3404 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003405 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003406 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003407 if (!doit) {
3408 return true;
3409 }
3410 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003411 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 if (service.app != null) {
3413 service.app.removed = true;
3414 }
3415 service.app = null;
3416 services.add(service);
3417 }
3418 }
3419
3420 N = services.size();
3421 for (i=0; i<N; i++) {
3422 bringDownServiceLocked(services.get(i), true);
3423 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003424
3425 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3426 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3427 if (provider.info.packageName.equals(name)
3428 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3429 if (!doit) {
3430 return true;
3431 }
3432 didSomething = true;
3433 providers.add(provider);
3434 }
3435 }
3436
3437 N = providers.size();
3438 for (i=0; i<N; i++) {
3439 removeDyingProviderLocked(null, providers.get(i));
3440 }
3441
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003442 if (doit) {
3443 if (purgeCache) {
3444 AttributeCache ac = AttributeCache.instance();
3445 if (ac != null) {
3446 ac.removePackage(name);
3447 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003448 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003449 if (mBooted) {
3450 mMainStack.resumeTopActivityLocked(null);
3451 mMainStack.scheduleIdleLocked();
3452 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003453 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003454
3455 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 }
3457
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003458 private final boolean removeProcessLocked(ProcessRecord app,
3459 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 final String name = app.processName;
3461 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003462 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 TAG, "Force removing process " + app + " (" + name
3464 + "/" + uid + ")");
3465
3466 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003467 if (mHeavyWeightProcess == app) {
3468 mHeavyWeightProcess = null;
3469 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 boolean needRestart = false;
3472 if (app.pid > 0 && app.pid != MY_PID) {
3473 int pid = app.pid;
3474 synchronized (mPidsSelfLocked) {
3475 mPidsSelfLocked.remove(pid);
3476 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3477 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003478 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003479 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480 Process.killProcess(pid);
3481
3482 if (app.persistent) {
3483 if (!callerWillRestart) {
3484 addAppLocked(app.info);
3485 } else {
3486 needRestart = true;
3487 }
3488 }
3489 } else {
3490 mRemovedProcesses.add(app);
3491 }
3492
3493 return needRestart;
3494 }
3495
3496 private final void processStartTimedOutLocked(ProcessRecord app) {
3497 final int pid = app.pid;
3498 boolean gone = false;
3499 synchronized (mPidsSelfLocked) {
3500 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3501 if (knownApp != null && knownApp.thread == null) {
3502 mPidsSelfLocked.remove(pid);
3503 gone = true;
3504 }
3505 }
3506
3507 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003508 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003509 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003510 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003512 if (mHeavyWeightProcess == app) {
3513 mHeavyWeightProcess = null;
3514 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3515 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003516 // Take care of any launching providers waiting for this process.
3517 checkAppInLaunchingProvidersLocked(app, true);
3518 // Take care of any services that are waiting for the process.
3519 for (int i=0; i<mPendingServices.size(); i++) {
3520 ServiceRecord sr = mPendingServices.get(i);
3521 if (app.info.uid == sr.appInfo.uid
3522 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003523 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003524 mPendingServices.remove(i);
3525 i--;
3526 bringDownServiceLocked(sr, true);
3527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003529 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3530 app.processName, app.setAdj, "start timeout");
3531 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003532 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003533 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003534 try {
3535 IBackupManager bm = IBackupManager.Stub.asInterface(
3536 ServiceManager.getService(Context.BACKUP_SERVICE));
3537 bm.agentDisconnected(app.info.packageName);
3538 } catch (RemoteException e) {
3539 // Can't happen; the backup manager is local
3540 }
3541 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003542 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003543 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003544 mPendingBroadcast.state = BroadcastRecord.IDLE;
3545 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003546 mPendingBroadcast = null;
3547 scheduleBroadcastsLocked();
3548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003550 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 }
3552 }
3553
3554 private final boolean attachApplicationLocked(IApplicationThread thread,
3555 int pid) {
3556
3557 // Find the application record that is being attached... either via
3558 // the pid if we are running in multiple processes, or just pull the
3559 // next app record if we are emulating process with anonymous threads.
3560 ProcessRecord app;
3561 if (pid != MY_PID && pid >= 0) {
3562 synchronized (mPidsSelfLocked) {
3563 app = mPidsSelfLocked.get(pid);
3564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 } else {
3566 app = null;
3567 }
3568
3569 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003570 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003572 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003574 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 } else {
3576 try {
3577 thread.scheduleExit();
3578 } catch (Exception e) {
3579 // Ignore exceptions.
3580 }
3581 }
3582 return false;
3583 }
3584
3585 // If this application record is still attached to a previous
3586 // process, clean it up now.
3587 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003588 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003589 }
3590
3591 // Tell the process all about itself.
3592
Joe Onorato8a9b2202010-02-26 18:56:32 -08003593 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 TAG, "Binding process pid " + pid + " to record " + app);
3595
3596 String processName = app.processName;
3597 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003598 AppDeathRecipient adr = new AppDeathRecipient(
3599 app, pid, thread);
3600 thread.asBinder().linkToDeath(adr, 0);
3601 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 } catch (RemoteException e) {
3603 app.resetPackageList();
3604 startProcessLocked(app, "link fail", processName);
3605 return false;
3606 }
3607
Doug Zongker2bec3d42009-12-04 12:52:44 -08003608 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609
3610 app.thread = thread;
3611 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003612 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3613 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 app.forcingToForeground = null;
3615 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003616 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 app.debugging = false;
3618
3619 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3620
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003621 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003622 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003624 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003625 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003626 }
3627
Joe Onorato8a9b2202010-02-26 18:56:32 -08003628 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 TAG, "New app record " + app
3630 + " thread=" + thread.asBinder() + " pid=" + pid);
3631 try {
3632 int testMode = IApplicationThread.DEBUG_OFF;
3633 if (mDebugApp != null && mDebugApp.equals(processName)) {
3634 testMode = mWaitForDebugger
3635 ? IApplicationThread.DEBUG_WAIT
3636 : IApplicationThread.DEBUG_ON;
3637 app.debugging = true;
3638 if (mDebugTransient) {
3639 mDebugApp = mOrigDebugApp;
3640 mWaitForDebugger = mOrigWaitForDebugger;
3641 }
3642 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003643 String profileFile = app.instrumentationProfileFile;
3644 ParcelFileDescriptor profileFd = null;
3645 boolean profileAutoStop = false;
3646 if (mProfileApp != null && mProfileApp.equals(processName)) {
3647 mProfileProc = app;
3648 profileFile = mProfileFile;
3649 profileFd = mProfileFd;
3650 profileAutoStop = mAutoStopProfiler;
3651 }
3652
Christopher Tate181fafa2009-05-14 11:12:14 -07003653 // If the app is being launched for restore or full backup, set it up specially
3654 boolean isRestrictedBackupMode = false;
3655 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3656 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003657 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003658 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3659 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003660
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003661 ensurePackageDexOpt(app.instrumentationInfo != null
3662 ? app.instrumentationInfo.packageName
3663 : app.info.packageName);
3664 if (app.instrumentationClass != null) {
3665 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003666 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003667 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003668 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003669 ApplicationInfo appInfo = app.instrumentationInfo != null
3670 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003671 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003672 if (profileFd != null) {
3673 profileFd = profileFd.dup();
3674 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003675 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003676 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003678 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003679 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003680 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003681 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003682 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003683 } catch (Exception e) {
3684 // todo: Yikes! What should we do? For now we will try to
3685 // start another process, but that could easily get us in
3686 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003687 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688
3689 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003690 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003691 startProcessLocked(app, "bind fail", processName);
3692 return false;
3693 }
3694
3695 // Remove this record from the list of starting applications.
3696 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003697 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3698 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 mProcessesOnHold.remove(app);
3700
3701 boolean badApp = false;
3702 boolean didSomething = false;
3703
3704 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003705 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003706 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3708 && processName.equals(hr.processName)) {
3709 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003710 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 didSomething = true;
3712 }
3713 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003714 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003715 + hr.intent.getComponent().flattenToShortString(), e);
3716 badApp = true;
3717 }
3718 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003719 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 }
3721 }
3722
3723 // Find any services that should be running in this process...
3724 if (!badApp && mPendingServices.size() > 0) {
3725 ServiceRecord sr = null;
3726 try {
3727 for (int i=0; i<mPendingServices.size(); i++) {
3728 sr = mPendingServices.get(i);
3729 if (app.info.uid != sr.appInfo.uid
3730 || !processName.equals(sr.processName)) {
3731 continue;
3732 }
3733
3734 mPendingServices.remove(i);
3735 i--;
3736 realStartServiceLocked(sr, app);
3737 didSomething = true;
3738 }
3739 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003740 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 + sr.shortName, e);
3742 badApp = true;
3743 }
3744 }
3745
3746 // Check if the next broadcast receiver is in this process...
3747 BroadcastRecord br = mPendingBroadcast;
3748 if (!badApp && br != null && br.curApp == app) {
3749 try {
3750 mPendingBroadcast = null;
3751 processCurBroadcastLocked(br, app);
3752 didSomething = true;
3753 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003754 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 + br.curComponent.flattenToShortString(), e);
3756 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003757 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3759 br.resultExtras, br.resultAbort, true);
3760 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003761 // We need to reset the state if we fails to start the receiver.
3762 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 }
3764 }
3765
Christopher Tate181fafa2009-05-14 11:12:14 -07003766 // Check whether the next backup agent is in this process...
3767 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003768 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003769 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003770 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003771 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3772 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3773 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003774 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003775 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003776 e.printStackTrace();
3777 }
3778 }
3779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 if (badApp) {
3781 // todo: Also need to kill application to deal with all
3782 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003783 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003784 return false;
3785 }
3786
3787 if (!didSomething) {
3788 updateOomAdjLocked();
3789 }
3790
3791 return true;
3792 }
3793
3794 public final void attachApplication(IApplicationThread thread) {
3795 synchronized (this) {
3796 int callingPid = Binder.getCallingPid();
3797 final long origId = Binder.clearCallingIdentity();
3798 attachApplicationLocked(thread, callingPid);
3799 Binder.restoreCallingIdentity(origId);
3800 }
3801 }
3802
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003803 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003805 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3806 if (stopProfiling) {
3807 synchronized (this) {
3808 if (mProfileProc == r.app) {
3809 if (mProfileFd != null) {
3810 try {
3811 mProfileFd.close();
3812 } catch (IOException e) {
3813 }
3814 clearProfilerLocked();
3815 }
3816 }
3817 }
3818 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819 Binder.restoreCallingIdentity(origId);
3820 }
3821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003823 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003824 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 mWindowManager.enableScreenAfterBoot();
3826 }
3827
Dianne Hackborn661cd522011-08-22 00:26:20 -07003828 public void showBootMessage(final CharSequence msg, final boolean always) {
3829 mWindowManager.showBootMessage(msg, always);
3830 }
3831
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003832 public void dismissKeyguardOnNextActivity() {
3833 synchronized (this) {
3834 mMainStack.dismissKeyguardOnNextActivityLocked();
3835 }
3836 }
3837
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003838 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003839 IntentFilter pkgFilter = new IntentFilter();
3840 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3841 pkgFilter.addDataScheme("package");
3842 mContext.registerReceiver(new BroadcastReceiver() {
3843 @Override
3844 public void onReceive(Context context, Intent intent) {
3845 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3846 if (pkgs != null) {
3847 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003848 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003849 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003850 setResultCode(Activity.RESULT_OK);
3851 return;
3852 }
3853 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003854 }
3855 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003856 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003857 }, pkgFilter);
3858
3859 synchronized (this) {
3860 // Ensure that any processes we had put on hold are now started
3861 // up.
3862 final int NP = mProcessesOnHold.size();
3863 if (NP > 0) {
3864 ArrayList<ProcessRecord> procs =
3865 new ArrayList<ProcessRecord>(mProcessesOnHold);
3866 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003867 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3868 + procs.get(ip));
3869 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003870 }
3871 }
3872
3873 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003874 // Start looking for apps that are abusing wake locks.
3875 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003876 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003877 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003878 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003879 broadcastIntentLocked(null, null,
3880 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3881 null, null, 0, null, null,
3882 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3883 false, false, MY_PID, Process.SYSTEM_UID);
3884 }
3885 }
3886 }
3887
3888 final void ensureBootCompleted() {
3889 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003890 boolean enableScreen;
3891 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003892 booting = mBooting;
3893 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003894 enableScreen = !mBooted;
3895 mBooted = true;
3896 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003897
3898 if (booting) {
3899 finishBooting();
3900 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003901
3902 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003903 enableScreenAfterBoot();
3904 }
3905 }
3906
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003907 public final void activityPaused(IBinder token) {
3908 final long origId = Binder.clearCallingIdentity();
3909 mMainStack.activityPaused(token, false);
3910 Binder.restoreCallingIdentity(origId);
3911 }
3912
3913 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3914 CharSequence description) {
3915 if (localLOGV) Slog.v(
3916 TAG, "Activity stopped: token=" + token);
3917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 // Refuse possible leaked file descriptors
3919 if (icicle != null && icicle.hasFileDescriptors()) {
3920 throw new IllegalArgumentException("File descriptors passed in Bundle");
3921 }
3922
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003923 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924
3925 final long origId = Binder.clearCallingIdentity();
3926
3927 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003928 r = mMainStack.isInStackLocked(token);
3929 if (r != null) {
3930 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 }
3932 }
3933
3934 if (r != null) {
3935 sendPendingThumbnail(r, null, null, null, false);
3936 }
3937
3938 trimApplications();
3939
3940 Binder.restoreCallingIdentity(origId);
3941 }
3942
3943 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003944 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003945 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 }
3947
3948 public String getCallingPackage(IBinder token) {
3949 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003950 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003951 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 }
3953 }
3954
3955 public ComponentName getCallingActivity(IBinder token) {
3956 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003957 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 return r != null ? r.intent.getComponent() : null;
3959 }
3960 }
3961
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003962 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003963 ActivityRecord r = mMainStack.isInStackLocked(token);
3964 if (r == null) {
3965 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003967 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 }
3969
3970 public ComponentName getActivityClassForToken(IBinder token) {
3971 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003972 ActivityRecord r = mMainStack.isInStackLocked(token);
3973 if (r == null) {
3974 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003975 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003976 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 }
3978 }
3979
3980 public String getPackageForToken(IBinder token) {
3981 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003982 ActivityRecord r = mMainStack.isInStackLocked(token);
3983 if (r == null) {
3984 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003986 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003987 }
3988 }
3989
3990 public IIntentSender getIntentSender(int type,
3991 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003992 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003994 if (intents != null) {
3995 if (intents.length < 1) {
3996 throw new IllegalArgumentException("Intents array length must be >= 1");
3997 }
3998 for (int i=0; i<intents.length; i++) {
3999 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004000 if (intent != null) {
4001 if (intent.hasFileDescriptors()) {
4002 throw new IllegalArgumentException("File descriptors passed in Intent");
4003 }
4004 if (type == INTENT_SENDER_BROADCAST &&
4005 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4006 throw new IllegalArgumentException(
4007 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4008 }
4009 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004010 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004011 }
4012 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004013 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004014 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004015 }
4016 }
4017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 synchronized(this) {
4019 int callingUid = Binder.getCallingUid();
4020 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004021 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004022 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 .getPackageUid(packageName);
4024 if (uid != Binder.getCallingUid()) {
4025 String msg = "Permission Denial: getIntentSender() from pid="
4026 + Binder.getCallingPid()
4027 + ", uid=" + Binder.getCallingUid()
4028 + ", (need uid=" + uid + ")"
4029 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004030 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 throw new SecurityException(msg);
4032 }
4033 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004034
4035 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004036 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004038 } catch (RemoteException e) {
4039 throw new SecurityException(e);
4040 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004041 }
4042 }
4043
4044 IIntentSender getIntentSenderLocked(int type,
4045 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004046 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004047 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004048 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004049 activity = mMainStack.isInStackLocked(token);
4050 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004051 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004053 if (activity.finishing) {
4054 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004056 }
4057
4058 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4059 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4060 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4061 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4062 |PendingIntent.FLAG_UPDATE_CURRENT);
4063
4064 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4065 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004066 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004067 WeakReference<PendingIntentRecord> ref;
4068 ref = mIntentSenderRecords.get(key);
4069 PendingIntentRecord rec = ref != null ? ref.get() : null;
4070 if (rec != null) {
4071 if (!cancelCurrent) {
4072 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004073 if (rec.key.requestIntent != null) {
4074 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4075 }
4076 if (intents != null) {
4077 intents[intents.length-1] = rec.key.requestIntent;
4078 rec.key.allIntents = intents;
4079 rec.key.allResolvedTypes = resolvedTypes;
4080 } else {
4081 rec.key.allIntents = null;
4082 rec.key.allResolvedTypes = null;
4083 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 return rec;
4086 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004087 rec.canceled = true;
4088 mIntentSenderRecords.remove(key);
4089 }
4090 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 return rec;
4092 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004093 rec = new PendingIntentRecord(this, key, callingUid);
4094 mIntentSenderRecords.put(key, rec.ref);
4095 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4096 if (activity.pendingResults == null) {
4097 activity.pendingResults
4098 = new HashSet<WeakReference<PendingIntentRecord>>();
4099 }
4100 activity.pendingResults.add(rec.ref);
4101 }
4102 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103 }
4104
4105 public void cancelIntentSender(IIntentSender sender) {
4106 if (!(sender instanceof PendingIntentRecord)) {
4107 return;
4108 }
4109 synchronized(this) {
4110 PendingIntentRecord rec = (PendingIntentRecord)sender;
4111 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004112 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004113 .getPackageUid(rec.key.packageName);
4114 if (uid != Binder.getCallingUid()) {
4115 String msg = "Permission Denial: cancelIntentSender() from pid="
4116 + Binder.getCallingPid()
4117 + ", uid=" + Binder.getCallingUid()
4118 + " is not allowed to cancel packges "
4119 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004120 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004121 throw new SecurityException(msg);
4122 }
4123 } catch (RemoteException e) {
4124 throw new SecurityException(e);
4125 }
4126 cancelIntentSenderLocked(rec, true);
4127 }
4128 }
4129
4130 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4131 rec.canceled = true;
4132 mIntentSenderRecords.remove(rec.key);
4133 if (cleanActivity && rec.key.activity != null) {
4134 rec.key.activity.pendingResults.remove(rec.ref);
4135 }
4136 }
4137
4138 public String getPackageForIntentSender(IIntentSender pendingResult) {
4139 if (!(pendingResult instanceof PendingIntentRecord)) {
4140 return null;
4141 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004142 try {
4143 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4144 return res.key.packageName;
4145 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004146 }
4147 return null;
4148 }
4149
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004150 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4151 if (!(pendingResult instanceof PendingIntentRecord)) {
4152 return false;
4153 }
4154 try {
4155 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4156 if (res.key.allIntents == null) {
4157 return false;
4158 }
4159 for (int i=0; i<res.key.allIntents.length; i++) {
4160 Intent intent = res.key.allIntents[i];
4161 if (intent.getPackage() != null && intent.getComponent() != null) {
4162 return false;
4163 }
4164 }
4165 return true;
4166 } catch (ClassCastException e) {
4167 }
4168 return false;
4169 }
4170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 public void setProcessLimit(int max) {
4172 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4173 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004174 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004175 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004176 mProcessLimitOverride = max;
4177 }
4178 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004179 }
4180
4181 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004182 synchronized (this) {
4183 return mProcessLimitOverride;
4184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 }
4186
4187 void foregroundTokenDied(ForegroundToken token) {
4188 synchronized (ActivityManagerService.this) {
4189 synchronized (mPidsSelfLocked) {
4190 ForegroundToken cur
4191 = mForegroundProcesses.get(token.pid);
4192 if (cur != token) {
4193 return;
4194 }
4195 mForegroundProcesses.remove(token.pid);
4196 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4197 if (pr == null) {
4198 return;
4199 }
4200 pr.forcingToForeground = null;
4201 pr.foregroundServices = false;
4202 }
4203 updateOomAdjLocked();
4204 }
4205 }
4206
4207 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4208 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4209 "setProcessForeground()");
4210 synchronized(this) {
4211 boolean changed = false;
4212
4213 synchronized (mPidsSelfLocked) {
4214 ProcessRecord pr = mPidsSelfLocked.get(pid);
4215 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004216 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 return;
4218 }
4219 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4220 if (oldToken != null) {
4221 oldToken.token.unlinkToDeath(oldToken, 0);
4222 mForegroundProcesses.remove(pid);
4223 pr.forcingToForeground = null;
4224 changed = true;
4225 }
4226 if (isForeground && token != null) {
4227 ForegroundToken newToken = new ForegroundToken() {
4228 public void binderDied() {
4229 foregroundTokenDied(this);
4230 }
4231 };
4232 newToken.pid = pid;
4233 newToken.token = token;
4234 try {
4235 token.linkToDeath(newToken, 0);
4236 mForegroundProcesses.put(pid, newToken);
4237 pr.forcingToForeground = token;
4238 changed = true;
4239 } catch (RemoteException e) {
4240 // If the process died while doing this, we will later
4241 // do the cleanup with the process death link.
4242 }
4243 }
4244 }
4245
4246 if (changed) {
4247 updateOomAdjLocked();
4248 }
4249 }
4250 }
4251
4252 // =========================================================
4253 // PERMISSIONS
4254 // =========================================================
4255
4256 static class PermissionController extends IPermissionController.Stub {
4257 ActivityManagerService mActivityManagerService;
4258 PermissionController(ActivityManagerService activityManagerService) {
4259 mActivityManagerService = activityManagerService;
4260 }
4261
4262 public boolean checkPermission(String permission, int pid, int uid) {
4263 return mActivityManagerService.checkPermission(permission, pid,
4264 uid) == PackageManager.PERMISSION_GRANTED;
4265 }
4266 }
4267
4268 /**
4269 * This can be called with or without the global lock held.
4270 */
4271 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004272 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 // We might be performing an operation on behalf of an indirect binder
4274 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4275 // client identity accordingly before proceeding.
4276 Identity tlsIdentity = sCallerIdentity.get();
4277 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004278 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4280 uid = tlsIdentity.uid;
4281 pid = tlsIdentity.pid;
4282 }
4283
4284 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004285 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 return PackageManager.PERMISSION_GRANTED;
4287 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004288 // If there is a uid that owns whatever is being accessed, it has
4289 // blanket access to it regardless of the permissions it requires.
4290 if (owningUid >= 0 && uid == owningUid) {
4291 return PackageManager.PERMISSION_GRANTED;
4292 }
4293 // If the target is not exported, then nobody else can get to it.
4294 if (!exported) {
4295 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 return PackageManager.PERMISSION_DENIED;
4297 }
4298 if (permission == null) {
4299 return PackageManager.PERMISSION_GRANTED;
4300 }
4301 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004302 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 .checkUidPermission(permission, uid);
4304 } catch (RemoteException e) {
4305 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004306 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 }
4308 return PackageManager.PERMISSION_DENIED;
4309 }
4310
4311 /**
4312 * As the only public entry point for permissions checking, this method
4313 * can enforce the semantic that requesting a check on a null global
4314 * permission is automatically denied. (Internally a null permission
4315 * string is used when calling {@link #checkComponentPermission} in cases
4316 * when only uid-based security is needed.)
4317 *
4318 * This can be called with or without the global lock held.
4319 */
4320 public int checkPermission(String permission, int pid, int uid) {
4321 if (permission == null) {
4322 return PackageManager.PERMISSION_DENIED;
4323 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004324 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 }
4326
4327 /**
4328 * Binder IPC calls go through the public entry point.
4329 * This can be called with or without the global lock held.
4330 */
4331 int checkCallingPermission(String permission) {
4332 return checkPermission(permission,
4333 Binder.getCallingPid(),
4334 Binder.getCallingUid());
4335 }
4336
4337 /**
4338 * This can be called with or without the global lock held.
4339 */
4340 void enforceCallingPermission(String permission, String func) {
4341 if (checkCallingPermission(permission)
4342 == PackageManager.PERMISSION_GRANTED) {
4343 return;
4344 }
4345
4346 String msg = "Permission Denial: " + func + " from pid="
4347 + Binder.getCallingPid()
4348 + ", uid=" + Binder.getCallingUid()
4349 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004350 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 throw new SecurityException(msg);
4352 }
4353
4354 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004355 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4356 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4357 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4358 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4359 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004361 // Is the component private from the target uid?
4362 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4363
4364 // Acceptable if the there is no read permission needed from the
4365 // target or the target is holding the read permission.
4366 if (!readPerm) {
4367 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004368 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004369 == PackageManager.PERMISSION_GRANTED)) {
4370 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 }
4372 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004373
4374 // Acceptable if the there is no write permission needed from the
4375 // target or the target is holding the read permission.
4376 if (!writePerm) {
4377 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004378 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004379 == PackageManager.PERMISSION_GRANTED)) {
4380 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 }
4382 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004383
4384 // Acceptable if there is a path permission matching the URI that
4385 // the target holds the permission on.
4386 PathPermission[] pps = pi.pathPermissions;
4387 if (pps != null && (!readPerm || !writePerm)) {
4388 final String path = uri.getPath();
4389 int i = pps.length;
4390 while (i > 0 && (!readPerm || !writePerm)) {
4391 i--;
4392 PathPermission pp = pps[i];
4393 if (!readPerm) {
4394 final String pprperm = pp.getReadPermission();
4395 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4396 + pprperm + " for " + pp.getPath()
4397 + ": match=" + pp.match(path)
4398 + " check=" + pm.checkUidPermission(pprperm, uid));
4399 if (pprperm != null && pp.match(path) &&
4400 (pm.checkUidPermission(pprperm, uid)
4401 == PackageManager.PERMISSION_GRANTED)) {
4402 readPerm = true;
4403 }
4404 }
4405 if (!writePerm) {
4406 final String ppwperm = pp.getWritePermission();
4407 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4408 + ppwperm + " for " + pp.getPath()
4409 + ": match=" + pp.match(path)
4410 + " check=" + pm.checkUidPermission(ppwperm, uid));
4411 if (ppwperm != null && pp.match(path) &&
4412 (pm.checkUidPermission(ppwperm, uid)
4413 == PackageManager.PERMISSION_GRANTED)) {
4414 writePerm = true;
4415 }
4416 }
4417 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 } catch (RemoteException e) {
4420 return false;
4421 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004422
4423 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 }
4425
4426 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4427 int modeFlags) {
4428 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004429 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 return true;
4431 }
4432 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4433 if (perms == null) return false;
4434 UriPermission perm = perms.get(uri);
4435 if (perm == null) return false;
4436 return (modeFlags&perm.modeFlags) == modeFlags;
4437 }
4438
4439 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4440 // Another redirected-binder-call permissions check as in
4441 // {@link checkComponentPermission}.
4442 Identity tlsIdentity = sCallerIdentity.get();
4443 if (tlsIdentity != null) {
4444 uid = tlsIdentity.uid;
4445 pid = tlsIdentity.pid;
4446 }
4447
4448 // Our own process gets to do everything.
4449 if (pid == MY_PID) {
4450 return PackageManager.PERMISSION_GRANTED;
4451 }
4452 synchronized(this) {
4453 return checkUriPermissionLocked(uri, uid, modeFlags)
4454 ? PackageManager.PERMISSION_GRANTED
4455 : PackageManager.PERMISSION_DENIED;
4456 }
4457 }
4458
Dianne Hackborn39792d22010-08-19 18:01:52 -07004459 /**
4460 * Check if the targetPkg can be granted permission to access uri by
4461 * the callingUid using the given modeFlags. Throws a security exception
4462 * if callingUid is not allowed to do this. Returns the uid of the target
4463 * if the URI permission grant should be performed; returns -1 if it is not
4464 * needed (for example targetPkg already has permission to access the URI).
4465 */
4466 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4467 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4469 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4470 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004471 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 }
4473
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004474 if (targetPkg != null) {
4475 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4476 "Checking grant " + targetPkg + " permission to " + uri);
4477 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004478
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004479 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004480
4481 // If this is not a content: uri, we can't do anything with it.
4482 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004483 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004484 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004485 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 }
4487
4488 String name = uri.getAuthority();
4489 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004490 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 if (cpr != null) {
4492 pi = cpr.info;
4493 } else {
4494 try {
4495 pi = pm.resolveContentProvider(name,
4496 PackageManager.GET_URI_PERMISSION_PATTERNS);
4497 } catch (RemoteException ex) {
4498 }
4499 }
4500 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004501 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004502 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 }
4504
4505 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004506 if (targetPkg != null) {
4507 try {
4508 targetUid = pm.getPackageUid(targetPkg);
4509 if (targetUid < 0) {
4510 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4511 "Can't grant URI permission no uid for: " + targetPkg);
4512 return -1;
4513 }
4514 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004515 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004517 } else {
4518 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 }
4520
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004521 if (targetUid >= 0) {
4522 // First... does the target actually need this permission?
4523 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4524 // No need to grant the target this permission.
4525 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4526 "Target " + targetPkg + " already has full permission to " + uri);
4527 return -1;
4528 }
4529 } else {
4530 // First... there is no target package, so can anyone access it?
4531 boolean allowed = pi.exported;
4532 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4533 if (pi.readPermission != null) {
4534 allowed = false;
4535 }
4536 }
4537 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4538 if (pi.writePermission != null) {
4539 allowed = false;
4540 }
4541 }
4542 if (allowed) {
4543 return -1;
4544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 }
4546
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004547 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004548 if (!pi.grantUriPermissions) {
4549 throw new SecurityException("Provider " + pi.packageName
4550 + "/" + pi.name
4551 + " does not allow granting of Uri permissions (uri "
4552 + uri + ")");
4553 }
4554 if (pi.uriPermissionPatterns != null) {
4555 final int N = pi.uriPermissionPatterns.length;
4556 boolean allowed = false;
4557 for (int i=0; i<N; i++) {
4558 if (pi.uriPermissionPatterns[i] != null
4559 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4560 allowed = true;
4561 break;
4562 }
4563 }
4564 if (!allowed) {
4565 throw new SecurityException("Provider " + pi.packageName
4566 + "/" + pi.name
4567 + " does not allow granting of permission to path of Uri "
4568 + uri);
4569 }
4570 }
4571
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004572 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004574 if (callingUid != Process.myUid()) {
4575 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4576 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4577 throw new SecurityException("Uid " + callingUid
4578 + " does not have permission to uri " + uri);
4579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 }
4581 }
4582
Dianne Hackborn39792d22010-08-19 18:01:52 -07004583 return targetUid;
4584 }
4585
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004586 public int checkGrantUriPermission(int callingUid, String targetPkg,
4587 Uri uri, int modeFlags) {
4588 synchronized(this) {
4589 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4590 }
4591 }
4592
Dianne Hackborn39792d22010-08-19 18:01:52 -07004593 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4594 Uri uri, int modeFlags, UriPermissionOwner owner) {
4595 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4596 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4597 if (modeFlags == 0) {
4598 return;
4599 }
4600
4601 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 // to the uri, and the target doesn't. Let's now give this to
4603 // the target.
4604
Joe Onorato8a9b2202010-02-26 18:56:32 -08004605 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004606 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004608 HashMap<Uri, UriPermission> targetUris
4609 = mGrantedUriPermissions.get(targetUid);
4610 if (targetUris == null) {
4611 targetUris = new HashMap<Uri, UriPermission>();
4612 mGrantedUriPermissions.put(targetUid, targetUris);
4613 }
4614
4615 UriPermission perm = targetUris.get(uri);
4616 if (perm == null) {
4617 perm = new UriPermission(targetUid, uri);
4618 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004622 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004624 } else {
4625 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4626 perm.readOwners.add(owner);
4627 owner.addReadPermission(perm);
4628 }
4629 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4630 perm.writeOwners.add(owner);
4631 owner.addWritePermission(perm);
4632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 }
4634 }
4635
Dianne Hackborn39792d22010-08-19 18:01:52 -07004636 void grantUriPermissionLocked(int callingUid,
4637 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004638 if (targetPkg == null) {
4639 throw new NullPointerException("targetPkg");
4640 }
4641
Dianne Hackborn39792d22010-08-19 18:01:52 -07004642 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4643 if (targetUid < 0) {
4644 return;
4645 }
4646
4647 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4648 }
4649
4650 /**
4651 * Like checkGrantUriPermissionLocked, but takes an Intent.
4652 */
4653 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4654 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004655 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004656 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004657 + " from " + intent + "; flags=0x"
4658 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4659
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004660 if (targetPkg == null) {
4661 throw new NullPointerException("targetPkg");
4662 }
4663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004665 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 }
4667 Uri data = intent.getData();
4668 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004669 return -1;
4670 }
4671 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4672 intent.getFlags());
4673 }
4674
4675 /**
4676 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4677 */
4678 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4679 String targetPkg, Intent intent, UriPermissionOwner owner) {
4680 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4681 intent.getFlags(), owner);
4682 }
4683
4684 void grantUriPermissionFromIntentLocked(int callingUid,
4685 String targetPkg, Intent intent, UriPermissionOwner owner) {
4686 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4687 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 return;
4689 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004690
4691 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004692 }
4693
4694 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4695 Uri uri, int modeFlags) {
4696 synchronized(this) {
4697 final ProcessRecord r = getRecordForAppLocked(caller);
4698 if (r == null) {
4699 throw new SecurityException("Unable to find app for caller "
4700 + caller
4701 + " when granting permission to uri " + uri);
4702 }
4703 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004704 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 }
4706 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004707 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 }
4709
4710 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4711 null);
4712 }
4713 }
4714
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004715 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004716 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4717 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4718 HashMap<Uri, UriPermission> perms
4719 = mGrantedUriPermissions.get(perm.uid);
4720 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004721 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004722 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 perms.remove(perm.uri);
4724 if (perms.size() == 0) {
4725 mGrantedUriPermissions.remove(perm.uid);
4726 }
4727 }
4728 }
4729 }
4730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4732 int modeFlags) {
4733 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4734 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4735 if (modeFlags == 0) {
4736 return;
4737 }
4738
Joe Onorato8a9b2202010-02-26 18:56:32 -08004739 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004740 "Revoking all granted permissions to " + uri);
4741
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004742 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743
4744 final String authority = uri.getAuthority();
4745 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004746 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 if (cpr != null) {
4748 pi = cpr.info;
4749 } else {
4750 try {
4751 pi = pm.resolveContentProvider(authority,
4752 PackageManager.GET_URI_PERMISSION_PATTERNS);
4753 } catch (RemoteException ex) {
4754 }
4755 }
4756 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004757 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 return;
4759 }
4760
4761 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004762 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 // Right now, if you are not the original owner of the permission,
4764 // you are not allowed to revoke it.
4765 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4766 throw new SecurityException("Uid " + callingUid
4767 + " does not have permission to uri " + uri);
4768 //}
4769 }
4770
4771 // Go through all of the permissions and remove any that match.
4772 final List<String> SEGMENTS = uri.getPathSegments();
4773 if (SEGMENTS != null) {
4774 final int NS = SEGMENTS.size();
4775 int N = mGrantedUriPermissions.size();
4776 for (int i=0; i<N; i++) {
4777 HashMap<Uri, UriPermission> perms
4778 = mGrantedUriPermissions.valueAt(i);
4779 Iterator<UriPermission> it = perms.values().iterator();
4780 toploop:
4781 while (it.hasNext()) {
4782 UriPermission perm = it.next();
4783 Uri targetUri = perm.uri;
4784 if (!authority.equals(targetUri.getAuthority())) {
4785 continue;
4786 }
4787 List<String> targetSegments = targetUri.getPathSegments();
4788 if (targetSegments == null) {
4789 continue;
4790 }
4791 if (targetSegments.size() < NS) {
4792 continue;
4793 }
4794 for (int j=0; j<NS; j++) {
4795 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4796 continue toploop;
4797 }
4798 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004799 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004800 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004801 perm.clearModes(modeFlags);
4802 if (perm.modeFlags == 0) {
4803 it.remove();
4804 }
4805 }
4806 if (perms.size() == 0) {
4807 mGrantedUriPermissions.remove(
4808 mGrantedUriPermissions.keyAt(i));
4809 N--;
4810 i--;
4811 }
4812 }
4813 }
4814 }
4815
4816 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4817 int modeFlags) {
4818 synchronized(this) {
4819 final ProcessRecord r = getRecordForAppLocked(caller);
4820 if (r == null) {
4821 throw new SecurityException("Unable to find app for caller "
4822 + caller
4823 + " when revoking permission to uri " + uri);
4824 }
4825 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004826 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 return;
4828 }
4829
4830 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4831 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4832 if (modeFlags == 0) {
4833 return;
4834 }
4835
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004836 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004837
4838 final String authority = uri.getAuthority();
4839 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004840 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004841 if (cpr != null) {
4842 pi = cpr.info;
4843 } else {
4844 try {
4845 pi = pm.resolveContentProvider(authority,
4846 PackageManager.GET_URI_PERMISSION_PATTERNS);
4847 } catch (RemoteException ex) {
4848 }
4849 }
4850 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004851 Slog.w(TAG, "No content provider found for permission revoke: "
4852 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004853 return;
4854 }
4855
4856 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4857 }
4858 }
4859
Dianne Hackborn7e269642010-08-25 19:50:20 -07004860 @Override
4861 public IBinder newUriPermissionOwner(String name) {
4862 synchronized(this) {
4863 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4864 return owner.getExternalTokenLocked();
4865 }
4866 }
4867
4868 @Override
4869 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4870 Uri uri, int modeFlags) {
4871 synchronized(this) {
4872 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4873 if (owner == null) {
4874 throw new IllegalArgumentException("Unknown owner: " + token);
4875 }
4876 if (fromUid != Binder.getCallingUid()) {
4877 if (Binder.getCallingUid() != Process.myUid()) {
4878 // Only system code can grant URI permissions on behalf
4879 // of other users.
4880 throw new SecurityException("nice try");
4881 }
4882 }
4883 if (targetPkg == null) {
4884 throw new IllegalArgumentException("null target");
4885 }
4886 if (uri == null) {
4887 throw new IllegalArgumentException("null uri");
4888 }
4889
4890 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4891 }
4892 }
4893
4894 @Override
4895 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4896 synchronized(this) {
4897 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4898 if (owner == null) {
4899 throw new IllegalArgumentException("Unknown owner: " + token);
4900 }
4901
4902 if (uri == null) {
4903 owner.removeUriPermissionsLocked(mode);
4904 } else {
4905 owner.removeUriPermissionLocked(uri, mode);
4906 }
4907 }
4908 }
4909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4911 synchronized (this) {
4912 ProcessRecord app =
4913 who != null ? getRecordForAppLocked(who) : null;
4914 if (app == null) return;
4915
4916 Message msg = Message.obtain();
4917 msg.what = WAIT_FOR_DEBUGGER_MSG;
4918 msg.obj = app;
4919 msg.arg1 = waiting ? 1 : 0;
4920 mHandler.sendMessage(msg);
4921 }
4922 }
4923
4924 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004925 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4926 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004928 outInfo.threshold = homeAppMem;
4929 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4930 outInfo.hiddenAppThreshold = hiddenAppMem;
4931 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07004932 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07004933 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4934 ProcessList.VISIBLE_APP_ADJ);
4935 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4936 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004937 }
4938
4939 // =========================================================
4940 // TASK MANAGEMENT
4941 // =========================================================
4942
4943 public List getTasks(int maxNum, int flags,
4944 IThumbnailReceiver receiver) {
4945 ArrayList list = new ArrayList();
4946
4947 PendingThumbnailsRecord pending = null;
4948 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004949 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950
4951 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004952 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4954 + ", receiver=" + receiver);
4955
4956 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4957 != PackageManager.PERMISSION_GRANTED) {
4958 if (receiver != null) {
4959 // If the caller wants to wait for pending thumbnails,
4960 // it ain't gonna get them.
4961 try {
4962 receiver.finished();
4963 } catch (RemoteException ex) {
4964 }
4965 }
4966 String msg = "Permission Denial: getTasks() from pid="
4967 + Binder.getCallingPid()
4968 + ", uid=" + Binder.getCallingUid()
4969 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004970 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 throw new SecurityException(msg);
4972 }
4973
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004974 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004975 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004976 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004977 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978 TaskRecord curTask = null;
4979 int numActivities = 0;
4980 int numRunning = 0;
4981 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004982 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004983 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004984 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985
4986 // Initialize state for next task if needed.
4987 if (top == null ||
4988 (top.state == ActivityState.INITIALIZING
4989 && top.task == r.task)) {
4990 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004991 curTask = r.task;
4992 numActivities = numRunning = 0;
4993 }
4994
4995 // Add 'r' into the current task.
4996 numActivities++;
4997 if (r.app != null && r.app.thread != null) {
4998 numRunning++;
4999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000
Joe Onorato8a9b2202010-02-26 18:56:32 -08005001 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 TAG, r.intent.getComponent().flattenToShortString()
5003 + ": task=" + r.task);
5004
5005 // If the next one is a different task, generate a new
5006 // TaskInfo entry for what we have.
5007 if (next == null || next.task != curTask) {
5008 ActivityManager.RunningTaskInfo ci
5009 = new ActivityManager.RunningTaskInfo();
5010 ci.id = curTask.taskId;
5011 ci.baseActivity = r.intent.getComponent();
5012 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005013 if (top.thumbHolder != null) {
5014 ci.description = top.thumbHolder.lastDescription;
5015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005016 ci.numActivities = numActivities;
5017 ci.numRunning = numRunning;
5018 //System.out.println(
5019 // "#" + maxNum + ": " + " descr=" + ci.description);
5020 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005021 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005022 TAG, "State=" + top.state + "Idle=" + top.idle
5023 + " app=" + top.app
5024 + " thr=" + (top.app != null ? top.app.thread : null));
5025 if (top.state == ActivityState.RESUMED
5026 || top.state == ActivityState.PAUSING) {
5027 if (top.idle && top.app != null
5028 && top.app.thread != null) {
5029 topRecord = top;
5030 topThumbnail = top.app.thread;
5031 } else {
5032 top.thumbnailNeeded = true;
5033 }
5034 }
5035 if (pending == null) {
5036 pending = new PendingThumbnailsRecord(receiver);
5037 }
5038 pending.pendingRecords.add(top);
5039 }
5040 list.add(ci);
5041 maxNum--;
5042 top = null;
5043 }
5044 }
5045
5046 if (pending != null) {
5047 mPendingThumbnails.add(pending);
5048 }
5049 }
5050
Joe Onorato8a9b2202010-02-26 18:56:32 -08005051 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052
5053 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005054 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 try {
5056 topThumbnail.requestThumbnail(topRecord);
5057 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005058 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059 sendPendingThumbnail(null, topRecord, null, null, true);
5060 }
5061 }
5062
5063 if (pending == null && receiver != null) {
5064 // In this case all thumbnails were available and the client
5065 // is being asked to be told when the remaining ones come in...
5066 // which is unusually, since the top-most currently running
5067 // activity should never have a canned thumbnail! Oh well.
5068 try {
5069 receiver.finished();
5070 } catch (RemoteException ex) {
5071 }
5072 }
5073
5074 return list;
5075 }
5076
5077 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5078 int flags) {
5079 synchronized (this) {
5080 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5081 "getRecentTasks()");
5082
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005083 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085 final int N = mRecentTasks.size();
5086 ArrayList<ActivityManager.RecentTaskInfo> res
5087 = new ArrayList<ActivityManager.RecentTaskInfo>(
5088 maxNum < N ? maxNum : N);
5089 for (int i=0; i<N && maxNum > 0; i++) {
5090 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005091 // Return the entry if desired by the caller. We always return
5092 // the first entry, because callers always expect this to be the
5093 // forground app. We may filter others if the caller has
5094 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5095 // we should exclude the entry.
5096 if (i == 0
5097 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005098 || (tr.intent == null)
5099 || ((tr.intent.getFlags()
5100 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5101 ActivityManager.RecentTaskInfo rti
5102 = new ActivityManager.RecentTaskInfo();
5103 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005104 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005105 rti.baseIntent = new Intent(
5106 tr.intent != null ? tr.intent : tr.affinityIntent);
5107 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005108 rti.description = tr.lastDescription;
5109
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005110 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5111 // Check whether this activity is currently available.
5112 try {
5113 if (rti.origActivity != null) {
5114 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5115 continue;
5116 }
5117 } else if (rti.baseIntent != null) {
5118 if (pm.queryIntentActivities(rti.baseIntent,
5119 null, 0) == null) {
5120 continue;
5121 }
5122 }
5123 } catch (RemoteException e) {
5124 // Will never happen.
5125 }
5126 }
5127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128 res.add(rti);
5129 maxNum--;
5130 }
5131 }
5132 return res;
5133 }
5134 }
5135
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005136 private TaskRecord taskForIdLocked(int id) {
5137 final int N = mRecentTasks.size();
5138 for (int i=0; i<N; i++) {
5139 TaskRecord tr = mRecentTasks.get(i);
5140 if (tr.taskId == id) {
5141 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005142 }
5143 }
5144 return null;
5145 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005146
5147 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5148 synchronized (this) {
5149 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5150 "getTaskThumbnails()");
5151 TaskRecord tr = taskForIdLocked(id);
5152 if (tr != null) {
5153 return mMainStack.getTaskThumbnailsLocked(tr);
5154 }
5155 }
5156 return null;
5157 }
5158
5159 public boolean removeSubTask(int taskId, int subTaskIndex) {
5160 synchronized (this) {
5161 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5162 "removeSubTask()");
5163 long ident = Binder.clearCallingIdentity();
5164 try {
5165 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5166 } finally {
5167 Binder.restoreCallingIdentity(ident);
5168 }
5169 }
5170 }
5171
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005172 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005173 TaskRecord tr = root.task;
5174 Intent baseIntent = new Intent(
5175 tr.intent != null ? tr.intent : tr.affinityIntent);
5176 ComponentName component = baseIntent.getComponent();
5177 if (component == null) {
5178 Slog.w(TAG, "Now component for base intent of task: " + tr);
5179 return;
5180 }
5181
5182 // Find any running services associated with this app.
5183 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5184 for (ServiceRecord sr : mServices.values()) {
5185 if (sr.packageName.equals(component.getPackageName())) {
5186 services.add(sr);
5187 }
5188 }
5189
5190 // Take care of any running services associated with the app.
5191 for (int i=0; i<services.size(); i++) {
5192 ServiceRecord sr = services.get(i);
5193 if (sr.startRequested) {
5194 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005195 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005196 stopServiceLocked(sr);
5197 } else {
5198 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5199 sr.makeNextStartId(), baseIntent, -1));
5200 if (sr.app != null && sr.app.thread != null) {
5201 sendServiceArgsLocked(sr, false);
5202 }
5203 }
5204 }
5205 }
5206
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005207 if (killProcesses) {
5208 // Find any running processes associated with this app.
5209 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5210 SparseArray<ProcessRecord> appProcs
5211 = mProcessNames.getMap().get(component.getPackageName());
5212 if (appProcs != null) {
5213 for (int i=0; i<appProcs.size(); i++) {
5214 procs.add(appProcs.valueAt(i));
5215 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005216 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005217
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005218 // Kill the running processes.
5219 for (int i=0; i<procs.size(); i++) {
5220 ProcessRecord pr = procs.get(i);
5221 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5222 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5223 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5224 pr.processName, pr.setAdj, "remove task");
5225 Process.killProcessQuiet(pr.pid);
5226 } else {
5227 pr.waitingToKill = "remove task";
5228 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005229 }
5230 }
5231 }
5232
5233 public boolean removeTask(int taskId, int flags) {
5234 synchronized (this) {
5235 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5236 "removeTask()");
5237 long ident = Binder.clearCallingIdentity();
5238 try {
5239 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5240 if (r != null) {
5241 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005242 cleanUpRemovedTaskLocked(r,
5243 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005244 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005245 } else {
5246 TaskRecord tr = null;
5247 int i=0;
5248 while (i < mRecentTasks.size()) {
5249 TaskRecord t = mRecentTasks.get(i);
5250 if (t.taskId == taskId) {
5251 tr = t;
5252 break;
5253 }
5254 i++;
5255 }
5256 if (tr != null) {
5257 if (tr.numActivities <= 0) {
5258 // Caller is just removing a recent task that is
5259 // not actively running. That is easy!
5260 mRecentTasks.remove(i);
5261 } else {
5262 Slog.w(TAG, "removeTask: task " + taskId
5263 + " does not have activities to remove, "
5264 + " but numActivities=" + tr.numActivities
5265 + ": " + tr);
5266 }
5267 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005268 }
5269 } finally {
5270 Binder.restoreCallingIdentity(ident);
5271 }
5272 }
5273 return false;
5274 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5277 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005278 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 TaskRecord jt = startTask;
5280
5281 // First look backwards
5282 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005283 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005284 if (r.task != jt) {
5285 jt = r.task;
5286 if (affinity.equals(jt.affinity)) {
5287 return j;
5288 }
5289 }
5290 }
5291
5292 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005293 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 jt = startTask;
5295 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005296 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 if (r.task != jt) {
5298 if (affinity.equals(jt.affinity)) {
5299 return j;
5300 }
5301 jt = r.task;
5302 }
5303 }
5304
5305 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005306 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 return N-1;
5308 }
5309
5310 return -1;
5311 }
5312
5313 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005314 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005316 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5318 "moveTaskToFront()");
5319
5320 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005321 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5322 Binder.getCallingUid(), "Task to front")) {
5323 return;
5324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005325 final long origId = Binder.clearCallingIdentity();
5326 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005327 TaskRecord tr = taskForIdLocked(task);
5328 if (tr != null) {
5329 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5330 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005332 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5333 // Caller wants the home activity moved with it. To accomplish this,
5334 // we'll just move the home task to the top first.
5335 mMainStack.moveHomeToFrontLocked();
5336 }
5337 mMainStack.moveTaskToFrontLocked(tr, null);
5338 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005339 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005340 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5341 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005343 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5344 mMainStack.mUserLeaving = true;
5345 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005346 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5347 // Caller wants the home activity moved with it. To accomplish this,
5348 // we'll just move the home task to the top first.
5349 mMainStack.moveHomeToFrontLocked();
5350 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005351 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005352 return;
5353 }
5354 }
5355 } finally {
5356 Binder.restoreCallingIdentity(origId);
5357 }
5358 }
5359 }
5360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005361 public void moveTaskToBack(int task) {
5362 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5363 "moveTaskToBack()");
5364
5365 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005366 if (mMainStack.mResumedActivity != null
5367 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005368 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5369 Binder.getCallingUid(), "Task to back")) {
5370 return;
5371 }
5372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005373 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005374 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 Binder.restoreCallingIdentity(origId);
5376 }
5377 }
5378
5379 /**
5380 * Moves an activity, and all of the other activities within the same task, to the bottom
5381 * of the history stack. The activity's order within the task is unchanged.
5382 *
5383 * @param token A reference to the activity we wish to move
5384 * @param nonRoot If false then this only works if the activity is the root
5385 * of a task; if true it will work for any activity in a task.
5386 * @return Returns true if the move completed, false if not.
5387 */
5388 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5389 synchronized(this) {
5390 final long origId = Binder.clearCallingIdentity();
5391 int taskId = getTaskForActivityLocked(token, !nonRoot);
5392 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005393 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005394 }
5395 Binder.restoreCallingIdentity(origId);
5396 }
5397 return false;
5398 }
5399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 public void moveTaskBackwards(int task) {
5401 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5402 "moveTaskBackwards()");
5403
5404 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005405 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5406 Binder.getCallingUid(), "Task backwards")) {
5407 return;
5408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 final long origId = Binder.clearCallingIdentity();
5410 moveTaskBackwardsLocked(task);
5411 Binder.restoreCallingIdentity(origId);
5412 }
5413 }
5414
5415 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005416 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 }
5418
5419 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5420 synchronized(this) {
5421 return getTaskForActivityLocked(token, onlyRoot);
5422 }
5423 }
5424
5425 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005426 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 TaskRecord lastTask = null;
5428 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005429 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005430 if (r == token) {
5431 if (!onlyRoot || lastTask != r.task) {
5432 return r.task.taskId;
5433 }
5434 return -1;
5435 }
5436 lastTask = r.task;
5437 }
5438
5439 return -1;
5440 }
5441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005442 public void finishOtherInstances(IBinder token, ComponentName className) {
5443 synchronized(this) {
5444 final long origId = Binder.clearCallingIdentity();
5445
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005446 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005447 TaskRecord lastTask = null;
5448 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005449 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 if (r.realActivity.equals(className)
5451 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005452 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005453 null, "others")) {
5454 i--;
5455 N--;
5456 }
5457 }
5458 lastTask = r.task;
5459 }
5460
5461 Binder.restoreCallingIdentity(origId);
5462 }
5463 }
5464
5465 // =========================================================
5466 // THUMBNAILS
5467 // =========================================================
5468
5469 public void reportThumbnail(IBinder token,
5470 Bitmap thumbnail, CharSequence description) {
5471 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5472 final long origId = Binder.clearCallingIdentity();
5473 sendPendingThumbnail(null, token, thumbnail, description, true);
5474 Binder.restoreCallingIdentity(origId);
5475 }
5476
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005477 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005478 Bitmap thumbnail, CharSequence description, boolean always) {
5479 TaskRecord task = null;
5480 ArrayList receivers = null;
5481
5482 //System.out.println("Send pending thumbnail: " + r);
5483
5484 synchronized(this) {
5485 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005486 r = mMainStack.isInStackLocked(token);
5487 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005488 return;
5489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005490 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005491 if (thumbnail == null && r.thumbHolder != null) {
5492 thumbnail = r.thumbHolder.lastThumbnail;
5493 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005494 }
5495 if (thumbnail == null && !always) {
5496 // If there is no thumbnail, and this entry is not actually
5497 // going away, then abort for now and pick up the next
5498 // thumbnail we get.
5499 return;
5500 }
5501 task = r.task;
5502
5503 int N = mPendingThumbnails.size();
5504 int i=0;
5505 while (i<N) {
5506 PendingThumbnailsRecord pr =
5507 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5508 //System.out.println("Looking in " + pr.pendingRecords);
5509 if (pr.pendingRecords.remove(r)) {
5510 if (receivers == null) {
5511 receivers = new ArrayList();
5512 }
5513 receivers.add(pr);
5514 if (pr.pendingRecords.size() == 0) {
5515 pr.finished = true;
5516 mPendingThumbnails.remove(i);
5517 N--;
5518 continue;
5519 }
5520 }
5521 i++;
5522 }
5523 }
5524
5525 if (receivers != null) {
5526 final int N = receivers.size();
5527 for (int i=0; i<N; i++) {
5528 try {
5529 PendingThumbnailsRecord pr =
5530 (PendingThumbnailsRecord)receivers.get(i);
5531 pr.receiver.newThumbnail(
5532 task != null ? task.taskId : -1, thumbnail, description);
5533 if (pr.finished) {
5534 pr.receiver.finished();
5535 }
5536 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005537 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
5539 }
5540 }
5541 }
5542
5543 // =========================================================
5544 // CONTENT PROVIDERS
5545 // =========================================================
5546
Jeff Brown10e89712011-07-08 18:52:57 -07005547 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5548 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005549 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005550 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005552 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005553 } catch (RemoteException ex) {
5554 }
5555 if (providers != null) {
5556 final int N = providers.size();
5557 for (int i=0; i<N; i++) {
5558 ProviderInfo cpi =
5559 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005560 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5561 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005563 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005564 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005565 }
5566 app.pubProviders.put(cpi.name, cpr);
5567 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005568 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 }
5570 }
5571 return providers;
5572 }
5573
5574 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005575 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005576 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5577 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5578 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005579 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005580 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 return null;
5582 }
5583 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005584 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005585 == PackageManager.PERMISSION_GRANTED) {
5586 return null;
5587 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005588
5589 PathPermission[] pps = cpi.pathPermissions;
5590 if (pps != null) {
5591 int i = pps.length;
5592 while (i > 0) {
5593 i--;
5594 PathPermission pp = pps[i];
5595 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005596 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005597 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005598 return null;
5599 }
5600 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005601 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005602 == PackageManager.PERMISSION_GRANTED) {
5603 return null;
5604 }
5605 }
5606 }
5607
Dianne Hackbornb424b632010-08-18 15:59:05 -07005608 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5609 if (perms != null) {
5610 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5611 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5612 return null;
5613 }
5614 }
5615 }
5616
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005617 String msg;
5618 if (!cpi.exported) {
5619 msg = "Permission Denial: opening provider " + cpi.name
5620 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5621 + ", uid=" + callingUid + ") that is not exported from uid "
5622 + cpi.applicationInfo.uid;
5623 } else {
5624 msg = "Permission Denial: opening provider " + cpi.name
5625 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5626 + ", uid=" + callingUid + ") requires "
5627 + cpi.readPermission + " or " + cpi.writePermission;
5628 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005629 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 return msg;
5631 }
5632
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005633 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5634 if (r != null) {
5635 Integer cnt = r.conProviders.get(cpr);
5636 if (DEBUG_PROVIDER) Slog.v(TAG,
5637 "Adding provider requested by "
5638 + r.processName + " from process "
5639 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5640 + " cnt=" + (cnt == null ? 1 : cnt));
5641 if (cnt == null) {
5642 cpr.clients.add(r);
5643 r.conProviders.put(cpr, new Integer(1));
5644 return true;
5645 } else {
5646 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5647 }
5648 } else {
5649 cpr.externals++;
5650 }
5651 return false;
5652 }
5653
5654 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5655 if (r != null) {
5656 Integer cnt = r.conProviders.get(cpr);
5657 if (DEBUG_PROVIDER) Slog.v(TAG,
5658 "Removing provider requested by "
5659 + r.processName + " from process "
5660 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5661 + " cnt=" + cnt);
5662 if (cnt == null || cnt.intValue() <= 1) {
5663 cpr.clients.remove(r);
5664 r.conProviders.remove(cpr);
5665 return true;
5666 } else {
5667 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5668 }
5669 } else {
5670 cpr.externals++;
5671 }
5672 return false;
5673 }
5674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 private final ContentProviderHolder getContentProviderImpl(
5676 IApplicationThread caller, String name) {
5677 ContentProviderRecord cpr;
5678 ProviderInfo cpi = null;
5679
5680 synchronized(this) {
5681 ProcessRecord r = null;
5682 if (caller != null) {
5683 r = getRecordForAppLocked(caller);
5684 if (r == null) {
5685 throw new SecurityException(
5686 "Unable to find app for caller " + caller
5687 + " (pid=" + Binder.getCallingPid()
5688 + ") when getting content provider " + name);
5689 }
5690 }
5691
5692 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005693 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005694 boolean providerRunning = cpr != null;
5695 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005697 String msg;
5698 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5699 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005700 }
5701
5702 if (r != null && cpr.canRunHere(r)) {
5703 // This provider has been published or is in the process
5704 // of being published... but it is also allowed to run
5705 // in the caller's process, so don't make a connection
5706 // and just let the caller instantiate its own instance.
5707 if (cpr.provider != null) {
5708 // don't give caller the provider object, it needs
5709 // to make its own.
5710 cpr = new ContentProviderRecord(cpr);
5711 }
5712 return cpr;
5713 }
5714
5715 final long origId = Binder.clearCallingIdentity();
5716
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005717 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005719 final boolean countChanged = incProviderCount(r, cpr);
5720 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005721 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005722 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005723 // make sure to count it as being accessed and thus
5724 // back up on the LRU list. This is good because
5725 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005726 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005727 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005728 }
5729
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005730 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005731 if (false) {
5732 if (cpr.name.flattenToShortString().equals(
5733 "com.android.providers.calendar/.CalendarProvider2")) {
5734 Slog.v(TAG, "****************** KILLING "
5735 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005736 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005737 }
5738 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005739 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005740 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5741 // NOTE: there is still a race here where a signal could be
5742 // pending on the process even though we managed to update its
5743 // adj level. Not sure what to do about this, but at least
5744 // the race is now smaller.
5745 if (!success) {
5746 // Uh oh... it looks like the provider's process
5747 // has been killed on us. We need to wait for a new
5748 // process to be started, and make sure its death
5749 // doesn't kill our process.
5750 Slog.i(TAG,
5751 "Existing provider " + cpr.name.flattenToShortString()
5752 + " is crashing; detaching " + r);
5753 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005754 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005755 if (!lastRef) {
5756 // This wasn't the last ref our process had on
5757 // the provider... we have now been killed, bail.
5758 return null;
5759 }
5760 providerRunning = false;
5761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005762 }
5763
5764 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005767 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005768 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005769 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005770 resolveContentProvider(name,
5771 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772 } catch (RemoteException ex) {
5773 }
5774 if (cpi == null) {
5775 return null;
5776 }
5777
Dianne Hackbornb424b632010-08-18 15:59:05 -07005778 String msg;
5779 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5780 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005781 }
5782
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005783 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005784 && !cpi.processName.equals("system")) {
5785 // If this content provider does not run in the system
5786 // process, and the system is not yet ready to run other
5787 // processes, then fail fast instead of hanging.
5788 throw new IllegalArgumentException(
5789 "Attempt to launch content provider before system ready");
5790 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005791
5792 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5793 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794 final boolean firstClass = cpr == null;
5795 if (firstClass) {
5796 try {
5797 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005798 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 getApplicationInfo(
5800 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005801 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005803 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 + cpi.name);
5805 return null;
5806 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005807 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005808 } catch (RemoteException ex) {
5809 // pm is in same process, this will never happen.
5810 }
5811 }
5812
5813 if (r != null && cpr.canRunHere(r)) {
5814 // If this is a multiprocess provider, then just return its
5815 // info and allow the caller to instantiate it. Only do
5816 // this if the provider is the same user as the caller's
5817 // process, or can run as root (so can be in any process).
5818 return cpr;
5819 }
5820
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005821 if (DEBUG_PROVIDER) {
5822 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005823 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005824 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 }
5826
5827 // This is single process, and our app is now connecting to it.
5828 // See if we are already in the process of launching this
5829 // provider.
5830 final int N = mLaunchingProviders.size();
5831 int i;
5832 for (i=0; i<N; i++) {
5833 if (mLaunchingProviders.get(i) == cpr) {
5834 break;
5835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005836 }
5837
5838 // If the provider is not already being launched, then get it
5839 // started.
5840 if (i >= N) {
5841 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005842
5843 try {
5844 // Content provider is now in use, its package can't be stopped.
5845 try {
5846 AppGlobals.getPackageManager().setPackageStoppedState(
5847 cpr.appInfo.packageName, false);
5848 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005849 } catch (IllegalArgumentException e) {
5850 Slog.w(TAG, "Failed trying to unstop package "
5851 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005852 }
5853
5854 ProcessRecord proc = startProcessLocked(cpi.processName,
5855 cpr.appInfo, false, 0, "content provider",
5856 new ComponentName(cpi.applicationInfo.packageName,
5857 cpi.name), false);
5858 if (proc == null) {
5859 Slog.w(TAG, "Unable to launch app "
5860 + cpi.applicationInfo.packageName + "/"
5861 + cpi.applicationInfo.uid + " for provider "
5862 + name + ": process is bad");
5863 return null;
5864 }
5865 cpr.launchingApp = proc;
5866 mLaunchingProviders.add(cpr);
5867 } finally {
5868 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005870 }
5871
5872 // Make sure the provider is published (the same provider class
5873 // may be published under multiple names).
5874 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005875 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005876 }
5877 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005878 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005879 }
5880 }
5881
5882 // Wait for the provider to be published...
5883 synchronized (cpr) {
5884 while (cpr.provider == null) {
5885 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005886 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005887 + cpi.applicationInfo.packageName + "/"
5888 + cpi.applicationInfo.uid + " for provider "
5889 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005890 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 cpi.applicationInfo.packageName,
5892 cpi.applicationInfo.uid, name);
5893 return null;
5894 }
5895 try {
5896 cpr.wait();
5897 } catch (InterruptedException ex) {
5898 }
5899 }
5900 }
5901 return cpr;
5902 }
5903
5904 public final ContentProviderHolder getContentProvider(
5905 IApplicationThread caller, String name) {
5906 if (caller == null) {
5907 String msg = "null IApplicationThread when getting content provider "
5908 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005909 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 throw new SecurityException(msg);
5911 }
5912
5913 return getContentProviderImpl(caller, name);
5914 }
5915
5916 private ContentProviderHolder getContentProviderExternal(String name) {
5917 return getContentProviderImpl(null, name);
5918 }
5919
5920 /**
5921 * Drop a content provider from a ProcessRecord's bookkeeping
5922 * @param cpr
5923 */
5924 public void removeContentProvider(IApplicationThread caller, String name) {
5925 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005926 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005927 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005928 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005929 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005930 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 return;
5932 }
5933 final ProcessRecord r = getRecordForAppLocked(caller);
5934 if (r == null) {
5935 throw new SecurityException(
5936 "Unable to find app for caller " + caller +
5937 " when removing content provider " + name);
5938 }
5939 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005940 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5941 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005942 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005943 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005944 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005945 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 return;
5947 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005948 if (decProviderCount(r, localCpr)) {
5949 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 }
5953 }
5954
5955 private void removeContentProviderExternal(String name) {
5956 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005957 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 if(cpr == null) {
5959 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005960 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005961 return;
5962 }
5963
5964 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005965 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5966 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005967 localCpr.externals--;
5968 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005969 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005970 }
5971 updateOomAdjLocked();
5972 }
5973 }
5974
5975 public final void publishContentProviders(IApplicationThread caller,
5976 List<ContentProviderHolder> providers) {
5977 if (providers == null) {
5978 return;
5979 }
5980
5981 synchronized(this) {
5982 final ProcessRecord r = getRecordForAppLocked(caller);
5983 if (r == null) {
5984 throw new SecurityException(
5985 "Unable to find app for caller " + caller
5986 + " (pid=" + Binder.getCallingPid()
5987 + ") when publishing content providers");
5988 }
5989
5990 final long origId = Binder.clearCallingIdentity();
5991
5992 final int N = providers.size();
5993 for (int i=0; i<N; i++) {
5994 ContentProviderHolder src = providers.get(i);
5995 if (src == null || src.info == null || src.provider == null) {
5996 continue;
5997 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005998 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006000 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6001 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006002 String names[] = dst.info.authority.split(";");
6003 for (int j = 0; j < names.length; j++) {
6004 mProvidersByName.put(names[j], dst);
6005 }
6006
6007 int NL = mLaunchingProviders.size();
6008 int j;
6009 for (j=0; j<NL; j++) {
6010 if (mLaunchingProviders.get(j) == dst) {
6011 mLaunchingProviders.remove(j);
6012 j--;
6013 NL--;
6014 }
6015 }
6016 synchronized (dst) {
6017 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006018 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 dst.notifyAll();
6020 }
6021 updateOomAdjLocked(r);
6022 }
6023 }
6024
6025 Binder.restoreCallingIdentity(origId);
6026 }
6027 }
6028
6029 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006030 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006031 synchronized (mSelf) {
6032 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6033 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006034 if (providers != null) {
6035 for (int i=providers.size()-1; i>=0; i--) {
6036 ProviderInfo pi = (ProviderInfo)providers.get(i);
6037 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6038 Slog.w(TAG, "Not installing system proc provider " + pi.name
6039 + ": not system .apk");
6040 providers.remove(i);
6041 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006042 }
6043 }
6044 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006045 if (providers != null) {
6046 mSystemThread.installSystemProviders(providers);
6047 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006048
6049 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006050
6051 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 }
6053
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006054 /**
6055 * Allows app to retrieve the MIME type of a URI without having permission
6056 * to access its content provider.
6057 *
6058 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6059 *
6060 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6061 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6062 */
6063 public String getProviderMimeType(Uri uri) {
6064 final String name = uri.getAuthority();
6065 final long ident = Binder.clearCallingIdentity();
6066 ContentProviderHolder holder = null;
6067
6068 try {
6069 holder = getContentProviderExternal(name);
6070 if (holder != null) {
6071 return holder.provider.getType(uri);
6072 }
6073 } catch (RemoteException e) {
6074 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6075 return null;
6076 } finally {
6077 if (holder != null) {
6078 removeContentProviderExternal(name);
6079 }
6080 Binder.restoreCallingIdentity(ident);
6081 }
6082
6083 return null;
6084 }
6085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 // =========================================================
6087 // GLOBAL MANAGEMENT
6088 // =========================================================
6089
6090 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6091 ApplicationInfo info, String customProcess) {
6092 String proc = customProcess != null ? customProcess : info.processName;
6093 BatteryStatsImpl.Uid.Proc ps = null;
6094 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6095 synchronized (stats) {
6096 ps = stats.getProcessStatsLocked(info.uid, proc);
6097 }
6098 return new ProcessRecord(ps, thread, info, proc);
6099 }
6100
6101 final ProcessRecord addAppLocked(ApplicationInfo info) {
6102 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6103
6104 if (app == null) {
6105 app = newProcessRecordLocked(null, info, null);
6106 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006107 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006108 }
6109
Dianne Hackborne7f97212011-02-24 14:40:20 -08006110 // This package really, really can not be stopped.
6111 try {
6112 AppGlobals.getPackageManager().setPackageStoppedState(
6113 info.packageName, false);
6114 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006115 } catch (IllegalArgumentException e) {
6116 Slog.w(TAG, "Failed trying to unstop package "
6117 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006118 }
6119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6121 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6122 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006123 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006124 }
6125 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6126 mPersistentStartingProcesses.add(app);
6127 startProcessLocked(app, "added application", app.processName);
6128 }
6129
6130 return app;
6131 }
6132
6133 public void unhandledBack() {
6134 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6135 "unhandledBack()");
6136
6137 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006138 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006139 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 TAG, "Performing unhandledBack(): stack size = " + count);
6141 if (count > 1) {
6142 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006143 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6145 Binder.restoreCallingIdentity(origId);
6146 }
6147 }
6148 }
6149
6150 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6151 String name = uri.getAuthority();
6152 ContentProviderHolder cph = getContentProviderExternal(name);
6153 ParcelFileDescriptor pfd = null;
6154 if (cph != null) {
6155 // We record the binder invoker's uid in thread-local storage before
6156 // going to the content provider to open the file. Later, in the code
6157 // that handles all permissions checks, we look for this uid and use
6158 // that rather than the Activity Manager's own uid. The effect is that
6159 // we do the check against the caller's permissions even though it looks
6160 // to the content provider like the Activity Manager itself is making
6161 // the request.
6162 sCallerIdentity.set(new Identity(
6163 Binder.getCallingPid(), Binder.getCallingUid()));
6164 try {
6165 pfd = cph.provider.openFile(uri, "r");
6166 } catch (FileNotFoundException e) {
6167 // do nothing; pfd will be returned null
6168 } finally {
6169 // Ensure that whatever happens, we clean up the identity state
6170 sCallerIdentity.remove();
6171 }
6172
6173 // We've got the fd now, so we're done with the provider.
6174 removeContentProviderExternal(name);
6175 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006176 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 }
6178 return pfd;
6179 }
6180
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006181 // Actually is sleeping or shutting down or whatever else in the future
6182 // is an inactive state.
6183 public boolean isSleeping() {
6184 return mSleeping || mShuttingDown;
6185 }
6186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006187 public void goingToSleep() {
6188 synchronized(this) {
6189 mSleeping = true;
6190 mWindowManager.setEventDispatching(false);
6191
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006192 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006193
6194 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006195 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006196 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6197 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006198 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006199 }
6200 }
6201
Dianne Hackborn55280a92009-05-07 15:53:46 -07006202 public boolean shutdown(int timeout) {
6203 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6204 != PackageManager.PERMISSION_GRANTED) {
6205 throw new SecurityException("Requires permission "
6206 + android.Manifest.permission.SHUTDOWN);
6207 }
6208
6209 boolean timedout = false;
6210
6211 synchronized(this) {
6212 mShuttingDown = true;
6213 mWindowManager.setEventDispatching(false);
6214
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006215 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006216 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006217 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006218 while (mMainStack.mResumedActivity != null
6219 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006220 long delay = endTime - System.currentTimeMillis();
6221 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006222 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006223 timedout = true;
6224 break;
6225 }
6226 try {
6227 this.wait();
6228 } catch (InterruptedException e) {
6229 }
6230 }
6231 }
6232 }
6233
6234 mUsageStatsService.shutdown();
6235 mBatteryStatsService.shutdown();
6236
6237 return timedout;
6238 }
6239
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006240 public final void activitySlept(IBinder token) {
6241 if (localLOGV) Slog.v(
6242 TAG, "Activity slept: token=" + token);
6243
6244 ActivityRecord r = null;
6245
6246 final long origId = Binder.clearCallingIdentity();
6247
6248 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006249 r = mMainStack.isInStackLocked(token);
6250 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006251 mMainStack.activitySleptLocked(r);
6252 }
6253 }
6254
6255 Binder.restoreCallingIdentity(origId);
6256 }
6257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006258 public void wakingUp() {
6259 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 mWindowManager.setEventDispatching(true);
6261 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006262 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006263 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006264 }
6265 }
6266
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006267 public void stopAppSwitches() {
6268 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6269 != PackageManager.PERMISSION_GRANTED) {
6270 throw new SecurityException("Requires permission "
6271 + android.Manifest.permission.STOP_APP_SWITCHES);
6272 }
6273
6274 synchronized(this) {
6275 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6276 + APP_SWITCH_DELAY_TIME;
6277 mDidAppSwitch = false;
6278 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6279 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6280 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6281 }
6282 }
6283
6284 public void resumeAppSwitches() {
6285 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6286 != PackageManager.PERMISSION_GRANTED) {
6287 throw new SecurityException("Requires permission "
6288 + android.Manifest.permission.STOP_APP_SWITCHES);
6289 }
6290
6291 synchronized(this) {
6292 // Note that we don't execute any pending app switches... we will
6293 // let those wait until either the timeout, or the next start
6294 // activity request.
6295 mAppSwitchesAllowedTime = 0;
6296 }
6297 }
6298
6299 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6300 String name) {
6301 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6302 return true;
6303 }
6304
6305 final int perm = checkComponentPermission(
6306 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006307 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006308 if (perm == PackageManager.PERMISSION_GRANTED) {
6309 return true;
6310 }
6311
Joe Onorato8a9b2202010-02-26 18:56:32 -08006312 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006313 return false;
6314 }
6315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 public void setDebugApp(String packageName, boolean waitForDebugger,
6317 boolean persistent) {
6318 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6319 "setDebugApp()");
6320
6321 // Note that this is not really thread safe if there are multiple
6322 // callers into it at the same time, but that's not a situation we
6323 // care about.
6324 if (persistent) {
6325 final ContentResolver resolver = mContext.getContentResolver();
6326 Settings.System.putString(
6327 resolver, Settings.System.DEBUG_APP,
6328 packageName);
6329 Settings.System.putInt(
6330 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6331 waitForDebugger ? 1 : 0);
6332 }
6333
6334 synchronized (this) {
6335 if (!persistent) {
6336 mOrigDebugApp = mDebugApp;
6337 mOrigWaitForDebugger = mWaitForDebugger;
6338 }
6339 mDebugApp = packageName;
6340 mWaitForDebugger = waitForDebugger;
6341 mDebugTransient = !persistent;
6342 if (packageName != null) {
6343 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006344 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006345 Binder.restoreCallingIdentity(origId);
6346 }
6347 }
6348 }
6349
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006350 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6351 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6352 synchronized (this) {
6353 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6354 if (!isDebuggable) {
6355 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6356 throw new SecurityException("Process not debuggable: " + app.packageName);
6357 }
6358 }
6359 mProfileApp = processName;
6360 mProfileFile = profileFile;
6361 if (mProfileFd != null) {
6362 try {
6363 mProfileFd.close();
6364 } catch (IOException e) {
6365 }
6366 mProfileFd = null;
6367 }
6368 mProfileFd = profileFd;
6369 mProfileType = 0;
6370 mAutoStopProfiler = autoStopProfiler;
6371 }
6372 }
6373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 public void setAlwaysFinish(boolean enabled) {
6375 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6376 "setAlwaysFinish()");
6377
6378 Settings.System.putInt(
6379 mContext.getContentResolver(),
6380 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6381
6382 synchronized (this) {
6383 mAlwaysFinishActivities = enabled;
6384 }
6385 }
6386
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006387 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006388 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006389 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006390 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006391 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006392 }
6393 }
6394
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006395 public boolean isUserAMonkey() {
6396 // For now the fact that there is a controller implies
6397 // we have a monkey.
6398 synchronized (this) {
6399 return mController != null;
6400 }
6401 }
6402
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006403 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006404 synchronized (this) {
6405 mWatchers.register(watcher);
6406 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006407 }
6408
6409 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006410 synchronized (this) {
6411 mWatchers.unregister(watcher);
6412 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006413 }
6414
Jeff Sharkeya4620792011-05-20 15:29:23 -07006415 public void registerProcessObserver(IProcessObserver observer) {
6416 mProcessObservers.register(observer);
6417 }
6418
6419 public void unregisterProcessObserver(IProcessObserver observer) {
6420 mProcessObservers.unregister(observer);
6421 }
6422
Daniel Sandler69a48172010-06-23 16:29:36 -04006423 public void setImmersive(IBinder token, boolean immersive) {
6424 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006425 ActivityRecord r = mMainStack.isInStackLocked(token);
6426 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006427 throw new IllegalArgumentException();
6428 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006429 r.immersive = immersive;
6430 }
6431 }
6432
6433 public boolean isImmersive(IBinder token) {
6434 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006435 ActivityRecord r = mMainStack.isInStackLocked(token);
6436 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006437 throw new IllegalArgumentException();
6438 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006439 return r.immersive;
6440 }
6441 }
6442
6443 public boolean isTopActivityImmersive() {
6444 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006445 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006446 return (r != null) ? r.immersive : false;
6447 }
6448 }
6449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 public final void enterSafeMode() {
6451 synchronized(this) {
6452 // It only makes sense to do this before the system is ready
6453 // and started launching other packages.
6454 if (!mSystemReady) {
6455 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006456 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006457 } catch (RemoteException e) {
6458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 }
6460 }
6461 }
6462
Jeff Brownb09abc12011-01-13 21:08:27 -08006463 public final void showSafeModeOverlay() {
6464 View v = LayoutInflater.from(mContext).inflate(
6465 com.android.internal.R.layout.safe_mode, null);
6466 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6467 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6468 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6469 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6470 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6471 lp.format = v.getBackground().getOpacity();
6472 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6473 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6474 ((WindowManager)mContext.getSystemService(
6475 Context.WINDOW_SERVICE)).addView(v, lp);
6476 }
6477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 public void noteWakeupAlarm(IIntentSender sender) {
6479 if (!(sender instanceof PendingIntentRecord)) {
6480 return;
6481 }
6482 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6483 synchronized (stats) {
6484 if (mBatteryStatsService.isOnBattery()) {
6485 mBatteryStatsService.enforceCallingPermission();
6486 PendingIntentRecord rec = (PendingIntentRecord)sender;
6487 int MY_UID = Binder.getCallingUid();
6488 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6489 BatteryStatsImpl.Uid.Pkg pkg =
6490 stats.getPackageStatsLocked(uid, rec.key.packageName);
6491 pkg.incWakeupsLocked();
6492 }
6493 }
6494 }
6495
Dianne Hackborn64825172011-03-02 21:32:58 -08006496 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006498 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006499 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006500 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 // XXX Note: don't acquire main activity lock here, because the window
6502 // manager calls in with its locks held.
6503
6504 boolean killed = false;
6505 synchronized (mPidsSelfLocked) {
6506 int[] types = new int[pids.length];
6507 int worstType = 0;
6508 for (int i=0; i<pids.length; i++) {
6509 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6510 if (proc != null) {
6511 int type = proc.setAdj;
6512 types[i] = type;
6513 if (type > worstType) {
6514 worstType = type;
6515 }
6516 }
6517 }
6518
Dianne Hackborn64825172011-03-02 21:32:58 -08006519 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006520 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006521 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6522 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006523 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006524 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006525
6526 // If this is not a secure call, don't let it kill processes that
6527 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006528 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6529 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006530 }
6531
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006532 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006533 for (int i=0; i<pids.length; i++) {
6534 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6535 if (proc == null) {
6536 continue;
6537 }
6538 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006539 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006540 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006541 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6542 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006543 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006544 proc.killedBackground = true;
6545 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006546 }
6547 }
6548 }
6549 return killed;
6550 }
6551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006552 public final void startRunning(String pkg, String cls, String action,
6553 String data) {
6554 synchronized(this) {
6555 if (mStartRunning) {
6556 return;
6557 }
6558 mStartRunning = true;
6559 mTopComponent = pkg != null && cls != null
6560 ? new ComponentName(pkg, cls) : null;
6561 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6562 mTopData = data;
6563 if (!mSystemReady) {
6564 return;
6565 }
6566 }
6567
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006568 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 }
6570
6571 private void retrieveSettings() {
6572 final ContentResolver resolver = mContext.getContentResolver();
6573 String debugApp = Settings.System.getString(
6574 resolver, Settings.System.DEBUG_APP);
6575 boolean waitForDebugger = Settings.System.getInt(
6576 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6577 boolean alwaysFinishActivities = Settings.System.getInt(
6578 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6579
6580 Configuration configuration = new Configuration();
6581 Settings.System.getConfiguration(resolver, configuration);
6582
6583 synchronized (this) {
6584 mDebugApp = mOrigDebugApp = debugApp;
6585 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6586 mAlwaysFinishActivities = alwaysFinishActivities;
6587 // This happens before any activities are started, so we can
6588 // change mConfiguration in-place.
6589 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006590 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006591 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006592 }
6593 }
6594
6595 public boolean testIsSystemReady() {
6596 // no need to synchronize(this) just to read & return the value
6597 return mSystemReady;
6598 }
6599
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006600 private static File getCalledPreBootReceiversFile() {
6601 File dataDir = Environment.getDataDirectory();
6602 File systemDir = new File(dataDir, "system");
6603 File fname = new File(systemDir, "called_pre_boots.dat");
6604 return fname;
6605 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006606
6607 static final int LAST_DONE_VERSION = 10000;
6608
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006609 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6610 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6611 File file = getCalledPreBootReceiversFile();
6612 FileInputStream fis = null;
6613 try {
6614 fis = new FileInputStream(file);
6615 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006616 int fvers = dis.readInt();
6617 if (fvers == LAST_DONE_VERSION) {
6618 String vers = dis.readUTF();
6619 String codename = dis.readUTF();
6620 String build = dis.readUTF();
6621 if (android.os.Build.VERSION.RELEASE.equals(vers)
6622 && android.os.Build.VERSION.CODENAME.equals(codename)
6623 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6624 int num = dis.readInt();
6625 while (num > 0) {
6626 num--;
6627 String pkg = dis.readUTF();
6628 String cls = dis.readUTF();
6629 lastDoneReceivers.add(new ComponentName(pkg, cls));
6630 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006631 }
6632 }
6633 } catch (FileNotFoundException e) {
6634 } catch (IOException e) {
6635 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6636 } finally {
6637 if (fis != null) {
6638 try {
6639 fis.close();
6640 } catch (IOException e) {
6641 }
6642 }
6643 }
6644 return lastDoneReceivers;
6645 }
6646
6647 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6648 File file = getCalledPreBootReceiversFile();
6649 FileOutputStream fos = null;
6650 DataOutputStream dos = null;
6651 try {
6652 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6653 fos = new FileOutputStream(file);
6654 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006655 dos.writeInt(LAST_DONE_VERSION);
6656 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006657 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006658 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006659 dos.writeInt(list.size());
6660 for (int i=0; i<list.size(); i++) {
6661 dos.writeUTF(list.get(i).getPackageName());
6662 dos.writeUTF(list.get(i).getClassName());
6663 }
6664 } catch (IOException e) {
6665 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6666 file.delete();
6667 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006668 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006669 if (dos != null) {
6670 try {
6671 dos.close();
6672 } catch (IOException e) {
6673 // TODO Auto-generated catch block
6674 e.printStackTrace();
6675 }
6676 }
6677 }
6678 }
6679
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006680 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 synchronized(this) {
6682 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006683 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006684 return;
6685 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006686
6687 // Check to see if there are any update receivers to run.
6688 if (!mDidUpdate) {
6689 if (mWaitingUpdate) {
6690 return;
6691 }
6692 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6693 List<ResolveInfo> ris = null;
6694 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006695 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006696 intent, null, 0);
6697 } catch (RemoteException e) {
6698 }
6699 if (ris != null) {
6700 for (int i=ris.size()-1; i>=0; i--) {
6701 if ((ris.get(i).activityInfo.applicationInfo.flags
6702 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6703 ris.remove(i);
6704 }
6705 }
6706 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006707
6708 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6709
6710 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006711 for (int i=0; i<ris.size(); i++) {
6712 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006713 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6714 if (lastDoneReceivers.contains(comp)) {
6715 ris.remove(i);
6716 i--;
6717 }
6718 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006719
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006720 for (int i=0; i<ris.size(); i++) {
6721 ActivityInfo ai = ris.get(i).activityInfo;
6722 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6723 doneReceivers.add(comp);
6724 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006725 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006726 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006727 finisher = new IIntentReceiver.Stub() {
6728 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006729 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006730 boolean sticky) {
6731 // The raw IIntentReceiver interface is called
6732 // with the AM lock held, so redispatch to
6733 // execute our code without the lock.
6734 mHandler.post(new Runnable() {
6735 public void run() {
6736 synchronized (ActivityManagerService.this) {
6737 mDidUpdate = true;
6738 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006739 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006740 showBootMessage(mContext.getText(
6741 R.string.android_upgrading_complete),
6742 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006743 systemReady(goingCallback);
6744 }
6745 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006746 }
6747 };
6748 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006749 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006750 broadcastIntentLocked(null, null, intent, null, finisher,
6751 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006752 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006753 mWaitingUpdate = true;
6754 }
6755 }
6756 }
6757 if (mWaitingUpdate) {
6758 return;
6759 }
6760 mDidUpdate = true;
6761 }
6762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006763 mSystemReady = true;
6764 if (!mStartRunning) {
6765 return;
6766 }
6767 }
6768
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006769 ArrayList<ProcessRecord> procsToKill = null;
6770 synchronized(mPidsSelfLocked) {
6771 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6772 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6773 if (!isAllowedWhileBooting(proc.info)){
6774 if (procsToKill == null) {
6775 procsToKill = new ArrayList<ProcessRecord>();
6776 }
6777 procsToKill.add(proc);
6778 }
6779 }
6780 }
6781
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006782 synchronized(this) {
6783 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006784 for (int i=procsToKill.size()-1; i>=0; i--) {
6785 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006786 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006787 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006788 }
6789 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006790
6791 // Now that we have cleaned up any update processes, we
6792 // are ready to start launching real processes and know that
6793 // we won't trample on them any more.
6794 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006795 }
6796
Joe Onorato8a9b2202010-02-26 18:56:32 -08006797 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006798 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 SystemClock.uptimeMillis());
6800
6801 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006802 // Make sure we have no pre-ready processes sitting around.
6803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6805 ResolveInfo ri = mContext.getPackageManager()
6806 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006807 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006808 CharSequence errorMsg = null;
6809 if (ri != null) {
6810 ActivityInfo ai = ri.activityInfo;
6811 ApplicationInfo app = ai.applicationInfo;
6812 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6813 mTopAction = Intent.ACTION_FACTORY_TEST;
6814 mTopData = null;
6815 mTopComponent = new ComponentName(app.packageName,
6816 ai.name);
6817 } else {
6818 errorMsg = mContext.getResources().getText(
6819 com.android.internal.R.string.factorytest_not_system);
6820 }
6821 } else {
6822 errorMsg = mContext.getResources().getText(
6823 com.android.internal.R.string.factorytest_no_action);
6824 }
6825 if (errorMsg != null) {
6826 mTopAction = null;
6827 mTopData = null;
6828 mTopComponent = null;
6829 Message msg = Message.obtain();
6830 msg.what = SHOW_FACTORY_ERROR_MSG;
6831 msg.getData().putCharSequence("msg", errorMsg);
6832 mHandler.sendMessage(msg);
6833 }
6834 }
6835 }
6836
6837 retrieveSettings();
6838
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006839 if (goingCallback != null) goingCallback.run();
6840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006841 synchronized (this) {
6842 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6843 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006844 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006845 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 if (apps != null) {
6847 int N = apps.size();
6848 int i;
6849 for (i=0; i<N; i++) {
6850 ApplicationInfo info
6851 = (ApplicationInfo)apps.get(i);
6852 if (info != null &&
6853 !info.packageName.equals("android")) {
6854 addAppLocked(info);
6855 }
6856 }
6857 }
6858 } catch (RemoteException ex) {
6859 // pm is in same process, this will never happen.
6860 }
6861 }
6862
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006863 // Start up initial activity.
6864 mBooting = true;
6865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006866 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006867 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 Message msg = Message.obtain();
6869 msg.what = SHOW_UID_ERROR_MSG;
6870 mHandler.sendMessage(msg);
6871 }
6872 } catch (RemoteException e) {
6873 }
6874
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006875 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 }
6877 }
6878
Dan Egnorb7f03672009-12-09 16:22:32 -08006879 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006880 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006882 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006883 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006884 startAppProblemLocked(app);
6885 app.stopFreezingAllLocked();
6886 return handleAppCrashLocked(app);
6887 }
6888
Dan Egnorb7f03672009-12-09 16:22:32 -08006889 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006890 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006891 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006892 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006893 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6894 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 startAppProblemLocked(app);
6896 app.stopFreezingAllLocked();
6897 }
6898
6899 /**
6900 * Generate a process error record, suitable for attachment to a ProcessRecord.
6901 *
6902 * @param app The ProcessRecord in which the error occurred.
6903 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6904 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006905 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 * @param shortMsg Short message describing the crash.
6907 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006908 * @param stackTrace Full crash stack trace, may be null.
6909 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 * @return Returns a fully-formed AppErrorStateInfo record.
6911 */
6912 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006913 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006914 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 report.condition = condition;
6917 report.processName = app.processName;
6918 report.pid = app.pid;
6919 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006920 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006921 report.shortMsg = shortMsg;
6922 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006923 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924
6925 return report;
6926 }
6927
Dan Egnor42471dd2010-01-07 17:25:22 -08006928 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 synchronized (this) {
6930 app.crashing = false;
6931 app.crashingReport = null;
6932 app.notResponding = false;
6933 app.notRespondingReport = null;
6934 if (app.anrDialog == fromDialog) {
6935 app.anrDialog = null;
6936 }
6937 if (app.waitDialog == fromDialog) {
6938 app.waitDialog = null;
6939 }
6940 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006941 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006942 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006943 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6944 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006945 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006947 }
6948 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006949
Dan Egnorb7f03672009-12-09 16:22:32 -08006950 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006951 long now = SystemClock.uptimeMillis();
6952
6953 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6954 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006955 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006957 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006958 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006959 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006960 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006961 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6962 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006963 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006964 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006965 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006966 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006967 }
6968 }
6969 if (!app.persistent) {
6970 // We don't want to start this process again until the user
6971 // explicitly does so... but for persistent process, we really
6972 // need to keep it running. If a persistent process is actually
6973 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006974 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006975 app.info.processName);
6976 mBadProcesses.put(app.info.processName, app.info.uid, now);
6977 app.bad = true;
6978 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6979 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006980 // Don't let services in this process be restarted and potentially
6981 // annoy the user repeatedly. Unless it is persistent, since those
6982 // processes run critical code.
6983 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006984 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 return false;
6986 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006987 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006988 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006989 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006990 if (r.app == app) {
6991 // If the top running activity is from this crashing
6992 // process, then terminate it to avoid getting in a loop.
6993 Slog.w(TAG, " Force finishing activity "
6994 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006995 int index = mMainStack.indexOfTokenLocked(r);
6996 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006997 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006998 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006999 // stopped, to avoid a situation where one will get
7000 // re-start our crashing activity once it gets resumed again.
7001 index--;
7002 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007003 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007004 if (r.state == ActivityState.RESUMED
7005 || r.state == ActivityState.PAUSING
7006 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007007 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007008 Slog.w(TAG, " Force finishing activity "
7009 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007010 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007011 Activity.RESULT_CANCELED, null, "crashed");
7012 }
7013 }
7014 }
7015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007016 }
7017
7018 // Bump up the crash count of any services currently running in the proc.
7019 if (app.services.size() != 0) {
7020 // Any services running in the application need to be placed
7021 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007022 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007024 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 sr.crashCount++;
7026 }
7027 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007028
7029 // If the crashing process is what we consider to be the "home process" and it has been
7030 // replaced by a third-party app, clear the package preferred activities from packages
7031 // with a home activity running in the process to prevent a repeatedly crashing app
7032 // from blocking the user to manually clear the list.
7033 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7034 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7035 Iterator it = mHomeProcess.activities.iterator();
7036 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007037 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007038 if (r.isHomeActivity) {
7039 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7040 try {
7041 ActivityThread.getPackageManager()
7042 .clearPackagePreferredActivities(r.packageName);
7043 } catch (RemoteException c) {
7044 // pm is in same process, this will never happen.
7045 }
7046 }
7047 }
7048 }
7049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7051 return true;
7052 }
7053
7054 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007055 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7056 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 skipCurrentReceiverLocked(app);
7058 }
7059
7060 void skipCurrentReceiverLocked(ProcessRecord app) {
7061 boolean reschedule = false;
7062 BroadcastRecord r = app.curReceiver;
7063 if (r != null) {
7064 // The current broadcast is waiting for this app's receiver
7065 // to be finished. Looks like that's not going to happen, so
7066 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007067 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007068 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7069 r.resultExtras, r.resultAbort, true);
7070 reschedule = true;
7071 }
7072 r = mPendingBroadcast;
7073 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007074 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007075 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007076 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007077 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7078 r.resultExtras, r.resultAbort, true);
7079 reschedule = true;
7080 }
7081 if (reschedule) {
7082 scheduleBroadcastsLocked();
7083 }
7084 }
7085
Dan Egnor60d87622009-12-16 16:32:58 -08007086 /**
7087 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7088 * The application process will exit immediately after this call returns.
7089 * @param app object of the crashing app, null for the system server
7090 * @param crashInfo describing the exception
7091 */
7092 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007093 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007094 final String processName = app == null ? "system_server"
7095 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007096
7097 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007098 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007099 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007100 crashInfo.exceptionClassName,
7101 crashInfo.exceptionMessage,
7102 crashInfo.throwFileName,
7103 crashInfo.throwLineNumber);
7104
Jeff Sharkeya353d262011-10-28 11:12:06 -07007105 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007106
7107 crashApplication(r, crashInfo);
7108 }
7109
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007110 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007111 IBinder app,
7112 int violationMask,
7113 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007114 ProcessRecord r = findAppProcess(app, "StrictMode");
7115 if (r == null) {
7116 return;
7117 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007118
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007119 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007120 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007121 boolean logIt = true;
7122 synchronized (mAlreadyLoggedViolatedStacks) {
7123 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7124 logIt = false;
7125 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007126 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007127 // the relative pain numbers, without logging all
7128 // the stack traces repeatedly. We'd want to do
7129 // likewise in the client code, which also does
7130 // dup suppression, before the Binder call.
7131 } else {
7132 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7133 mAlreadyLoggedViolatedStacks.clear();
7134 }
7135 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7136 }
7137 }
7138 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007139 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007140 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007141 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007142
7143 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7144 AppErrorResult result = new AppErrorResult();
7145 synchronized (this) {
7146 final long origId = Binder.clearCallingIdentity();
7147
7148 Message msg = Message.obtain();
7149 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7150 HashMap<String, Object> data = new HashMap<String, Object>();
7151 data.put("result", result);
7152 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007153 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007154 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007155 msg.obj = data;
7156 mHandler.sendMessage(msg);
7157
7158 Binder.restoreCallingIdentity(origId);
7159 }
7160 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007161 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007162 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007163 }
7164
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007165 // Depending on the policy in effect, there could be a bunch of
7166 // these in quick succession so we try to batch these together to
7167 // minimize disk writes, number of dropbox entries, and maximize
7168 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007169 private void logStrictModeViolationToDropBox(
7170 ProcessRecord process,
7171 StrictMode.ViolationInfo info) {
7172 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007173 return;
7174 }
7175 final boolean isSystemApp = process == null ||
7176 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7177 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007178 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007179 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7180 final DropBoxManager dbox = (DropBoxManager)
7181 mContext.getSystemService(Context.DROPBOX_SERVICE);
7182
7183 // Exit early if the dropbox isn't configured to accept this report type.
7184 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7185
7186 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007187 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007188 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7189 synchronized (sb) {
7190 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007191 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007192 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7193 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007194 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7195 if (info.violationNumThisLoop != 0) {
7196 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7197 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007198 if (info.numAnimationsRunning != 0) {
7199 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7200 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007201 if (info.broadcastIntentAction != null) {
7202 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7203 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007204 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007205 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007206 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007207 if (info.numInstances != -1) {
7208 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7209 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007210 if (info.tags != null) {
7211 for (String tag : info.tags) {
7212 sb.append("Span-Tag: ").append(tag).append("\n");
7213 }
7214 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007215 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007216 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7217 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007218 }
7219 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007220
7221 // Only buffer up to ~64k. Various logging bits truncate
7222 // things at 128k.
7223 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007224 }
7225
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007226 // Flush immediately if the buffer's grown too large, or this
7227 // is a non-system app. Non-system apps are isolated with a
7228 // different tag & policy and not batched.
7229 //
7230 // Batching is useful during internal testing with
7231 // StrictMode settings turned up high. Without batching,
7232 // thousands of separate files could be created on boot.
7233 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007234 new Thread("Error dump: " + dropboxTag) {
7235 @Override
7236 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007237 String report;
7238 synchronized (sb) {
7239 report = sb.toString();
7240 sb.delete(0, sb.length());
7241 sb.trimToSize();
7242 }
7243 if (report.length() != 0) {
7244 dbox.addText(dropboxTag, report);
7245 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007246 }
7247 }.start();
7248 return;
7249 }
7250
7251 // System app batching:
7252 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007253 // An existing dropbox-writing thread is outstanding, so
7254 // we don't need to start it up. The existing thread will
7255 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007256 return;
7257 }
7258
7259 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7260 // (After this point, we shouldn't access AMS internal data structures.)
7261 new Thread("Error dump: " + dropboxTag) {
7262 @Override
7263 public void run() {
7264 // 5 second sleep to let stacks arrive and be batched together
7265 try {
7266 Thread.sleep(5000); // 5 seconds
7267 } catch (InterruptedException e) {}
7268
7269 String errorReport;
7270 synchronized (mStrictModeBuffer) {
7271 errorReport = mStrictModeBuffer.toString();
7272 if (errorReport.length() == 0) {
7273 return;
7274 }
7275 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7276 mStrictModeBuffer.trimToSize();
7277 }
7278 dbox.addText(dropboxTag, errorReport);
7279 }
7280 }.start();
7281 }
7282
Dan Egnor60d87622009-12-16 16:32:58 -08007283 /**
7284 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7285 * @param app object of the crashing app, null for the system server
7286 * @param tag reported by the caller
7287 * @param crashInfo describing the context of the error
7288 * @return true if the process should exit immediately (WTF is fatal)
7289 */
7290 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007291 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007292 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007293 final String processName = app == null ? "system_server"
7294 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007295
7296 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007297 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007298 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007299 tag, crashInfo.exceptionMessage);
7300
Jeff Sharkeya353d262011-10-28 11:12:06 -07007301 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007302
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007303 if (r != null && r.pid != Process.myPid() &&
7304 Settings.Secure.getInt(mContext.getContentResolver(),
7305 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007306 crashApplication(r, crashInfo);
7307 return true;
7308 } else {
7309 return false;
7310 }
7311 }
7312
7313 /**
7314 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7315 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7316 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007317 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007318 if (app == null) {
7319 return null;
7320 }
7321
7322 synchronized (this) {
7323 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7324 final int NA = apps.size();
7325 for (int ia=0; ia<NA; ia++) {
7326 ProcessRecord p = apps.valueAt(ia);
7327 if (p.thread != null && p.thread.asBinder() == app) {
7328 return p;
7329 }
7330 }
7331 }
7332
Dianne Hackborncb44d962011-03-10 17:02:27 -08007333 Slog.w(TAG, "Can't find mystery application for " + reason
7334 + " from pid=" + Binder.getCallingPid()
7335 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007336 return null;
7337 }
7338 }
7339
7340 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007341 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7342 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007343 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007344 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7345 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007346 // Watchdog thread ends up invoking this function (with
7347 // a null ProcessRecord) to add the stack file to dropbox.
7348 // Do not acquire a lock on this (am) in such cases, as it
7349 // could cause a potential deadlock, if and when watchdog
7350 // is invoked due to unavailability of lock on am and it
7351 // would prevent watchdog from killing system_server.
7352 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007353 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007354 return;
7355 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007356 // Note: ProcessRecord 'process' is guarded by the service
7357 // instance. (notably process.pkgList, which could otherwise change
7358 // concurrently during execution of this method)
7359 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007360 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007361 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007362 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007363 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7364 for (String pkg : process.pkgList) {
7365 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007366 try {
Dan Egnora455d192010-03-12 08:52:28 -08007367 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7368 if (pi != null) {
7369 sb.append(" v").append(pi.versionCode);
7370 if (pi.versionName != null) {
7371 sb.append(" (").append(pi.versionName).append(")");
7372 }
7373 }
7374 } catch (RemoteException e) {
7375 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007376 }
Dan Egnora455d192010-03-12 08:52:28 -08007377 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007378 }
Dan Egnora455d192010-03-12 08:52:28 -08007379 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007380 }
7381
7382 private static String processClass(ProcessRecord process) {
7383 if (process == null || process.pid == MY_PID) {
7384 return "system_server";
7385 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7386 return "system_app";
7387 } else {
7388 return "data_app";
7389 }
7390 }
7391
7392 /**
7393 * Write a description of an error (crash, WTF, ANR) to the drop box.
7394 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7395 * @param process which caused the error, null means the system server
7396 * @param activity which triggered the error, null if unknown
7397 * @param parent activity related to the error, null if unknown
7398 * @param subject line related to the error, null if absent
7399 * @param report in long form describing the error, null if absent
7400 * @param logFile to include in the report, null if none
7401 * @param crashInfo giving an application stack trace, null if absent
7402 */
7403 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007404 ProcessRecord process, String processName, ActivityRecord activity,
7405 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007406 final String report, final File logFile,
7407 final ApplicationErrorReport.CrashInfo crashInfo) {
7408 // NOTE -- this must never acquire the ActivityManagerService lock,
7409 // otherwise the watchdog may be prevented from resetting the system.
7410
7411 final String dropboxTag = processClass(process) + "_" + eventType;
7412 final DropBoxManager dbox = (DropBoxManager)
7413 mContext.getSystemService(Context.DROPBOX_SERVICE);
7414
7415 // Exit early if the dropbox isn't configured to accept this report type.
7416 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7417
7418 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007419 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007420 if (activity != null) {
7421 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7422 }
7423 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7424 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7425 }
7426 if (parent != null && parent != activity) {
7427 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7428 }
7429 if (subject != null) {
7430 sb.append("Subject: ").append(subject).append("\n");
7431 }
7432 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007433 if (Debug.isDebuggerConnected()) {
7434 sb.append("Debugger: Connected\n");
7435 }
Dan Egnora455d192010-03-12 08:52:28 -08007436 sb.append("\n");
7437
7438 // Do the rest in a worker thread to avoid blocking the caller on I/O
7439 // (After this point, we shouldn't access AMS internal data structures.)
7440 Thread worker = new Thread("Error dump: " + dropboxTag) {
7441 @Override
7442 public void run() {
7443 if (report != null) {
7444 sb.append(report);
7445 }
7446 if (logFile != null) {
7447 try {
7448 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7449 } catch (IOException e) {
7450 Slog.e(TAG, "Error reading " + logFile, e);
7451 }
7452 }
7453 if (crashInfo != null && crashInfo.stackTrace != null) {
7454 sb.append(crashInfo.stackTrace);
7455 }
7456
7457 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7458 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7459 if (lines > 0) {
7460 sb.append("\n");
7461
7462 // Merge several logcat streams, and take the last N lines
7463 InputStreamReader input = null;
7464 try {
7465 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7466 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7467 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7468
7469 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7470 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7471 input = new InputStreamReader(logcat.getInputStream());
7472
7473 int num;
7474 char[] buf = new char[8192];
7475 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7476 } catch (IOException e) {
7477 Slog.e(TAG, "Error running logcat", e);
7478 } finally {
7479 if (input != null) try { input.close(); } catch (IOException e) {}
7480 }
7481 }
7482
7483 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007484 }
Dan Egnora455d192010-03-12 08:52:28 -08007485 };
7486
7487 if (process == null || process.pid == MY_PID) {
7488 worker.run(); // We may be about to die -- need to run this synchronously
7489 } else {
7490 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007491 }
7492 }
7493
7494 /**
7495 * Bring up the "unexpected error" dialog box for a crashing app.
7496 * Deal with edge cases (intercepts from instrumented applications,
7497 * ActivityController, error intent receivers, that sort of thing).
7498 * @param r the application crashing
7499 * @param crashInfo describing the failure
7500 */
7501 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007502 long timeMillis = System.currentTimeMillis();
7503 String shortMsg = crashInfo.exceptionClassName;
7504 String longMsg = crashInfo.exceptionMessage;
7505 String stackTrace = crashInfo.stackTrace;
7506 if (shortMsg != null && longMsg != null) {
7507 longMsg = shortMsg + ": " + longMsg;
7508 } else if (shortMsg != null) {
7509 longMsg = shortMsg;
7510 }
7511
Dan Egnor60d87622009-12-16 16:32:58 -08007512 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007514 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007515 try {
7516 String name = r != null ? r.processName : null;
7517 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007518 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007519 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007520 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007521 + " at watcher's request");
7522 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007523 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 }
7525 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007526 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 }
7528 }
7529
7530 final long origId = Binder.clearCallingIdentity();
7531
7532 // If this process is running instrumentation, finish it.
7533 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007534 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007535 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007536 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7537 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 Bundle info = new Bundle();
7539 info.putString("shortMsg", shortMsg);
7540 info.putString("longMsg", longMsg);
7541 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7542 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007543 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007544 }
7545
Dan Egnor60d87622009-12-16 16:32:58 -08007546 // If we can't identify the process or it's already exceeded its crash quota,
7547 // quit right away without showing a crash dialog.
7548 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007549 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007550 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007551 }
7552
7553 Message msg = Message.obtain();
7554 msg.what = SHOW_ERROR_MSG;
7555 HashMap data = new HashMap();
7556 data.put("result", result);
7557 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007558 msg.obj = data;
7559 mHandler.sendMessage(msg);
7560
7561 Binder.restoreCallingIdentity(origId);
7562 }
7563
7564 int res = result.get();
7565
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007566 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 synchronized (this) {
7568 if (r != null) {
7569 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7570 SystemClock.uptimeMillis());
7571 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007572 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007573 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007574 }
7575 }
7576
7577 if (appErrorIntent != null) {
7578 try {
7579 mContext.startActivity(appErrorIntent);
7580 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007581 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007584 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007585
7586 Intent createAppErrorIntentLocked(ProcessRecord r,
7587 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7588 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007589 if (report == null) {
7590 return null;
7591 }
7592 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7593 result.setComponent(r.errorReportReceiver);
7594 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7595 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7596 return result;
7597 }
7598
Dan Egnorb7f03672009-12-09 16:22:32 -08007599 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7600 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007601 if (r.errorReportReceiver == null) {
7602 return null;
7603 }
7604
7605 if (!r.crashing && !r.notResponding) {
7606 return null;
7607 }
7608
Dan Egnorb7f03672009-12-09 16:22:32 -08007609 ApplicationErrorReport report = new ApplicationErrorReport();
7610 report.packageName = r.info.packageName;
7611 report.installerPackageName = r.errorReportReceiver.getPackageName();
7612 report.processName = r.processName;
7613 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007614 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007615
Dan Egnorb7f03672009-12-09 16:22:32 -08007616 if (r.crashing) {
7617 report.type = ApplicationErrorReport.TYPE_CRASH;
7618 report.crashInfo = crashInfo;
7619 } else if (r.notResponding) {
7620 report.type = ApplicationErrorReport.TYPE_ANR;
7621 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007622
Dan Egnorb7f03672009-12-09 16:22:32 -08007623 report.anrInfo.activity = r.notRespondingReport.tag;
7624 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7625 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007626 }
7627
Dan Egnorb7f03672009-12-09 16:22:32 -08007628 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007629 }
7630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7632 // assume our apps are happy - lazy create the list
7633 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7634
7635 synchronized (this) {
7636
7637 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007638 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7639 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007640 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7641 // This one's in trouble, so we'll generate a report for it
7642 // crashes are higher priority (in case there's a crash *and* an anr)
7643 ActivityManager.ProcessErrorStateInfo report = null;
7644 if (app.crashing) {
7645 report = app.crashingReport;
7646 } else if (app.notResponding) {
7647 report = app.notRespondingReport;
7648 }
7649
7650 if (report != null) {
7651 if (errList == null) {
7652 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7653 }
7654 errList.add(report);
7655 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007656 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 " crashing = " + app.crashing +
7658 " notResponding = " + app.notResponding);
7659 }
7660 }
7661 }
7662 }
7663
7664 return errList;
7665 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007666
7667 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007668 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007669 if (currApp != null) {
7670 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7671 }
7672 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007673 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7674 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007675 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7676 if (currApp != null) {
7677 currApp.lru = 0;
7678 }
7679 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007680 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007681 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7682 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7683 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7684 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7685 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7686 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7687 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7688 } else {
7689 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7690 }
7691 }
7692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007693 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7694 // Lazy instantiation of list
7695 List<ActivityManager.RunningAppProcessInfo> runList = null;
7696 synchronized (this) {
7697 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007698 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7699 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007700 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7701 // Generate process state info for running application
7702 ActivityManager.RunningAppProcessInfo currApp =
7703 new ActivityManager.RunningAppProcessInfo(app.processName,
7704 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007705 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007706 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007707 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007708 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007709 if (app.persistent) {
7710 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007712 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007713 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007714 currApp.importanceReasonCode = app.adjTypeCode;
7715 if (app.adjSource instanceof ProcessRecord) {
7716 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007717 currApp.importanceReasonImportance = oomAdjToImportance(
7718 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007719 } else if (app.adjSource instanceof ActivityRecord) {
7720 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007721 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7722 }
7723 if (app.adjTarget instanceof ComponentName) {
7724 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7725 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007726 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007727 // + " lru=" + currApp.lru);
7728 if (runList == null) {
7729 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7730 }
7731 runList.add(currApp);
7732 }
7733 }
7734 }
7735 return runList;
7736 }
7737
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007738 public List<ApplicationInfo> getRunningExternalApplications() {
7739 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7740 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7741 if (runningApps != null && runningApps.size() > 0) {
7742 Set<String> extList = new HashSet<String>();
7743 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7744 if (app.pkgList != null) {
7745 for (String pkg : app.pkgList) {
7746 extList.add(pkg);
7747 }
7748 }
7749 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007750 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007751 for (String pkg : extList) {
7752 try {
7753 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7754 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7755 retList.add(info);
7756 }
7757 } catch (RemoteException e) {
7758 }
7759 }
7760 }
7761 return retList;
7762 }
7763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007764 @Override
7765 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007766 if (checkCallingPermission(android.Manifest.permission.DUMP)
7767 != PackageManager.PERMISSION_GRANTED) {
7768 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7769 + Binder.getCallingPid()
7770 + ", uid=" + Binder.getCallingUid()
7771 + " without permission "
7772 + android.Manifest.permission.DUMP);
7773 return;
7774 }
7775
7776 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007777 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778
7779 int opti = 0;
7780 while (opti < args.length) {
7781 String opt = args[opti];
7782 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7783 break;
7784 }
7785 opti++;
7786 if ("-a".equals(opt)) {
7787 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007788 } else if ("-c".equals(opt)) {
7789 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790 } else if ("-h".equals(opt)) {
7791 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007792 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007793 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007794 pw.println(" a[ctivities]: activity stack state");
7795 pw.println(" b[roadcasts]: broadcast state");
7796 pw.println(" i[ntents]: pending intent state");
7797 pw.println(" p[rocesses]: process state");
7798 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007799 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7800 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007801 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007802 pw.println(" all: dump all activities");
7803 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007804 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007805 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7806 pw.println(" a partial substring in a component name, a");
7807 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007808 pw.println(" -a: include all available server state.");
7809 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007810 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007811 } else {
7812 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007813 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007814 }
7815
7816 // Is the caller requesting to dump a particular piece of data?
7817 if (opti < args.length) {
7818 String cmd = args[opti];
7819 opti++;
7820 if ("activities".equals(cmd) || "a".equals(cmd)) {
7821 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007822 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007824 return;
7825 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7826 synchronized (this) {
7827 dumpBroadcastsLocked(fd, pw, args, opti, true);
7828 }
7829 return;
7830 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7831 synchronized (this) {
7832 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7833 }
7834 return;
7835 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7836 synchronized (this) {
7837 dumpProcessesLocked(fd, pw, args, opti, true);
7838 }
7839 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007840 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7841 synchronized (this) {
7842 dumpOomLocked(fd, pw, args, opti, true);
7843 }
7844 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007845 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7846 synchronized (this) {
7847 dumpProvidersLocked(fd, pw, args, opti, true);
7848 }
7849 return;
7850 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007851 String[] newArgs;
7852 String name;
7853 if (opti >= args.length) {
7854 name = null;
7855 newArgs = EMPTY_STRING_ARRAY;
7856 } else {
7857 name = args[opti];
7858 opti++;
7859 newArgs = new String[args.length - opti];
7860 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7861 }
7862 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7863 pw.println("No services match: " + name);
7864 pw.println("Use -h for help.");
7865 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007866 return;
7867 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7868 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007869 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007870 }
7871 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007872 } else {
7873 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007874 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7875 pw.println("Bad activity command, or no activities match: " + cmd);
7876 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007877 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007878 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007879 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007880 }
7881
7882 // No piece of data specified, dump everything.
7883 synchronized (this) {
7884 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007885 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007886 if (needSep) {
7887 pw.println(" ");
7888 }
7889 if (dumpAll) {
7890 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007891 }
7892 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7893 if (needSep) {
7894 pw.println(" ");
7895 }
7896 if (dumpAll) {
7897 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007898 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007899 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900 if (needSep) {
7901 pw.println(" ");
7902 }
7903 if (dumpAll) {
7904 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007905 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007906 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007907 if (needSep) {
7908 pw.println(" ");
7909 }
7910 if (dumpAll) {
7911 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007912 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007913 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007914 if (needSep) {
7915 pw.println(" ");
7916 }
7917 if (dumpAll) {
7918 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007919 }
7920 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7921 }
7922 }
7923
7924 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007925 int opti, boolean dumpAll, boolean dumpClient) {
7926 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7927 pw.println(" Main stack:");
7928 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 pw.println(" ");
7930 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007931 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007932 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007934 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007935 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7936 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007937 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007938 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007940 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007941 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7942 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007943 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007944 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7945 pw.println(" ");
7946 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007947 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7948 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007949 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007950 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007951 pw.println(" ");
7952 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007953 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7954 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007957 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007958 if (mMainStack.mPausingActivity != null) {
7959 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7960 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007961 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007962 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007963 if (dumpAll) {
7964 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7965 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007966 pw.println(" mDismissKeyguardOnNextActivity: "
7967 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007970 if (mRecentTasks.size() > 0) {
7971 pw.println();
7972 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007973
7974 final int N = mRecentTasks.size();
7975 for (int i=0; i<N; i++) {
7976 TaskRecord tr = mRecentTasks.get(i);
7977 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7978 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007979 if (dumpAll) {
7980 mRecentTasks.get(i).dump(pw, " ");
7981 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007982 }
7983 }
7984
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007985 if (dumpAll) {
7986 pw.println(" ");
7987 pw.println(" mCurTask: " + mCurTask);
7988 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007989
7990 return true;
7991 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007992
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007993 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7994 int opti, boolean dumpAll) {
7995 boolean needSep = false;
7996 int numPers = 0;
7997
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007998 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7999
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008000 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8002 final int NA = procs.size();
8003 for (int ia=0; ia<NA; ia++) {
8004 if (!needSep) {
8005 pw.println(" All known processes:");
8006 needSep = true;
8007 }
8008 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008009 pw.print(r.persistent ? " *PERS*" : " *APP*");
8010 pw.print(" UID "); pw.print(procs.keyAt(ia));
8011 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 r.dump(pw, " ");
8013 if (r.persistent) {
8014 numPers++;
8015 }
8016 }
8017 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008018 }
8019
8020 if (mLruProcesses.size() > 0) {
8021 if (needSep) pw.println(" ");
8022 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008023 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008024 dumpProcessOomList(pw, this, mLruProcesses, " ",
8025 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008026 needSep = true;
8027 }
8028
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008029 if (dumpAll) {
8030 synchronized (mPidsSelfLocked) {
8031 if (mPidsSelfLocked.size() > 0) {
8032 if (needSep) pw.println(" ");
8033 needSep = true;
8034 pw.println(" PID mappings:");
8035 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8036 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8037 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 }
8040 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008041 }
8042
8043 if (mForegroundProcesses.size() > 0) {
8044 if (needSep) pw.println(" ");
8045 needSep = true;
8046 pw.println(" Foreground Processes:");
8047 for (int i=0; i<mForegroundProcesses.size(); i++) {
8048 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8049 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008050 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008051 }
8052
8053 if (mPersistentStartingProcesses.size() > 0) {
8054 if (needSep) pw.println(" ");
8055 needSep = true;
8056 pw.println(" Persisent processes that are starting:");
8057 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008058 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008060
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008061 if (mRemovedProcesses.size() > 0) {
8062 if (needSep) pw.println(" ");
8063 needSep = true;
8064 pw.println(" Processes that are being removed:");
8065 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008066 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008067 }
8068
8069 if (mProcessesOnHold.size() > 0) {
8070 if (needSep) pw.println(" ");
8071 needSep = true;
8072 pw.println(" Processes that are on old until the system is ready:");
8073 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008074 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008076
Dianne Hackborn287952c2010-09-22 22:34:31 -07008077 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008078
8079 if (mProcessCrashTimes.getMap().size() > 0) {
8080 if (needSep) pw.println(" ");
8081 needSep = true;
8082 pw.println(" Time since processes crashed:");
8083 long now = SystemClock.uptimeMillis();
8084 for (Map.Entry<String, SparseArray<Long>> procs
8085 : mProcessCrashTimes.getMap().entrySet()) {
8086 SparseArray<Long> uids = procs.getValue();
8087 final int N = uids.size();
8088 for (int i=0; i<N; i++) {
8089 pw.print(" Process "); pw.print(procs.getKey());
8090 pw.print(" uid "); pw.print(uids.keyAt(i));
8091 pw.print(": last crashed ");
8092 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008093 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008094 }
8095 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008097
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008098 if (mBadProcesses.getMap().size() > 0) {
8099 if (needSep) pw.println(" ");
8100 needSep = true;
8101 pw.println(" Bad processes:");
8102 for (Map.Entry<String, SparseArray<Long>> procs
8103 : mBadProcesses.getMap().entrySet()) {
8104 SparseArray<Long> uids = procs.getValue();
8105 final int N = uids.size();
8106 for (int i=0; i<N; i++) {
8107 pw.print(" Bad process "); pw.print(procs.getKey());
8108 pw.print(" uid "); pw.print(uids.keyAt(i));
8109 pw.print(": crashed at time ");
8110 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008111 }
8112 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008114
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008115 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008116 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008117 if (mHeavyWeightProcess != null) {
8118 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8119 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008120 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008121 if (dumpAll) {
8122 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008123 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008124 pw.println(" mScreenCompatPackages:");
8125 for (Map.Entry<String, Integer> entry
8126 : mCompatModePackages.getPackages().entrySet()) {
8127 String pkg = entry.getKey();
8128 int mode = entry.getValue();
8129 pw.print(" "); pw.print(pkg); pw.print(": ");
8130 pw.print(mode); pw.println();
8131 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008132 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008133 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008134 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8135 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8136 || mOrigWaitForDebugger) {
8137 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8138 + " mDebugTransient=" + mDebugTransient
8139 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8140 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008141 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8142 || mProfileFd != null) {
8143 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8144 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8145 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8146 + mAutoStopProfiler);
8147 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008148 if (mAlwaysFinishActivities || mController != null) {
8149 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8150 + " mController=" + mController);
8151 }
8152 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008155 + " mProcessesReady=" + mProcessesReady
8156 + " mSystemReady=" + mSystemReady);
8157 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008158 + " mBooted=" + mBooted
8159 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008160 pw.print(" mLastPowerCheckRealtime=");
8161 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8162 pw.println("");
8163 pw.print(" mLastPowerCheckUptime=");
8164 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8165 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008166 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8167 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008168 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008169 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8170 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008171 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008172
8173 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 }
8175
Dianne Hackborn287952c2010-09-22 22:34:31 -07008176 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8177 int opti, boolean needSep, boolean dumpAll) {
8178 if (mProcessesToGc.size() > 0) {
8179 if (needSep) pw.println(" ");
8180 needSep = true;
8181 pw.println(" Processes that are waiting to GC:");
8182 long now = SystemClock.uptimeMillis();
8183 for (int i=0; i<mProcessesToGc.size(); i++) {
8184 ProcessRecord proc = mProcessesToGc.get(i);
8185 pw.print(" Process "); pw.println(proc);
8186 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8187 pw.print(", last gced=");
8188 pw.print(now-proc.lastRequestedGc);
8189 pw.print(" ms ago, last lowMem=");
8190 pw.print(now-proc.lastLowMemory);
8191 pw.println(" ms ago");
8192
8193 }
8194 }
8195 return needSep;
8196 }
8197
8198 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8199 int opti, boolean dumpAll) {
8200 boolean needSep = false;
8201
8202 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008203 if (needSep) pw.println(" ");
8204 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008205 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008206 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008207 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008208 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8209 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8210 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8211 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8212 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008213 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008214 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008215 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008216 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008217 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008218
8219 if (needSep) pw.println(" ");
8220 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008221 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008222 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008223 "Proc", "PERS", true);
8224 needSep = true;
8225 }
8226
8227 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8228
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008229 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008230 pw.println(" mHomeProcess: " + mHomeProcess);
8231 if (mHeavyWeightProcess != null) {
8232 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8233 }
8234
8235 return true;
8236 }
8237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238 /**
8239 * There are three ways to call this:
8240 * - no service specified: dump all the services
8241 * - a flattened component name that matched an existing service was specified as the
8242 * first arg: dump that one service
8243 * - the first arg isn't the flattened component name of an existing service:
8244 * dump all services whose component contains the first arg as a substring
8245 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008246 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8247 int opti, boolean dumpAll) {
8248 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008249
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008250 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008251 synchronized (this) {
8252 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008253 services.add(r1);
8254 }
8255 }
8256 } else {
8257 ComponentName componentName = name != null
8258 ? ComponentName.unflattenFromString(name) : null;
8259 int objectId = 0;
8260 if (componentName == null) {
8261 // Not a '/' separated full component name; maybe an object ID?
8262 try {
8263 objectId = Integer.parseInt(name, 16);
8264 name = null;
8265 componentName = null;
8266 } catch (RuntimeException e) {
8267 }
8268 }
8269
8270 synchronized (this) {
8271 for (ServiceRecord r1 : mServices.values()) {
8272 if (componentName != null) {
8273 if (r1.name.equals(componentName)) {
8274 services.add(r1);
8275 }
8276 } else if (name != null) {
8277 if (r1.name.flattenToString().contains(name)) {
8278 services.add(r1);
8279 }
8280 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008281 services.add(r1);
8282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 }
8284 }
8285 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008286
8287 if (services.size() <= 0) {
8288 return false;
8289 }
8290
8291 boolean needSep = false;
8292 for (int i=0; i<services.size(); i++) {
8293 if (needSep) {
8294 pw.println();
8295 }
8296 needSep = true;
8297 dumpService("", fd, pw, services.get(i), args, dumpAll);
8298 }
8299 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 }
8301
8302 /**
8303 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8304 * there is a thread associated with the service.
8305 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008306 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8307 final ServiceRecord r, String[] args, boolean dumpAll) {
8308 String innerPrefix = prefix + " ";
8309 synchronized (this) {
8310 pw.print(prefix); pw.print("SERVICE ");
8311 pw.print(r.shortName); pw.print(" ");
8312 pw.print(Integer.toHexString(System.identityHashCode(r)));
8313 pw.print(" pid=");
8314 if (r.app != null) pw.println(r.app.pid);
8315 else pw.println("(not running)");
8316 if (dumpAll) {
8317 r.dump(pw, innerPrefix);
8318 }
8319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008320 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008321 pw.print(prefix); pw.println(" Client:");
8322 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008323 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008324 TransferPipe tp = new TransferPipe();
8325 try {
8326 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8327 tp.setBufferPrefix(prefix + " ");
8328 tp.go(fd);
8329 } finally {
8330 tp.kill();
8331 }
8332 } catch (IOException e) {
8333 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008334 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008335 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008336 }
8337 }
8338 }
8339
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008340 static class ItemMatcher {
8341 ArrayList<ComponentName> components;
8342 ArrayList<String> strings;
8343 ArrayList<Integer> objects;
8344 boolean all;
8345
8346 ItemMatcher() {
8347 all = true;
8348 }
8349
8350 void build(String name) {
8351 ComponentName componentName = ComponentName.unflattenFromString(name);
8352 if (componentName != null) {
8353 if (components == null) {
8354 components = new ArrayList<ComponentName>();
8355 }
8356 components.add(componentName);
8357 all = false;
8358 } else {
8359 int objectId = 0;
8360 // Not a '/' separated full component name; maybe an object ID?
8361 try {
8362 objectId = Integer.parseInt(name, 16);
8363 if (objects == null) {
8364 objects = new ArrayList<Integer>();
8365 }
8366 objects.add(objectId);
8367 all = false;
8368 } catch (RuntimeException e) {
8369 // Not an integer; just do string match.
8370 if (strings == null) {
8371 strings = new ArrayList<String>();
8372 }
8373 strings.add(name);
8374 all = false;
8375 }
8376 }
8377 }
8378
8379 int build(String[] args, int opti) {
8380 for (; opti<args.length; opti++) {
8381 String name = args[opti];
8382 if ("--".equals(name)) {
8383 return opti+1;
8384 }
8385 build(name);
8386 }
8387 return opti;
8388 }
8389
8390 boolean match(Object object, ComponentName comp) {
8391 if (all) {
8392 return true;
8393 }
8394 if (components != null) {
8395 for (int i=0; i<components.size(); i++) {
8396 if (components.get(i).equals(comp)) {
8397 return true;
8398 }
8399 }
8400 }
8401 if (objects != null) {
8402 for (int i=0; i<objects.size(); i++) {
8403 if (System.identityHashCode(object) == objects.get(i)) {
8404 return true;
8405 }
8406 }
8407 }
8408 if (strings != null) {
8409 String flat = comp.flattenToString();
8410 for (int i=0; i<strings.size(); i++) {
8411 if (flat.contains(strings.get(i))) {
8412 return true;
8413 }
8414 }
8415 }
8416 return false;
8417 }
8418 }
8419
Dianne Hackborn625ac272010-09-17 18:29:22 -07008420 /**
8421 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008422 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008423 * - the cmd arg isn't the flattened component name of an existing activity:
8424 * dump all activity whose component contains the cmd as a substring
8425 * - A hex number of the ActivityRecord object instance.
8426 */
8427 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8428 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008429 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008430
8431 if ("all".equals(name)) {
8432 synchronized (this) {
8433 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008434 activities.add(r1);
8435 }
8436 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008437 } else if ("top".equals(name)) {
8438 synchronized (this) {
8439 final int N = mMainStack.mHistory.size();
8440 if (N > 0) {
8441 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8442 }
8443 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008444 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008445 ItemMatcher matcher = new ItemMatcher();
8446 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008447
8448 synchronized (this) {
8449 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008450 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008451 activities.add(r1);
8452 }
8453 }
8454 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008455 }
8456
8457 if (activities.size() <= 0) {
8458 return false;
8459 }
8460
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008461 String[] newArgs = new String[args.length - opti];
8462 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8463
Dianne Hackborn30d71892010-12-11 10:37:55 -08008464 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008465 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008466 for (int i=activities.size()-1; i>=0; i--) {
8467 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008468 if (needSep) {
8469 pw.println();
8470 }
8471 needSep = true;
8472 synchronized (this) {
8473 if (lastTask != r.task) {
8474 lastTask = r.task;
8475 pw.print("TASK "); pw.print(lastTask.affinity);
8476 pw.print(" id="); pw.println(lastTask.taskId);
8477 if (dumpAll) {
8478 lastTask.dump(pw, " ");
8479 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008480 }
8481 }
8482 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008483 }
8484 return true;
8485 }
8486
8487 /**
8488 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8489 * there is a thread associated with the activity.
8490 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008491 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008492 final ActivityRecord r, String[] args, boolean dumpAll) {
8493 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008494 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008495 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8496 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8497 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008498 if (r.app != null) pw.println(r.app.pid);
8499 else pw.println("(not running)");
8500 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008501 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008502 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008503 }
8504 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008505 // flush anything that is already in the PrintWriter since the thread is going
8506 // to write to the file descriptor directly
8507 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008508 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008509 TransferPipe tp = new TransferPipe();
8510 try {
8511 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8512 innerPrefix, args);
8513 tp.go(fd);
8514 } finally {
8515 tp.kill();
8516 }
8517 } catch (IOException e) {
8518 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008519 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008520 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008521 }
8522 }
8523 }
8524
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008525 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8526 int opti, boolean dumpAll) {
8527 boolean needSep = false;
8528
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008529 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008530 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008531 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 pw.println(" Registered Receivers:");
8533 Iterator it = mRegisteredReceivers.values().iterator();
8534 while (it.hasNext()) {
8535 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008536 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008537 r.dump(pw, " ");
8538 }
8539 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008540
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008541 pw.println();
8542 pw.println(" Receiver Resolver Table:");
8543 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008544 needSep = true;
8545 }
8546
8547 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8548 || mPendingBroadcast != null) {
8549 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008550 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008551 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008552 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008553 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8554 pw.println(" Broadcast #" + i + ":");
8555 mParallelBroadcasts.get(i).dump(pw, " ");
8556 }
8557 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008558 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008559 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008560 }
8561 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8562 pw.println(" Serialized Broadcast #" + i + ":");
8563 mOrderedBroadcasts.get(i).dump(pw, " ");
8564 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008565 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008566 pw.println(" Pending broadcast:");
8567 if (mPendingBroadcast != null) {
8568 mPendingBroadcast.dump(pw, " ");
8569 } else {
8570 pw.println(" (null)");
8571 }
8572 needSep = true;
8573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008574
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008575 if (needSep) {
8576 pw.println();
8577 }
8578 pw.println(" Historical broadcasts:");
8579 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8580 BroadcastRecord r = mBroadcastHistory[i];
8581 if (r == null) {
8582 break;
8583 }
8584 if (dumpAll) {
8585 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8586 r.dump(pw, " ");
8587 } else {
8588 if (i >= 50) {
8589 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008590 break;
8591 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008592 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008593 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008594 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008595 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008596
8597 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008598 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008599 pw.println(" Sticky broadcasts:");
8600 StringBuilder sb = new StringBuilder(128);
8601 for (Map.Entry<String, ArrayList<Intent>> ent
8602 : mStickyBroadcasts.entrySet()) {
8603 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008604 if (dumpAll) {
8605 pw.println(":");
8606 ArrayList<Intent> intents = ent.getValue();
8607 final int N = intents.size();
8608 for (int i=0; i<N; i++) {
8609 sb.setLength(0);
8610 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008611 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008612 pw.println(sb.toString());
8613 Bundle bundle = intents.get(i).getExtras();
8614 if (bundle != null) {
8615 pw.print(" ");
8616 pw.println(bundle.toString());
8617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008619 } else {
8620 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 }
8622 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008623 needSep = true;
8624 }
8625
8626 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008627 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008628 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008629 pw.println(" mHandler:");
8630 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008631 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008632 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008633
8634 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008635 }
8636
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008637 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008638 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008639 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008640
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008641 ItemMatcher matcher = new ItemMatcher();
8642 matcher.build(args, opti);
8643
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008644 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8645 if (mServices.size() > 0) {
8646 pw.println(" Active services:");
8647 long nowReal = SystemClock.elapsedRealtime();
8648 Iterator<ServiceRecord> it = mServices.values().iterator();
8649 needSep = false;
8650 while (it.hasNext()) {
8651 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008652 if (!matcher.match(r, r.name)) {
8653 continue;
8654 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008655 if (needSep) {
8656 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008657 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008658 pw.print(" * "); pw.println(r);
8659 if (dumpAll) {
8660 r.dump(pw, " ");
8661 needSep = true;
8662 } else {
8663 pw.print(" app="); pw.println(r.app);
8664 pw.print(" created=");
8665 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8666 pw.print(" started="); pw.print(r.startRequested);
8667 pw.print(" connections="); pw.println(r.connections.size());
8668 }
8669 if (dumpClient && r.app != null && r.app.thread != null) {
8670 pw.println(" Client:");
8671 pw.flush();
8672 try {
8673 TransferPipe tp = new TransferPipe();
8674 try {
8675 r.app.thread.dumpService(
8676 tp.getWriteFd().getFileDescriptor(), r, args);
8677 tp.setBufferPrefix(" ");
8678 // Short timeout, since blocking here can
8679 // deadlock with the application.
8680 tp.go(fd, 2000);
8681 } finally {
8682 tp.kill();
8683 }
8684 } catch (IOException e) {
8685 pw.println(" Failure while dumping the service: " + e);
8686 } catch (RemoteException e) {
8687 pw.println(" Got a RemoteException while dumping the service");
8688 }
8689 needSep = true;
8690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008691 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008692 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008694
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008695 if (mPendingServices.size() > 0) {
8696 if (needSep) pw.println(" ");
8697 pw.println(" Pending services:");
8698 for (int i=0; i<mPendingServices.size(); i++) {
8699 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008700 if (!matcher.match(r, r.name)) {
8701 continue;
8702 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008703 pw.print(" * Pending "); pw.println(r);
8704 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008706 needSep = true;
8707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008709 if (mRestartingServices.size() > 0) {
8710 if (needSep) pw.println(" ");
8711 pw.println(" Restarting services:");
8712 for (int i=0; i<mRestartingServices.size(); i++) {
8713 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008714 if (!matcher.match(r, r.name)) {
8715 continue;
8716 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008717 pw.print(" * Restarting "); pw.println(r);
8718 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008719 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008720 needSep = true;
8721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008722
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008723 if (mStoppingServices.size() > 0) {
8724 if (needSep) pw.println(" ");
8725 pw.println(" Stopping services:");
8726 for (int i=0; i<mStoppingServices.size(); i++) {
8727 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008728 if (!matcher.match(r, r.name)) {
8729 continue;
8730 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008731 pw.print(" * Stopping "); pw.println(r);
8732 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008734 needSep = true;
8735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008736
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008737 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008738 if (mServiceConnections.size() > 0) {
8739 if (needSep) pw.println(" ");
8740 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008741 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742 = mServiceConnections.values().iterator();
8743 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008744 ArrayList<ConnectionRecord> r = it.next();
8745 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008746 ConnectionRecord cr = r.get(i);
8747 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8748 continue;
8749 }
8750 pw.print(" * "); pw.println(cr);
8751 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008753 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008754 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008755 }
8756 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008757
8758 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 }
8760
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008761 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8762 int opti, boolean dumpAll) {
8763 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008764
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008765 ItemMatcher matcher = new ItemMatcher();
8766 matcher.build(args, opti);
8767
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8769 if (mProvidersByClass.size() > 0) {
8770 if (needSep) pw.println(" ");
8771 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008772 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008773 = mProvidersByClass.entrySet().iterator();
8774 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008775 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008776 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008777 ComponentName comp = e.getKey();
8778 String cls = comp.getClassName();
8779 int end = cls.lastIndexOf('.');
8780 if (end > 0 && end < (cls.length()-2)) {
8781 cls = cls.substring(end+1);
8782 }
8783 if (!matcher.match(r, comp)) {
8784 continue;
8785 }
8786 pw.print(" * "); pw.print(cls); pw.print(" (");
8787 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008788 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008789 pw.println();
8790 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008791 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008792 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008793 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008794 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008795 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008796 } else {
8797 pw.println();
8798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008800 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008801 needSep = true;
8802 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008803
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008804 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008805 if (mProvidersByName.size() > 0) {
8806 pw.println(" ");
8807 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008808 Iterator<Map.Entry<String, ContentProviderRecord>> it
8809 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008810 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008811 Map.Entry<String, ContentProviderRecord> e = it.next();
8812 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008813 if (!matcher.match(r, r.name)) {
8814 continue;
8815 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008816 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8817 pw.println(r);
8818 }
8819 needSep = true;
8820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008822
8823 if (mLaunchingProviders.size() > 0) {
8824 if (needSep) pw.println(" ");
8825 pw.println(" Launching content providers:");
8826 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8827 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8828 pw.println(mLaunchingProviders.get(i));
8829 }
8830 needSep = true;
8831 }
8832
8833 if (mGrantedUriPermissions.size() > 0) {
8834 pw.println();
8835 pw.println("Granted Uri Permissions:");
8836 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8837 int uid = mGrantedUriPermissions.keyAt(i);
8838 HashMap<Uri, UriPermission> perms
8839 = mGrantedUriPermissions.valueAt(i);
8840 pw.print(" * UID "); pw.print(uid);
8841 pw.println(" holds:");
8842 for (UriPermission perm : perms.values()) {
8843 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008844 if (dumpAll) {
8845 perm.dump(pw, " ");
8846 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008847 }
8848 }
8849 needSep = true;
8850 }
8851
8852 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008853 }
8854
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008855 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8856 int opti, boolean dumpAll) {
8857 boolean needSep = false;
8858
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008859 if (this.mIntentSenderRecords.size() > 0) {
8860 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8861 Iterator<WeakReference<PendingIntentRecord>> it
8862 = mIntentSenderRecords.values().iterator();
8863 while (it.hasNext()) {
8864 WeakReference<PendingIntentRecord> ref = it.next();
8865 PendingIntentRecord rec = ref != null ? ref.get(): null;
8866 needSep = true;
8867 if (rec != null) {
8868 pw.print(" * "); pw.println(rec);
8869 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008870 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008871 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008872 } else {
8873 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008874 }
8875 }
8876 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008877
8878 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 }
8880
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008881 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8882 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008884 boolean needNL = false;
8885 final String innerPrefix = prefix + " ";
8886 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008887 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008889 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008890 if (needNL) {
8891 pw.println(" ");
8892 needNL = false;
8893 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008894 if (lastTask != r.task) {
8895 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008896 pw.print(prefix);
8897 pw.print(full ? "* " : " ");
8898 pw.println(lastTask);
8899 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008900 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008901 } else if (complete) {
8902 // Complete + brief == give a summary. Isn't that obvious?!?
8903 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008904 pw.print(prefix); pw.print(" ");
8905 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008906 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008908 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008909 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8910 pw.print(" #"); pw.print(i); pw.print(": ");
8911 pw.println(r);
8912 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008913 r.dump(pw, innerPrefix);
8914 } else if (complete) {
8915 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008916 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008917 if (r.app != null) {
8918 pw.print(innerPrefix); pw.println(r.app);
8919 }
8920 }
8921 if (client && r.app != null && r.app.thread != null) {
8922 // flush anything that is already in the PrintWriter since the thread is going
8923 // to write to the file descriptor directly
8924 pw.flush();
8925 try {
8926 TransferPipe tp = new TransferPipe();
8927 try {
8928 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8929 innerPrefix, args);
8930 // Short timeout, since blocking here can
8931 // deadlock with the application.
8932 tp.go(fd, 2000);
8933 } finally {
8934 tp.kill();
8935 }
8936 } catch (IOException e) {
8937 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8938 } catch (RemoteException e) {
8939 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8940 }
8941 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008943 }
8944 }
8945
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008946 private static String buildOomTag(String prefix, String space, int val, int base) {
8947 if (val == base) {
8948 if (space == null) return prefix;
8949 return prefix + " ";
8950 }
8951 return prefix + "+" + Integer.toString(val-base);
8952 }
8953
8954 private static final int dumpProcessList(PrintWriter pw,
8955 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008956 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008957 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008958 final int N = list.size()-1;
8959 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008960 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008961 pw.println(String.format("%s%s #%2d: %s",
8962 prefix, (r.persistent ? persistentLabel : normalLabel),
8963 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008964 if (r.persistent) {
8965 numPers++;
8966 }
8967 }
8968 return numPers;
8969 }
8970
Dianne Hackborn287952c2010-09-22 22:34:31 -07008971 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008972 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008973 String prefix, String normalLabel, String persistentLabel,
8974 boolean inclDetails) {
8975
Dianne Hackborn905577f2011-09-07 18:31:28 -07008976 ArrayList<Pair<ProcessRecord, Integer>> list
8977 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8978 for (int i=0; i<origList.size(); i++) {
8979 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8980 }
8981
8982 Comparator<Pair<ProcessRecord, Integer>> comparator
8983 = new Comparator<Pair<ProcessRecord, Integer>>() {
8984 @Override
8985 public int compare(Pair<ProcessRecord, Integer> object1,
8986 Pair<ProcessRecord, Integer> object2) {
8987 if (object1.first.setAdj != object2.first.setAdj) {
8988 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8989 }
8990 if (object1.second.intValue() != object2.second.intValue()) {
8991 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8992 }
8993 return 0;
8994 }
8995 };
8996
8997 Collections.sort(list, comparator);
8998
Dianne Hackborn287952c2010-09-22 22:34:31 -07008999 final long curRealtime = SystemClock.elapsedRealtime();
9000 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9001 final long curUptime = SystemClock.uptimeMillis();
9002 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9003
9004 final int N = list.size()-1;
9005 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009006 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009007 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009008 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009009 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009010 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9011 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009012 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9013 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009014 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9015 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009016 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9017 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9018 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9019 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9020 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9021 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9022 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9023 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9024 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9025 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009026 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9027 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009028 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9029 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009030 } else {
9031 oomAdj = Integer.toString(r.setAdj);
9032 }
9033 String schedGroup;
9034 switch (r.setSchedGroup) {
9035 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9036 schedGroup = "B";
9037 break;
9038 case Process.THREAD_GROUP_DEFAULT:
9039 schedGroup = "F";
9040 break;
9041 default:
9042 schedGroup = Integer.toString(r.setSchedGroup);
9043 break;
9044 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009045 String foreground;
9046 if (r.foregroundActivities) {
9047 foreground = "A";
9048 } else if (r.foregroundServices) {
9049 foreground = "S";
9050 } else {
9051 foreground = " ";
9052 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009053 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009054 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009055 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009056 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009057 if (r.adjSource != null || r.adjTarget != null) {
9058 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009059 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009060 if (r.adjTarget instanceof ComponentName) {
9061 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9062 } else if (r.adjTarget != null) {
9063 pw.print(r.adjTarget.toString());
9064 } else {
9065 pw.print("{null}");
9066 }
9067 pw.print("<=");
9068 if (r.adjSource instanceof ProcessRecord) {
9069 pw.print("Proc{");
9070 pw.print(((ProcessRecord)r.adjSource).toShortString());
9071 pw.println("}");
9072 } else if (r.adjSource != null) {
9073 pw.println(r.adjSource.toString());
9074 } else {
9075 pw.println("{null}");
9076 }
9077 }
9078 if (inclDetails) {
9079 pw.print(prefix);
9080 pw.print(" ");
9081 pw.print("oom: max="); pw.print(r.maxAdj);
9082 pw.print(" hidden="); pw.print(r.hiddenAdj);
9083 pw.print(" curRaw="); pw.print(r.curRawAdj);
9084 pw.print(" setRaw="); pw.print(r.setRawAdj);
9085 pw.print(" cur="); pw.print(r.curAdj);
9086 pw.print(" set="); pw.println(r.setAdj);
9087 pw.print(prefix);
9088 pw.print(" ");
9089 pw.print("keeping="); pw.print(r.keeping);
9090 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009091 pw.print(" empty="); pw.print(r.empty);
9092 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009093
9094 if (!r.keeping) {
9095 if (r.lastWakeTime != 0) {
9096 long wtime;
9097 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9098 synchronized (stats) {
9099 wtime = stats.getProcessWakeTime(r.info.uid,
9100 r.pid, curRealtime);
9101 }
9102 long timeUsed = wtime - r.lastWakeTime;
9103 pw.print(prefix);
9104 pw.print(" ");
9105 pw.print("keep awake over ");
9106 TimeUtils.formatDuration(realtimeSince, pw);
9107 pw.print(" used ");
9108 TimeUtils.formatDuration(timeUsed, pw);
9109 pw.print(" (");
9110 pw.print((timeUsed*100)/realtimeSince);
9111 pw.println("%)");
9112 }
9113 if (r.lastCpuTime != 0) {
9114 long timeUsed = r.curCpuTime - r.lastCpuTime;
9115 pw.print(prefix);
9116 pw.print(" ");
9117 pw.print("run cpu over ");
9118 TimeUtils.formatDuration(uptimeSince, pw);
9119 pw.print(" used ");
9120 TimeUtils.formatDuration(timeUsed, pw);
9121 pw.print(" (");
9122 pw.print((timeUsed*100)/uptimeSince);
9123 pw.println("%)");
9124 }
9125 }
9126 }
9127 }
9128 }
9129
Dianne Hackbornb437e092011-08-05 17:50:29 -07009130 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009131 ArrayList<ProcessRecord> procs;
9132 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009133 if (args != null && args.length > start
9134 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009135 procs = new ArrayList<ProcessRecord>();
9136 int pid = -1;
9137 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009138 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009139 } catch (NumberFormatException e) {
9140
9141 }
9142 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9143 ProcessRecord proc = mLruProcesses.get(i);
9144 if (proc.pid == pid) {
9145 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009146 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009147 procs.add(proc);
9148 }
9149 }
9150 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009151 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009152 return null;
9153 }
9154 } else {
9155 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9156 }
9157 }
9158 return procs;
9159 }
9160
9161 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9162 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009163 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009164 if (procs == null) {
9165 return;
9166 }
9167
9168 long uptime = SystemClock.uptimeMillis();
9169 long realtime = SystemClock.elapsedRealtime();
9170 pw.println("Applications Graphics Acceleration Info:");
9171 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9172
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009173 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9174 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009175 if (r.thread != null) {
9176 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9177 pw.flush();
9178 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009179 TransferPipe tp = new TransferPipe();
9180 try {
9181 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9182 tp.go(fd);
9183 } finally {
9184 tp.kill();
9185 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009186 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009187 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009188 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009189 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009190 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009191 pw.flush();
9192 }
9193 }
9194 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009195 }
9196
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009197 final static class MemItem {
9198 final String label;
9199 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009200 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009201
9202 public MemItem(String _label, long _pss) {
9203 label = _label;
9204 pss = _pss;
9205 }
9206 }
9207
Dianne Hackbornb437e092011-08-05 17:50:29 -07009208 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9209 boolean sort) {
9210 if (sort) {
9211 Collections.sort(items, new Comparator<MemItem>() {
9212 @Override
9213 public int compare(MemItem lhs, MemItem rhs) {
9214 if (lhs.pss < rhs.pss) {
9215 return 1;
9216 } else if (lhs.pss > rhs.pss) {
9217 return -1;
9218 }
9219 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009220 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009221 });
9222 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009223
9224 for (int i=0; i<items.size(); i++) {
9225 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009226 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9227 if (mi.subitems != null) {
9228 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9229 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009230 }
9231 }
9232
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009233 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9234 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009235 boolean dumpAll = false;
9236
9237 int opti = 0;
9238 while (opti < args.length) {
9239 String opt = args[opti];
9240 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9241 break;
9242 }
9243 opti++;
9244 if ("-a".equals(opt)) {
9245 dumpAll = true;
9246 } else if ("-h".equals(opt)) {
9247 pw.println("meminfo dump options: [-a] [process]");
9248 pw.println(" -a: include all available information for each process.");
9249 pw.println("If [process] is specified it can be the name or ");
9250 pw.println("pid of a specific process to dump.");
9251 return;
9252 } else {
9253 pw.println("Unknown argument: " + opt + "; use -h for help");
9254 }
9255 }
9256
9257 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009258 if (procs == null) {
9259 return;
9260 }
9261
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009262 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009263 long uptime = SystemClock.uptimeMillis();
9264 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009265
9266 if (procs.size() == 1 || isCheckinRequest) {
9267 dumpAll = true;
9268 }
9269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009270 if (isCheckinRequest) {
9271 // short checkin version
9272 pw.println(uptime + "," + realtime);
9273 pw.flush();
9274 } else {
9275 pw.println("Applications Memory Usage (kB):");
9276 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9277 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009278
Dianne Hackbornb437e092011-08-05 17:50:29 -07009279 String[] innerArgs = new String[args.length-opti];
9280 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9281
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009282 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9283 long nativePss=0, dalvikPss=0, otherPss=0;
9284 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9285
Dianne Hackbornb437e092011-08-05 17:50:29 -07009286 final int[] oomAdj = new int[] {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009287 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
Dianne Hackborn7d608422011-08-07 16:24:18 -07009288 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009289 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9290 ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009291 };
9292 final String[] oomLabel = new String[] {
9293 "System", "Persistent", "Foreground",
9294 "Visible", "Perceptible", "Heavy Weight",
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009295 "Backup", "A Services", "Home", "B Services", "Background"
Dianne Hackbornb437e092011-08-05 17:50:29 -07009296 };
9297 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009298 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009299
9300 long totalPss = 0;
9301
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009302 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9303 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009304 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009305 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9307 pw.flush();
9308 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009309 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009310 if (dumpAll) {
9311 try {
9312 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9313 } catch (RemoteException e) {
9314 if (!isCheckinRequest) {
9315 pw.println("Got RemoteException!");
9316 pw.flush();
9317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009319 } else {
9320 mi = new Debug.MemoryInfo();
9321 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009322 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009323
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009324 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009325 long myTotalPss = mi.getTotalPss();
9326 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009327 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9328 myTotalPss);
9329 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009330
9331 nativePss += mi.nativePss;
9332 dalvikPss += mi.dalvikPss;
9333 otherPss += mi.otherPss;
9334 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9335 long mem = mi.getOtherPss(j);
9336 miscPss[j] += mem;
9337 otherPss -= mem;
9338 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009339
9340 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9341 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9342 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009343 if (oomProcs[oomIndex] == null) {
9344 oomProcs[oomIndex] = new ArrayList<MemItem>();
9345 }
9346 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009347 break;
9348 }
9349 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009351 }
9352 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009353
9354 if (!isCheckinRequest && procs.size() > 1) {
9355 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9356
9357 catMems.add(new MemItem("Native", nativePss));
9358 catMems.add(new MemItem("Dalvik", dalvikPss));
9359 catMems.add(new MemItem("Unknown", otherPss));
9360 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9361 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9362 }
9363
Dianne Hackbornb437e092011-08-05 17:50:29 -07009364 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9365 for (int j=0; j<oomPss.length; j++) {
9366 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009367 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9368 item.subitems = oomProcs[j];
9369 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009370 }
9371 }
9372
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009373 pw.println();
9374 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009375 dumpMemItems(pw, " ", procMems, true);
9376 pw.println();
9377 pw.println("Total PSS by OOM adjustment:");
9378 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009379 pw.println();
9380 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009381 dumpMemItems(pw, " ", catMems, true);
9382 pw.println();
9383 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009385 }
9386
9387 /**
9388 * Searches array of arguments for the specified string
9389 * @param args array of argument strings
9390 * @param value value to search for
9391 * @return true if the value is contained in the array
9392 */
9393 private static boolean scanArgs(String[] args, String value) {
9394 if (args != null) {
9395 for (String arg : args) {
9396 if (value.equals(arg)) {
9397 return true;
9398 }
9399 }
9400 }
9401 return false;
9402 }
9403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009404 private final void killServicesLocked(ProcessRecord app,
9405 boolean allowRestart) {
9406 // Report disconnected services.
9407 if (false) {
9408 // XXX we are letting the client link to the service for
9409 // death notifications.
9410 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009411 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009412 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009413 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009414 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009415 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009416 = r.connections.values().iterator();
9417 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009418 ArrayList<ConnectionRecord> cl = jt.next();
9419 for (int i=0; i<cl.size(); i++) {
9420 ConnectionRecord c = cl.get(i);
9421 if (c.binding.client != app) {
9422 try {
9423 //c.conn.connected(r.className, null);
9424 } catch (Exception e) {
9425 // todo: this should be asynchronous!
9426 Slog.w(TAG, "Exception thrown disconnected servce "
9427 + r.shortName
9428 + " from app " + app.processName, e);
9429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009430 }
9431 }
9432 }
9433 }
9434 }
9435 }
9436 }
9437
9438 // Clean up any connections this application has to other services.
9439 if (app.connections.size() > 0) {
9440 Iterator<ConnectionRecord> it = app.connections.iterator();
9441 while (it.hasNext()) {
9442 ConnectionRecord r = it.next();
9443 removeConnectionLocked(r, app, null);
9444 }
9445 }
9446 app.connections.clear();
9447
9448 if (app.services.size() != 0) {
9449 // Any services running in the application need to be placed
9450 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009451 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009452 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009453 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 synchronized (sr.stats.getBatteryStats()) {
9455 sr.stats.stopLaunchedLocked();
9456 }
9457 sr.app = null;
9458 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009459 if (mStoppingServices.remove(sr)) {
9460 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9461 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009462
9463 boolean hasClients = sr.bindings.size() > 0;
9464 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009465 Iterator<IntentBindRecord> bindings
9466 = sr.bindings.values().iterator();
9467 while (bindings.hasNext()) {
9468 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009469 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009470 + ": shouldUnbind=" + b.hasBound);
9471 b.binder = null;
9472 b.requested = b.received = b.hasBound = false;
9473 }
9474 }
9475
Dianne Hackborn070783f2010-12-29 16:46:28 -08009476 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9477 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009478 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009479 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009480 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009481 sr.crashCount, sr.shortName, app.pid);
9482 bringDownServiceLocked(sr, true);
9483 } else if (!allowRestart) {
9484 bringDownServiceLocked(sr, true);
9485 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009486 boolean canceled = scheduleServiceRestartLocked(sr, true);
9487
9488 // Should the service remain running? Note that in the
9489 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009490 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009491 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9492 if (sr.pendingStarts.size() == 0) {
9493 sr.startRequested = false;
9494 if (!hasClients) {
9495 // Whoops, no reason to restart!
9496 bringDownServiceLocked(sr, true);
9497 }
9498 }
9499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 }
9501 }
9502
9503 if (!allowRestart) {
9504 app.services.clear();
9505 }
9506 }
9507
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009508 // Make sure we have no more records on the stopping list.
9509 int i = mStoppingServices.size();
9510 while (i > 0) {
9511 i--;
9512 ServiceRecord sr = mStoppingServices.get(i);
9513 if (sr.app == app) {
9514 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009515 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009516 }
9517 }
9518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009519 app.executingServices.clear();
9520 }
9521
9522 private final void removeDyingProviderLocked(ProcessRecord proc,
9523 ContentProviderRecord cpr) {
9524 synchronized (cpr) {
9525 cpr.launchingApp = null;
9526 cpr.notifyAll();
9527 }
9528
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009529 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009530 String names[] = cpr.info.authority.split(";");
9531 for (int j = 0; j < names.length; j++) {
9532 mProvidersByName.remove(names[j]);
9533 }
9534
9535 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9536 while (cit.hasNext()) {
9537 ProcessRecord capp = cit.next();
9538 if (!capp.persistent && capp.thread != null
9539 && capp.pid != 0
9540 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009541 Slog.i(TAG, "Kill " + capp.processName
9542 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009543 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009544 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009545 capp.processName, capp.setAdj, "dying provider "
9546 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009547 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009548 }
9549 }
9550
9551 mLaunchingProviders.remove(cpr);
9552 }
9553
9554 /**
9555 * Main code for cleaning up a process when it has gone away. This is
9556 * called both as a result of the process dying, or directly when stopping
9557 * a process when running in single process mode.
9558 */
9559 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009560 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009561 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009562 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 }
9564
Dianne Hackborn36124872009-10-08 16:22:03 -07009565 mProcessesToGc.remove(app);
9566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 // Dismiss any open dialogs.
9568 if (app.crashDialog != null) {
9569 app.crashDialog.dismiss();
9570 app.crashDialog = null;
9571 }
9572 if (app.anrDialog != null) {
9573 app.anrDialog.dismiss();
9574 app.anrDialog = null;
9575 }
9576 if (app.waitDialog != null) {
9577 app.waitDialog.dismiss();
9578 app.waitDialog = null;
9579 }
9580
9581 app.crashing = false;
9582 app.notResponding = false;
9583
9584 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009585 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009586 app.thread = null;
9587 app.forcingToForeground = null;
9588 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009589 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009590 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009591 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009592
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009593 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009594
9595 boolean restart = false;
9596
9597 int NL = mLaunchingProviders.size();
9598
9599 // Remove published content providers.
9600 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009601 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009602 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009603 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009605 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606
9607 // See if someone is waiting for this provider... in which
9608 // case we don't remove it, but just let it restart.
9609 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009610 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009611 for (; i<NL; i++) {
9612 if (mLaunchingProviders.get(i) == cpr) {
9613 restart = true;
9614 break;
9615 }
9616 }
9617 } else {
9618 i = NL;
9619 }
9620
9621 if (i >= NL) {
9622 removeDyingProviderLocked(app, cpr);
9623 NL = mLaunchingProviders.size();
9624 }
9625 }
9626 app.pubProviders.clear();
9627 }
9628
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009629 // Take care of any launching providers waiting for this process.
9630 if (checkAppInLaunchingProvidersLocked(app, false)) {
9631 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 // Unregister from connected content providers.
9635 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009636 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009637 while (it.hasNext()) {
9638 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9639 cpr.clients.remove(app);
9640 }
9641 app.conProviders.clear();
9642 }
9643
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009644 // At this point there may be remaining entries in mLaunchingProviders
9645 // where we were the only one waiting, so they are no longer of use.
9646 // Look for these and clean up if found.
9647 // XXX Commented out for now. Trying to figure out a way to reproduce
9648 // the actual situation to identify what is actually going on.
9649 if (false) {
9650 for (int i=0; i<NL; i++) {
9651 ContentProviderRecord cpr = (ContentProviderRecord)
9652 mLaunchingProviders.get(i);
9653 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9654 synchronized (cpr) {
9655 cpr.launchingApp = null;
9656 cpr.notifyAll();
9657 }
9658 }
9659 }
9660 }
9661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009662 skipCurrentReceiverLocked(app);
9663
9664 // Unregister any receivers.
9665 if (app.receivers.size() > 0) {
9666 Iterator<ReceiverList> it = app.receivers.iterator();
9667 while (it.hasNext()) {
9668 removeReceiverLocked(it.next());
9669 }
9670 app.receivers.clear();
9671 }
9672
Christopher Tate181fafa2009-05-14 11:12:14 -07009673 // If the app is undergoing backup, tell the backup manager about it
9674 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009675 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009676 try {
9677 IBackupManager bm = IBackupManager.Stub.asInterface(
9678 ServiceManager.getService(Context.BACKUP_SERVICE));
9679 bm.agentDisconnected(app.info.packageName);
9680 } catch (RemoteException e) {
9681 // can't happen; backup manager is local
9682 }
9683 }
9684
Jeff Sharkey287bd832011-05-28 19:36:26 -07009685 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009687 // If the caller is restarting this app, then leave it in its
9688 // current lists and let the caller take care of it.
9689 if (restarting) {
9690 return;
9691 }
9692
9693 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009694 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009695 "Removing non-persistent process during cleanup: " + app);
9696 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009697 if (mHeavyWeightProcess == app) {
9698 mHeavyWeightProcess = null;
9699 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009701 } else if (!app.removed) {
9702 // This app is persistent, so we need to keep its record around.
9703 // If it is not already on the pending app list, add it there
9704 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009705 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9706 mPersistentStartingProcesses.add(app);
9707 restart = true;
9708 }
9709 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009710 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9711 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009712 mProcessesOnHold.remove(app);
9713
The Android Open Source Project4df24232009-03-05 14:34:35 -08009714 if (app == mHomeProcess) {
9715 mHomeProcess = null;
9716 }
9717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009718 if (restart) {
9719 // We have components that still need to be running in the
9720 // process, so re-launch it.
9721 mProcessNames.put(app.processName, app.info.uid, app);
9722 startProcessLocked(app, "restart", app.processName);
9723 } else if (app.pid > 0 && app.pid != MY_PID) {
9724 // Goodbye!
9725 synchronized (mPidsSelfLocked) {
9726 mPidsSelfLocked.remove(app.pid);
9727 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9728 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009729 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009730 }
9731 }
9732
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009733 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9734 // Look through the content providers we are waiting to have launched,
9735 // and if any run in this process then either schedule a restart of
9736 // the process or kill the client waiting for it if this process has
9737 // gone bad.
9738 int NL = mLaunchingProviders.size();
9739 boolean restart = false;
9740 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009741 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009742 if (cpr.launchingApp == app) {
9743 if (!alwaysBad && !app.bad) {
9744 restart = true;
9745 } else {
9746 removeDyingProviderLocked(app, cpr);
9747 NL = mLaunchingProviders.size();
9748 }
9749 }
9750 }
9751 return restart;
9752 }
9753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754 // =========================================================
9755 // SERVICES
9756 // =========================================================
9757
9758 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9759 ActivityManager.RunningServiceInfo info =
9760 new ActivityManager.RunningServiceInfo();
9761 info.service = r.name;
9762 if (r.app != null) {
9763 info.pid = r.app.pid;
9764 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009765 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 info.process = r.processName;
9767 info.foreground = r.isForeground;
9768 info.activeSince = r.createTime;
9769 info.started = r.startRequested;
9770 info.clientCount = r.connections.size();
9771 info.crashCount = r.crashCount;
9772 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009773 if (r.isForeground) {
9774 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9775 }
9776 if (r.startRequested) {
9777 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9778 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009779 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009780 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9781 }
9782 if (r.app != null && r.app.persistent) {
9783 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9784 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009785
9786 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9787 for (int i=0; i<connl.size(); i++) {
9788 ConnectionRecord conn = connl.get(i);
9789 if (conn.clientLabel != 0) {
9790 info.clientPackage = conn.binding.client.info.packageName;
9791 info.clientLabel = conn.clientLabel;
9792 return info;
9793 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009794 }
9795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009796 return info;
9797 }
9798
9799 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9800 int flags) {
9801 synchronized (this) {
9802 ArrayList<ActivityManager.RunningServiceInfo> res
9803 = new ArrayList<ActivityManager.RunningServiceInfo>();
9804
9805 if (mServices.size() > 0) {
9806 Iterator<ServiceRecord> it = mServices.values().iterator();
9807 while (it.hasNext() && res.size() < maxNum) {
9808 res.add(makeRunningServiceInfoLocked(it.next()));
9809 }
9810 }
9811
9812 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9813 ServiceRecord r = mRestartingServices.get(i);
9814 ActivityManager.RunningServiceInfo info =
9815 makeRunningServiceInfoLocked(r);
9816 info.restarting = r.nextRestartTime;
9817 res.add(info);
9818 }
9819
9820 return res;
9821 }
9822 }
9823
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009824 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9825 synchronized (this) {
9826 ServiceRecord r = mServices.get(name);
9827 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009828 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9829 for (int i=0; i<conn.size(); i++) {
9830 if (conn.get(i).clientIntent != null) {
9831 return conn.get(i).clientIntent;
9832 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009833 }
9834 }
9835 }
9836 }
9837 return null;
9838 }
9839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 private final ServiceRecord findServiceLocked(ComponentName name,
9841 IBinder token) {
9842 ServiceRecord r = mServices.get(name);
9843 return r == token ? r : null;
9844 }
9845
9846 private final class ServiceLookupResult {
9847 final ServiceRecord record;
9848 final String permission;
9849
9850 ServiceLookupResult(ServiceRecord _record, String _permission) {
9851 record = _record;
9852 permission = _permission;
9853 }
9854 };
9855
9856 private ServiceLookupResult findServiceLocked(Intent service,
9857 String resolvedType) {
9858 ServiceRecord r = null;
9859 if (service.getComponent() != null) {
9860 r = mServices.get(service.getComponent());
9861 }
9862 if (r == null) {
9863 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9864 r = mServicesByIntent.get(filter);
9865 }
9866
9867 if (r == null) {
9868 try {
9869 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009870 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009871 service, resolvedType, 0);
9872 ServiceInfo sInfo =
9873 rInfo != null ? rInfo.serviceInfo : null;
9874 if (sInfo == null) {
9875 return null;
9876 }
9877
9878 ComponentName name = new ComponentName(
9879 sInfo.applicationInfo.packageName, sInfo.name);
9880 r = mServices.get(name);
9881 } catch (RemoteException ex) {
9882 // pm is in same process, this will never happen.
9883 }
9884 }
9885 if (r != null) {
9886 int callingPid = Binder.getCallingPid();
9887 int callingUid = Binder.getCallingUid();
9888 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009889 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009890 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009891 if (!r.exported) {
9892 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9893 + " from pid=" + callingPid
9894 + ", uid=" + callingUid
9895 + " that is not exported from uid " + r.appInfo.uid);
9896 return new ServiceLookupResult(null, "not exported from uid "
9897 + r.appInfo.uid);
9898 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009899 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009900 + " from pid=" + callingPid
9901 + ", uid=" + callingUid
9902 + " requires " + r.permission);
9903 return new ServiceLookupResult(null, r.permission);
9904 }
9905 return new ServiceLookupResult(r, null);
9906 }
9907 return null;
9908 }
9909
9910 private class ServiceRestarter implements Runnable {
9911 private ServiceRecord mService;
9912
9913 void setService(ServiceRecord service) {
9914 mService = service;
9915 }
9916
9917 public void run() {
9918 synchronized(ActivityManagerService.this) {
9919 performServiceRestartLocked(mService);
9920 }
9921 }
9922 }
9923
9924 private ServiceLookupResult retrieveServiceLocked(Intent service,
9925 String resolvedType, int callingPid, int callingUid) {
9926 ServiceRecord r = null;
9927 if (service.getComponent() != null) {
9928 r = mServices.get(service.getComponent());
9929 }
9930 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9931 r = mServicesByIntent.get(filter);
9932 if (r == null) {
9933 try {
9934 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009935 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009936 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 ServiceInfo sInfo =
9938 rInfo != null ? rInfo.serviceInfo : null;
9939 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009940 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009941 ": not found");
9942 return null;
9943 }
9944
9945 ComponentName name = new ComponentName(
9946 sInfo.applicationInfo.packageName, sInfo.name);
9947 r = mServices.get(name);
9948 if (r == null) {
9949 filter = new Intent.FilterComparison(service.cloneFilter());
9950 ServiceRestarter res = new ServiceRestarter();
9951 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9952 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9953 synchronized (stats) {
9954 ss = stats.getServiceStatsLocked(
9955 sInfo.applicationInfo.uid, sInfo.packageName,
9956 sInfo.name);
9957 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009958 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009959 res.setService(r);
9960 mServices.put(name, r);
9961 mServicesByIntent.put(filter, r);
9962
9963 // Make sure this component isn't in the pending list.
9964 int N = mPendingServices.size();
9965 for (int i=0; i<N; i++) {
9966 ServiceRecord pr = mPendingServices.get(i);
9967 if (pr.name.equals(name)) {
9968 mPendingServices.remove(i);
9969 i--;
9970 N--;
9971 }
9972 }
9973 }
9974 } catch (RemoteException ex) {
9975 // pm is in same process, this will never happen.
9976 }
9977 }
9978 if (r != null) {
9979 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009980 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009982 if (!r.exported) {
9983 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9984 + " from pid=" + callingPid
9985 + ", uid=" + callingUid
9986 + " that is not exported from uid " + r.appInfo.uid);
9987 return new ServiceLookupResult(null, "not exported from uid "
9988 + r.appInfo.uid);
9989 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009990 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009991 + " from pid=" + callingPid
9992 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009993 + " requires " + r.permission);
9994 return new ServiceLookupResult(null, r.permission);
9995 }
9996 return new ServiceLookupResult(r, null);
9997 }
9998 return null;
9999 }
10000
Dianne Hackborn287952c2010-09-22 22:34:31 -070010001 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10002 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10003 + why + " of " + r + " in app " + r.app);
10004 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10005 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010006 long now = SystemClock.uptimeMillis();
10007 if (r.executeNesting == 0 && r.app != null) {
10008 if (r.app.executingServices.size() == 0) {
10009 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10010 msg.obj = r.app;
10011 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10012 }
10013 r.app.executingServices.add(r);
10014 }
10015 r.executeNesting++;
10016 r.executingStart = now;
10017 }
10018
10019 private final void sendServiceArgsLocked(ServiceRecord r,
10020 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010021 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022 if (N == 0) {
10023 return;
10024 }
10025
Dianne Hackborn39792d22010-08-19 18:01:52 -070010026 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010027 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010028 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010029 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10030 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010031 if (si.intent == null && N > 1) {
10032 // If somehow we got a dummy null intent in the middle,
10033 // then skip it. DO NOT skip a null intent when it is
10034 // the only one in the list -- this is to support the
10035 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010036 continue;
10037 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010038 si.deliveredTime = SystemClock.uptimeMillis();
10039 r.deliveredStarts.add(si);
10040 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010041 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010042 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010043 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010044 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010045 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046 if (!oomAdjusted) {
10047 oomAdjusted = true;
10048 updateOomAdjLocked(r.app);
10049 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010050 int flags = 0;
10051 if (si.deliveryCount > 0) {
10052 flags |= Service.START_FLAG_RETRY;
10053 }
10054 if (si.doneExecutingCount > 0) {
10055 flags |= Service.START_FLAG_REDELIVERY;
10056 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010057 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010058 } catch (RemoteException e) {
10059 // Remote process gone... we'll let the normal cleanup take
10060 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010061 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010062 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010064 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 break;
10066 }
10067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010068 }
10069
10070 private final boolean requestServiceBindingLocked(ServiceRecord r,
10071 IntentBindRecord i, boolean rebind) {
10072 if (r.app == null || r.app.thread == null) {
10073 // If service is not currently running, can't yet bind.
10074 return false;
10075 }
10076 if ((!i.requested || rebind) && i.apps.size() > 0) {
10077 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010078 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10080 if (!rebind) {
10081 i.requested = true;
10082 }
10083 i.hasBound = true;
10084 i.doRebind = false;
10085 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010086 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010087 return false;
10088 }
10089 }
10090 return true;
10091 }
10092
10093 private final void requestServiceBindingsLocked(ServiceRecord r) {
10094 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10095 while (bindings.hasNext()) {
10096 IntentBindRecord i = bindings.next();
10097 if (!requestServiceBindingLocked(r, i, false)) {
10098 break;
10099 }
10100 }
10101 }
10102
10103 private final void realStartServiceLocked(ServiceRecord r,
10104 ProcessRecord app) throws RemoteException {
10105 if (app.thread == null) {
10106 throw new RemoteException();
10107 }
10108
10109 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010110 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010111
10112 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010113 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010114 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010115
10116 boolean created = false;
10117 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010118 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010119 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010120 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010122 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010123 synchronized (r.stats.getBatteryStats()) {
10124 r.stats.startLaunchedLocked();
10125 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010126 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010127 app.thread.scheduleCreateService(r, r.serviceInfo,
10128 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010129 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010130 created = true;
10131 } finally {
10132 if (!created) {
10133 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010134 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 }
10136 }
10137
10138 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010139
10140 // If the service is in the started state, and there are no
10141 // pending arguments, then fake up one so its onStartCommand() will
10142 // be called.
10143 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010144 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10145 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010146 }
10147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010148 sendServiceArgsLocked(r, true);
10149 }
10150
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010151 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10152 boolean allowCancel) {
10153 boolean canceled = false;
10154
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010155 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010156 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010157 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010158
Dianne Hackborn070783f2010-12-29 16:46:28 -080010159 if ((r.serviceInfo.applicationInfo.flags
10160 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10161 minDuration /= 4;
10162 }
10163
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010164 // Any delivered but not yet finished starts should be put back
10165 // on the pending list.
10166 final int N = r.deliveredStarts.size();
10167 if (N > 0) {
10168 for (int i=N-1; i>=0; i--) {
10169 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010170 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010171 if (si.intent == null) {
10172 // We'll generate this again if needed.
10173 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10174 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10175 r.pendingStarts.add(0, si);
10176 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10177 dur *= 2;
10178 if (minDuration < dur) minDuration = dur;
10179 if (resetTime < dur) resetTime = dur;
10180 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010181 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010182 + r.name);
10183 canceled = true;
10184 }
10185 }
10186 r.deliveredStarts.clear();
10187 }
10188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010189 r.totalRestartCount++;
10190 if (r.restartDelay == 0) {
10191 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010192 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193 } else {
10194 // If it has been a "reasonably long time" since the service
10195 // was started, then reset our restart duration back to
10196 // the beginning, so we don't infinitely increase the duration
10197 // on a service that just occasionally gets killed (which is
10198 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010199 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010200 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010201 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010203 if ((r.serviceInfo.applicationInfo.flags
10204 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10205 // Services in peristent processes will restart much more
10206 // quickly, since they are pretty important. (Think SystemUI).
10207 r.restartDelay += minDuration/2;
10208 } else {
10209 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10210 if (r.restartDelay < minDuration) {
10211 r.restartDelay = minDuration;
10212 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010214 }
10215 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010216
10217 r.nextRestartTime = now + r.restartDelay;
10218
10219 // Make sure that we don't end up restarting a bunch of services
10220 // all at the same time.
10221 boolean repeat;
10222 do {
10223 repeat = false;
10224 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10225 ServiceRecord r2 = mRestartingServices.get(i);
10226 if (r2 != r && r.nextRestartTime
10227 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10228 && r.nextRestartTime
10229 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10230 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10231 r.restartDelay = r.nextRestartTime - now;
10232 repeat = true;
10233 break;
10234 }
10235 }
10236 } while (repeat);
10237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010238 if (!mRestartingServices.contains(r)) {
10239 mRestartingServices.add(r);
10240 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010241
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010242 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010245 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010246 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010247 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010248 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010249 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010250 r.shortName, r.restartDelay);
10251
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010252 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 }
10254
10255 final void performServiceRestartLocked(ServiceRecord r) {
10256 if (!mRestartingServices.contains(r)) {
10257 return;
10258 }
10259 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10260 }
10261
10262 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10263 if (r.restartDelay == 0) {
10264 return false;
10265 }
10266 r.resetRestartCounter();
10267 mRestartingServices.remove(r);
10268 mHandler.removeCallbacks(r.restarter);
10269 return true;
10270 }
10271
10272 private final boolean bringUpServiceLocked(ServiceRecord r,
10273 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010274 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 //r.dump(" ");
10276
Dianne Hackborn36124872009-10-08 16:22:03 -070010277 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010278 sendServiceArgsLocked(r, false);
10279 return true;
10280 }
10281
10282 if (!whileRestarting && r.restartDelay > 0) {
10283 // If waiting for a restart, then do nothing.
10284 return true;
10285 }
10286
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010287 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010289 // We are now bringing the service up, so no longer in the
10290 // restarting state.
10291 mRestartingServices.remove(r);
10292
Dianne Hackborne7f97212011-02-24 14:40:20 -080010293 // Service is now being launched, its package can't be stopped.
10294 try {
10295 AppGlobals.getPackageManager().setPackageStoppedState(
10296 r.packageName, false);
10297 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010298 } catch (IllegalArgumentException e) {
10299 Slog.w(TAG, "Failed trying to unstop package "
10300 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010301 }
10302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010303 final String appName = r.processName;
10304 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10305 if (app != null && app.thread != null) {
10306 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010307 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010308 realStartServiceLocked(r, app);
10309 return true;
10310 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010311 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 }
10313
10314 // If a dead object exception was thrown -- fall through to
10315 // restart the application.
10316 }
10317
Dianne Hackborn36124872009-10-08 16:22:03 -070010318 // Not running -- get it started, and enqueue this service record
10319 // to be executed when the app comes up.
10320 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10321 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010322 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010323 + r.appInfo.packageName + "/"
10324 + r.appInfo.uid + " for service "
10325 + r.intent.getIntent() + ": process is bad");
10326 bringDownServiceLocked(r, true);
10327 return false;
10328 }
10329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010331 mPendingServices.add(r);
10332 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 return true;
10335 }
10336
10337 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010338 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010339 //r.dump(" ");
10340
10341 // Does it still need to run?
10342 if (!force && r.startRequested) {
10343 return;
10344 }
10345 if (r.connections.size() > 0) {
10346 if (!force) {
10347 // XXX should probably keep a count of the number of auto-create
10348 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010349 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010350 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010351 ArrayList<ConnectionRecord> cr = it.next();
10352 for (int i=0; i<cr.size(); i++) {
10353 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10354 return;
10355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010356 }
10357 }
10358 }
10359
10360 // Report to all of the connections that the service is no longer
10361 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010362 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010363 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010364 ArrayList<ConnectionRecord> c = it.next();
10365 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010366 ConnectionRecord cr = c.get(i);
10367 // There is still a connection to the service that is
10368 // being brought down. Mark it as dead.
10369 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010370 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010371 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010372 } catch (Exception e) {
10373 Slog.w(TAG, "Failure disconnecting service " + r.name +
10374 " to connection " + c.get(i).conn.asBinder() +
10375 " (in " + c.get(i).binding.client.processName + ")", e);
10376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010377 }
10378 }
10379 }
10380
10381 // Tell the service that it has been unbound.
10382 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10383 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10384 while (it.hasNext()) {
10385 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010386 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010387 + ": hasBound=" + ibr.hasBound);
10388 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10389 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010390 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010391 updateOomAdjLocked(r.app);
10392 ibr.hasBound = false;
10393 r.app.thread.scheduleUnbindService(r,
10394 ibr.intent.getIntent());
10395 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010396 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 + r.shortName, e);
10398 serviceDoneExecutingLocked(r, true);
10399 }
10400 }
10401 }
10402 }
10403
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010404 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010405 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 System.identityHashCode(r), r.shortName,
10407 (r.app != null) ? r.app.pid : -1);
10408
10409 mServices.remove(r.name);
10410 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 r.totalRestartCount = 0;
10412 unscheduleServiceRestartLocked(r);
10413
10414 // Also make sure it is not on the pending list.
10415 int N = mPendingServices.size();
10416 for (int i=0; i<N; i++) {
10417 if (mPendingServices.get(i) == r) {
10418 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010419 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 i--;
10421 N--;
10422 }
10423 }
10424
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010425 r.cancelNotification();
10426 r.isForeground = false;
10427 r.foregroundId = 0;
10428 r.foregroundNoti = null;
10429
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010430 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010431 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010432 r.pendingStarts.clear();
10433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010434 if (r.app != null) {
10435 synchronized (r.stats.getBatteryStats()) {
10436 r.stats.stopLaunchedLocked();
10437 }
10438 r.app.services.remove(r);
10439 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010440 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010441 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010442 mStoppingServices.add(r);
10443 updateOomAdjLocked(r.app);
10444 r.app.thread.scheduleStopService(r);
10445 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010446 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010447 + r.shortName, e);
10448 serviceDoneExecutingLocked(r, true);
10449 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010450 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010452 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010453 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010454 }
10455 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010456 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010457 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010459
10460 if (r.bindings.size() > 0) {
10461 r.bindings.clear();
10462 }
10463
10464 if (r.restarter instanceof ServiceRestarter) {
10465 ((ServiceRestarter)r.restarter).setService(null);
10466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010467 }
10468
10469 ComponentName startServiceLocked(IApplicationThread caller,
10470 Intent service, String resolvedType,
10471 int callingPid, int callingUid) {
10472 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010473 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010474 + " type=" + resolvedType + " args=" + service.getExtras());
10475
10476 if (caller != null) {
10477 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10478 if (callerApp == null) {
10479 throw new SecurityException(
10480 "Unable to find app for caller " + caller
10481 + " (pid=" + Binder.getCallingPid()
10482 + ") when starting service " + service);
10483 }
10484 }
10485
10486 ServiceLookupResult res =
10487 retrieveServiceLocked(service, resolvedType,
10488 callingPid, callingUid);
10489 if (res == null) {
10490 return null;
10491 }
10492 if (res.record == null) {
10493 return new ComponentName("!", res.permission != null
10494 ? res.permission : "private to package");
10495 }
10496 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010497 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10498 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010499 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010500 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010501 }
10502 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010503 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010504 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010505 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010506 r.lastActivity = SystemClock.uptimeMillis();
10507 synchronized (r.stats.getBatteryStats()) {
10508 r.stats.startRunningLocked();
10509 }
10510 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10511 return new ComponentName("!", "Service process is bad");
10512 }
10513 return r.name;
10514 }
10515 }
10516
10517 public ComponentName startService(IApplicationThread caller, Intent service,
10518 String resolvedType) {
10519 // Refuse possible leaked file descriptors
10520 if (service != null && service.hasFileDescriptors() == true) {
10521 throw new IllegalArgumentException("File descriptors passed in Intent");
10522 }
10523
10524 synchronized(this) {
10525 final int callingPid = Binder.getCallingPid();
10526 final int callingUid = Binder.getCallingUid();
10527 final long origId = Binder.clearCallingIdentity();
10528 ComponentName res = startServiceLocked(caller, service,
10529 resolvedType, callingPid, callingUid);
10530 Binder.restoreCallingIdentity(origId);
10531 return res;
10532 }
10533 }
10534
10535 ComponentName startServiceInPackage(int uid,
10536 Intent service, String resolvedType) {
10537 synchronized(this) {
10538 final long origId = Binder.clearCallingIdentity();
10539 ComponentName res = startServiceLocked(null, service,
10540 resolvedType, -1, uid);
10541 Binder.restoreCallingIdentity(origId);
10542 return res;
10543 }
10544 }
10545
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010546 private void stopServiceLocked(ServiceRecord service) {
10547 synchronized (service.stats.getBatteryStats()) {
10548 service.stats.stopRunningLocked();
10549 }
10550 service.startRequested = false;
10551 service.callStart = false;
10552 bringDownServiceLocked(service, false);
10553 }
10554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 public int stopService(IApplicationThread caller, Intent service,
10556 String resolvedType) {
10557 // Refuse possible leaked file descriptors
10558 if (service != null && service.hasFileDescriptors() == true) {
10559 throw new IllegalArgumentException("File descriptors passed in Intent");
10560 }
10561
10562 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010563 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010564 + " type=" + resolvedType);
10565
10566 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10567 if (caller != null && callerApp == null) {
10568 throw new SecurityException(
10569 "Unable to find app for caller " + caller
10570 + " (pid=" + Binder.getCallingPid()
10571 + ") when stopping service " + service);
10572 }
10573
10574 // If this service is active, make sure it is stopped.
10575 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10576 if (r != null) {
10577 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010578 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010579 try {
10580 stopServiceLocked(r.record);
10581 } finally {
10582 Binder.restoreCallingIdentity(origId);
10583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010584 return 1;
10585 }
10586 return -1;
10587 }
10588 }
10589
10590 return 0;
10591 }
10592
10593 public IBinder peekService(Intent service, String resolvedType) {
10594 // Refuse possible leaked file descriptors
10595 if (service != null && service.hasFileDescriptors() == true) {
10596 throw new IllegalArgumentException("File descriptors passed in Intent");
10597 }
10598
10599 IBinder ret = null;
10600
10601 synchronized(this) {
10602 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10603
10604 if (r != null) {
10605 // r.record is null if findServiceLocked() failed the caller permission check
10606 if (r.record == null) {
10607 throw new SecurityException(
10608 "Permission Denial: Accessing service " + r.record.name
10609 + " from pid=" + Binder.getCallingPid()
10610 + ", uid=" + Binder.getCallingUid()
10611 + " requires " + r.permission);
10612 }
10613 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10614 if (ib != null) {
10615 ret = ib.binder;
10616 }
10617 }
10618 }
10619
10620 return ret;
10621 }
10622
10623 public boolean stopServiceToken(ComponentName className, IBinder token,
10624 int startId) {
10625 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010626 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010627 + " " + token + " startId=" + startId);
10628 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010629 if (r != null) {
10630 if (startId >= 0) {
10631 // Asked to only stop if done with all work. Note that
10632 // to avoid leaks, we will take this as dropping all
10633 // start items up to and including this one.
10634 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10635 if (si != null) {
10636 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010637 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10638 cur.removeUriPermissionsLocked();
10639 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010640 break;
10641 }
10642 }
10643 }
10644
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010645 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010646 return false;
10647 }
10648
10649 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010650 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010651 + " is last, but have " + r.deliveredStarts.size()
10652 + " remaining args");
10653 }
10654 }
10655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 synchronized (r.stats.getBatteryStats()) {
10657 r.stats.stopRunningLocked();
10658 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010659 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010660 }
10661 final long origId = Binder.clearCallingIdentity();
10662 bringDownServiceLocked(r, false);
10663 Binder.restoreCallingIdentity(origId);
10664 return true;
10665 }
10666 }
10667 return false;
10668 }
10669
10670 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010671 int id, Notification notification, boolean removeNotification) {
10672 final long origId = Binder.clearCallingIdentity();
10673 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010674 synchronized(this) {
10675 ServiceRecord r = findServiceLocked(className, token);
10676 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010677 if (id != 0) {
10678 if (notification == null) {
10679 throw new IllegalArgumentException("null notification");
10680 }
10681 if (r.foregroundId != id) {
10682 r.cancelNotification();
10683 r.foregroundId = id;
10684 }
10685 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10686 r.foregroundNoti = notification;
10687 r.isForeground = true;
10688 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 if (r.app != null) {
10690 updateServiceForegroundLocked(r.app, true);
10691 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010692 } else {
10693 if (r.isForeground) {
10694 r.isForeground = false;
10695 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010696 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010697 updateServiceForegroundLocked(r.app, true);
10698 }
10699 }
10700 if (removeNotification) {
10701 r.cancelNotification();
10702 r.foregroundId = 0;
10703 r.foregroundNoti = null;
10704 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010705 }
10706 }
10707 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010708 } finally {
10709 Binder.restoreCallingIdentity(origId);
10710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010711 }
10712
10713 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10714 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010715 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010716 if (sr.isForeground) {
10717 anyForeground = true;
10718 break;
10719 }
10720 }
10721 if (anyForeground != proc.foregroundServices) {
10722 proc.foregroundServices = anyForeground;
10723 if (oomAdj) {
10724 updateOomAdjLocked();
10725 }
10726 }
10727 }
10728
10729 public int bindService(IApplicationThread caller, IBinder token,
10730 Intent service, String resolvedType,
10731 IServiceConnection connection, int flags) {
10732 // Refuse possible leaked file descriptors
10733 if (service != null && service.hasFileDescriptors() == true) {
10734 throw new IllegalArgumentException("File descriptors passed in Intent");
10735 }
10736
10737 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010738 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 + " type=" + resolvedType + " conn=" + connection.asBinder()
10740 + " flags=0x" + Integer.toHexString(flags));
10741 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10742 if (callerApp == null) {
10743 throw new SecurityException(
10744 "Unable to find app for caller " + caller
10745 + " (pid=" + Binder.getCallingPid()
10746 + ") when binding service " + service);
10747 }
10748
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010749 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010750 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010751 activity = mMainStack.isInStackLocked(token);
10752 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010753 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010754 return 0;
10755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010756 }
10757
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010758 int clientLabel = 0;
10759 PendingIntent clientIntent = null;
10760
10761 if (callerApp.info.uid == Process.SYSTEM_UID) {
10762 // Hacky kind of thing -- allow system stuff to tell us
10763 // what they are, so we can report this elsewhere for
10764 // others to know why certain services are running.
10765 try {
10766 clientIntent = (PendingIntent)service.getParcelableExtra(
10767 Intent.EXTRA_CLIENT_INTENT);
10768 } catch (RuntimeException e) {
10769 }
10770 if (clientIntent != null) {
10771 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10772 if (clientLabel != 0) {
10773 // There are no useful extras in the intent, trash them.
10774 // System code calling with this stuff just needs to know
10775 // this will happen.
10776 service = service.cloneFilter();
10777 }
10778 }
10779 }
10780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 ServiceLookupResult res =
10782 retrieveServiceLocked(service, resolvedType,
10783 Binder.getCallingPid(), Binder.getCallingUid());
10784 if (res == null) {
10785 return 0;
10786 }
10787 if (res.record == null) {
10788 return -1;
10789 }
10790 ServiceRecord s = res.record;
10791
10792 final long origId = Binder.clearCallingIdentity();
10793
10794 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010795 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010796 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010797 }
10798
10799 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10800 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010801 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010802
10803 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010804 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10805 if (clist == null) {
10806 clist = new ArrayList<ConnectionRecord>();
10807 s.connections.put(binder, clist);
10808 }
10809 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010810 b.connections.add(c);
10811 if (activity != null) {
10812 if (activity.connections == null) {
10813 activity.connections = new HashSet<ConnectionRecord>();
10814 }
10815 activity.connections.add(c);
10816 }
10817 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010818 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10819 b.client.hasAboveClient = true;
10820 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010821 clist = mServiceConnections.get(binder);
10822 if (clist == null) {
10823 clist = new ArrayList<ConnectionRecord>();
10824 mServiceConnections.put(binder, clist);
10825 }
10826 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010827
10828 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10829 s.lastActivity = SystemClock.uptimeMillis();
10830 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10831 return 0;
10832 }
10833 }
10834
10835 if (s.app != null) {
10836 // This could have made the service more important.
10837 updateOomAdjLocked(s.app);
10838 }
10839
Joe Onorato8a9b2202010-02-26 18:56:32 -080010840 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010841 + ": received=" + b.intent.received
10842 + " apps=" + b.intent.apps.size()
10843 + " doRebind=" + b.intent.doRebind);
10844
10845 if (s.app != null && b.intent.received) {
10846 // Service is already running, so we can immediately
10847 // publish the connection.
10848 try {
10849 c.conn.connected(s.name, b.intent.binder);
10850 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010851 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010852 + " to connection " + c.conn.asBinder()
10853 + " (in " + c.binding.client.processName + ")", e);
10854 }
10855
10856 // If this is the first app connected back to this binding,
10857 // and the service had previously asked to be told when
10858 // rebound, then do so.
10859 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10860 requestServiceBindingLocked(s, b.intent, true);
10861 }
10862 } else if (!b.intent.requested) {
10863 requestServiceBindingLocked(s, b.intent, false);
10864 }
10865
10866 Binder.restoreCallingIdentity(origId);
10867 }
10868
10869 return 1;
10870 }
10871
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010872 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010873 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010874 IBinder binder = c.conn.asBinder();
10875 AppBindRecord b = c.binding;
10876 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010877 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10878 if (clist != null) {
10879 clist.remove(c);
10880 if (clist.size() == 0) {
10881 s.connections.remove(binder);
10882 }
10883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010884 b.connections.remove(c);
10885 if (c.activity != null && c.activity != skipAct) {
10886 if (c.activity.connections != null) {
10887 c.activity.connections.remove(c);
10888 }
10889 }
10890 if (b.client != skipApp) {
10891 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010892 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10893 b.client.updateHasAboveClientLocked();
10894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010895 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010896 clist = mServiceConnections.get(binder);
10897 if (clist != null) {
10898 clist.remove(c);
10899 if (clist.size() == 0) {
10900 mServiceConnections.remove(binder);
10901 }
10902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010903
10904 if (b.connections.size() == 0) {
10905 b.intent.apps.remove(b.client);
10906 }
10907
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010908 if (!c.serviceDead) {
10909 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10910 + ": shouldUnbind=" + b.intent.hasBound);
10911 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10912 && b.intent.hasBound) {
10913 try {
10914 bumpServiceExecutingLocked(s, "unbind");
10915 updateOomAdjLocked(s.app);
10916 b.intent.hasBound = false;
10917 // Assume the client doesn't want to know about a rebind;
10918 // we will deal with that later if it asks for one.
10919 b.intent.doRebind = false;
10920 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10921 } catch (Exception e) {
10922 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10923 serviceDoneExecutingLocked(s, true);
10924 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010926
10927 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10928 bringDownServiceLocked(s, false);
10929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010930 }
10931 }
10932
10933 public boolean unbindService(IServiceConnection connection) {
10934 synchronized (this) {
10935 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010936 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010937 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10938 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010939 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010940 + connection.asBinder());
10941 return false;
10942 }
10943
10944 final long origId = Binder.clearCallingIdentity();
10945
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010946 while (clist.size() > 0) {
10947 ConnectionRecord r = clist.get(0);
10948 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010950 if (r.binding.service.app != null) {
10951 // This could have made the service less important.
10952 updateOomAdjLocked(r.binding.service.app);
10953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010954 }
10955
10956 Binder.restoreCallingIdentity(origId);
10957 }
10958
10959 return true;
10960 }
10961
10962 public void publishService(IBinder token, Intent intent, IBinder service) {
10963 // Refuse possible leaked file descriptors
10964 if (intent != null && intent.hasFileDescriptors() == true) {
10965 throw new IllegalArgumentException("File descriptors passed in Intent");
10966 }
10967
10968 synchronized(this) {
10969 if (!(token instanceof ServiceRecord)) {
10970 throw new IllegalArgumentException("Invalid service token");
10971 }
10972 ServiceRecord r = (ServiceRecord)token;
10973
10974 final long origId = Binder.clearCallingIdentity();
10975
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010976 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010977 + " " + intent + ": " + service);
10978 if (r != null) {
10979 Intent.FilterComparison filter
10980 = new Intent.FilterComparison(intent);
10981 IntentBindRecord b = r.bindings.get(filter);
10982 if (b != null && !b.received) {
10983 b.binder = service;
10984 b.requested = true;
10985 b.received = true;
10986 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010987 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010988 = r.connections.values().iterator();
10989 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010990 ArrayList<ConnectionRecord> clist = it.next();
10991 for (int i=0; i<clist.size(); i++) {
10992 ConnectionRecord c = clist.get(i);
10993 if (!filter.equals(c.binding.intent.intent)) {
10994 if (DEBUG_SERVICE) Slog.v(
10995 TAG, "Not publishing to: " + c);
10996 if (DEBUG_SERVICE) Slog.v(
10997 TAG, "Bound intent: " + c.binding.intent.intent);
10998 if (DEBUG_SERVICE) Slog.v(
10999 TAG, "Published intent: " + intent);
11000 continue;
11001 }
11002 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11003 try {
11004 c.conn.connected(r.name, service);
11005 } catch (Exception e) {
11006 Slog.w(TAG, "Failure sending service " + r.name +
11007 " to connection " + c.conn.asBinder() +
11008 " (in " + c.binding.client.processName + ")", e);
11009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011010 }
11011 }
11012 }
11013 }
11014
11015 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11016
11017 Binder.restoreCallingIdentity(origId);
11018 }
11019 }
11020 }
11021
11022 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11023 // Refuse possible leaked file descriptors
11024 if (intent != null && intent.hasFileDescriptors() == true) {
11025 throw new IllegalArgumentException("File descriptors passed in Intent");
11026 }
11027
11028 synchronized(this) {
11029 if (!(token instanceof ServiceRecord)) {
11030 throw new IllegalArgumentException("Invalid service token");
11031 }
11032 ServiceRecord r = (ServiceRecord)token;
11033
11034 final long origId = Binder.clearCallingIdentity();
11035
11036 if (r != null) {
11037 Intent.FilterComparison filter
11038 = new Intent.FilterComparison(intent);
11039 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011040 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011041 + " at " + b + ": apps="
11042 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011043
11044 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011045 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011046 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011047 // Applications have already bound since the last
11048 // unbind, so just rebind right here.
11049 requestServiceBindingLocked(r, b, true);
11050 } else {
11051 // Note to tell the service the next time there is
11052 // a new client.
11053 b.doRebind = true;
11054 }
11055 }
11056
Per Edelberg78f9fff2010-08-30 20:01:35 +020011057 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011058
11059 Binder.restoreCallingIdentity(origId);
11060 }
11061 }
11062 }
11063
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011064 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 synchronized(this) {
11066 if (!(token instanceof ServiceRecord)) {
11067 throw new IllegalArgumentException("Invalid service token");
11068 }
11069 ServiceRecord r = (ServiceRecord)token;
11070 boolean inStopping = mStoppingServices.contains(token);
11071 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011072 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011073 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011074 + " with incorrect token: given " + token
11075 + ", expected " + r);
11076 return;
11077 }
11078
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011079 if (type == 1) {
11080 // This is a call from a service start... take care of
11081 // book-keeping.
11082 r.callStart = true;
11083 switch (res) {
11084 case Service.START_STICKY_COMPATIBILITY:
11085 case Service.START_STICKY: {
11086 // We are done with the associated start arguments.
11087 r.findDeliveredStart(startId, true);
11088 // Don't stop if killed.
11089 r.stopIfKilled = false;
11090 break;
11091 }
11092 case Service.START_NOT_STICKY: {
11093 // We are done with the associated start arguments.
11094 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011095 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011096 // There is no more work, and this service
11097 // doesn't want to hang around if killed.
11098 r.stopIfKilled = true;
11099 }
11100 break;
11101 }
11102 case Service.START_REDELIVER_INTENT: {
11103 // We'll keep this item until they explicitly
11104 // call stop for it, but keep track of the fact
11105 // that it was delivered.
11106 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11107 if (si != null) {
11108 si.deliveryCount = 0;
11109 si.doneExecutingCount++;
11110 // Don't stop if killed.
11111 r.stopIfKilled = true;
11112 }
11113 break;
11114 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011115 case Service.START_TASK_REMOVED_COMPLETE: {
11116 // Special processing for onTaskRemoved(). Don't
11117 // impact normal onStartCommand() processing.
11118 r.findDeliveredStart(startId, true);
11119 break;
11120 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011121 default:
11122 throw new IllegalArgumentException(
11123 "Unknown service start result: " + res);
11124 }
11125 if (res == Service.START_STICKY_COMPATIBILITY) {
11126 r.callStart = false;
11127 }
11128 }
11129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011130 final long origId = Binder.clearCallingIdentity();
11131 serviceDoneExecutingLocked(r, inStopping);
11132 Binder.restoreCallingIdentity(origId);
11133 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011134 Slog.w(TAG, "Done executing unknown service from pid "
11135 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 }
11137 }
11138 }
11139
11140 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011141 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11142 + ": nesting=" + r.executeNesting
11143 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011144 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 r.executeNesting--;
11146 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011147 if (DEBUG_SERVICE) Slog.v(TAG,
11148 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 r.app.executingServices.remove(r);
11150 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011151 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11152 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011153 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11154 }
11155 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011156 if (DEBUG_SERVICE) Slog.v(TAG,
11157 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011158 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011159 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011160 }
11161 updateOomAdjLocked(r.app);
11162 }
11163 }
11164
11165 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011166 String anrMessage = null;
11167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 synchronized(this) {
11169 if (proc.executingServices.size() == 0 || proc.thread == null) {
11170 return;
11171 }
11172 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11173 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11174 ServiceRecord timeout = null;
11175 long nextTime = 0;
11176 while (it.hasNext()) {
11177 ServiceRecord sr = it.next();
11178 if (sr.executingStart < maxTime) {
11179 timeout = sr;
11180 break;
11181 }
11182 if (sr.executingStart > nextTime) {
11183 nextTime = sr.executingStart;
11184 }
11185 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011186 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011187 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011188 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011189 } else {
11190 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11191 msg.obj = proc;
11192 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11193 }
11194 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011195
11196 if (anrMessage != null) {
11197 appNotResponding(proc, null, null, anrMessage);
11198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011199 }
11200
11201 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011202 // BACKUP AND RESTORE
11203 // =========================================================
11204
11205 // Cause the target app to be launched if necessary and its backup agent
11206 // instantiated. The backup agent will invoke backupAgentCreated() on the
11207 // activity manager to announce its creation.
11208 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011209 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011210 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11211
11212 synchronized(this) {
11213 // !!! TODO: currently no check here that we're already bound
11214 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11215 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11216 synchronized (stats) {
11217 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11218 }
11219
Dianne Hackborne7f97212011-02-24 14:40:20 -080011220 // Backup agent is now in use, its package can't be stopped.
11221 try {
11222 AppGlobals.getPackageManager().setPackageStoppedState(
11223 app.packageName, false);
11224 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011225 } catch (IllegalArgumentException e) {
11226 Slog.w(TAG, "Failed trying to unstop package "
11227 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011228 }
11229
Christopher Tate181fafa2009-05-14 11:12:14 -070011230 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011231 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11232 ? new ComponentName(app.packageName, app.backupAgentName)
11233 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011234 // startProcessLocked() returns existing proc's record if it's already running
11235 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011236 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011237 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011238 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011239 return false;
11240 }
11241
11242 r.app = proc;
11243 mBackupTarget = r;
11244 mBackupAppName = app.packageName;
11245
Christopher Tate6fa95972009-06-05 18:43:55 -070011246 // Try not to kill the process during backup
11247 updateOomAdjLocked(proc);
11248
Christopher Tate181fafa2009-05-14 11:12:14 -070011249 // If the process is already attached, schedule the creation of the backup agent now.
11250 // If it is not yet live, this will be done when it attaches to the framework.
11251 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011252 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011253 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011254 proc.thread.scheduleCreateBackupAgent(app,
11255 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011256 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011257 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011258 }
11259 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011260 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011261 }
11262 // Invariants: at this point, the target app process exists and the application
11263 // is either already running or in the process of coming up. mBackupTarget and
11264 // mBackupAppName describe the app, so that when it binds back to the AM we
11265 // know that it's scheduled for a backup-agent operation.
11266 }
11267
11268 return true;
11269 }
11270
11271 // A backup agent has just come up
11272 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011273 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011274 + " = " + agent);
11275
11276 synchronized(this) {
11277 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011278 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011279 return;
11280 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011281 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011282
Dianne Hackborn06740692010-09-22 22:46:21 -070011283 long oldIdent = Binder.clearCallingIdentity();
11284 try {
11285 IBackupManager bm = IBackupManager.Stub.asInterface(
11286 ServiceManager.getService(Context.BACKUP_SERVICE));
11287 bm.agentConnected(agentPackageName, agent);
11288 } catch (RemoteException e) {
11289 // can't happen; the backup manager service is local
11290 } catch (Exception e) {
11291 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11292 e.printStackTrace();
11293 } finally {
11294 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011295 }
11296 }
11297
11298 // done with this agent
11299 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011300 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011301 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011302 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011303 return;
11304 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011305
11306 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011307 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011308 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011309 return;
11310 }
11311
Christopher Tate181fafa2009-05-14 11:12:14 -070011312 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011313 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011314 return;
11315 }
11316
Christopher Tate6fa95972009-06-05 18:43:55 -070011317 ProcessRecord proc = mBackupTarget.app;
11318 mBackupTarget = null;
11319 mBackupAppName = null;
11320
11321 // Not backing this app up any more; reset its OOM adjustment
11322 updateOomAdjLocked(proc);
11323
Christopher Tatec7b31e32009-06-10 15:49:30 -070011324 // If the app crashed during backup, 'thread' will be null here
11325 if (proc.thread != null) {
11326 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011327 proc.thread.scheduleDestroyBackupAgent(appInfo,
11328 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011329 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011330 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011331 e.printStackTrace();
11332 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011333 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011334 }
11335 }
11336 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011337 // BROADCASTS
11338 // =========================================================
11339
Josh Bartel7f208742010-02-25 11:01:44 -060011340 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011341 List cur) {
11342 final ContentResolver resolver = mContext.getContentResolver();
11343 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11344 if (list == null) {
11345 return cur;
11346 }
11347 int N = list.size();
11348 for (int i=0; i<N; i++) {
11349 Intent intent = list.get(i);
11350 if (filter.match(resolver, intent, true, TAG) >= 0) {
11351 if (cur == null) {
11352 cur = new ArrayList<Intent>();
11353 }
11354 cur.add(intent);
11355 }
11356 }
11357 return cur;
11358 }
11359
11360 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011361 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011362 + mBroadcastsScheduled);
11363
11364 if (mBroadcastsScheduled) {
11365 return;
11366 }
11367 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11368 mBroadcastsScheduled = true;
11369 }
11370
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011371 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 IIntentReceiver receiver, IntentFilter filter, String permission) {
11373 synchronized(this) {
11374 ProcessRecord callerApp = null;
11375 if (caller != null) {
11376 callerApp = getRecordForAppLocked(caller);
11377 if (callerApp == null) {
11378 throw new SecurityException(
11379 "Unable to find app for caller " + caller
11380 + " (pid=" + Binder.getCallingPid()
11381 + ") when registering receiver " + receiver);
11382 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011383 if (callerApp.info.uid != Process.SYSTEM_UID &&
11384 !callerApp.pkgList.contains(callerPackage)) {
11385 throw new SecurityException("Given caller package " + callerPackage
11386 + " is not running in process " + callerApp);
11387 }
11388 } else {
11389 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011390 }
11391
11392 List allSticky = null;
11393
11394 // Look for any matching sticky broadcasts...
11395 Iterator actions = filter.actionsIterator();
11396 if (actions != null) {
11397 while (actions.hasNext()) {
11398 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011399 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011400 }
11401 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011402 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011403 }
11404
11405 // The first sticky in the list is returned directly back to
11406 // the client.
11407 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11408
Joe Onorato8a9b2202010-02-26 18:56:32 -080011409 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011410 + ": " + sticky);
11411
11412 if (receiver == null) {
11413 return sticky;
11414 }
11415
11416 ReceiverList rl
11417 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11418 if (rl == null) {
11419 rl = new ReceiverList(this, callerApp,
11420 Binder.getCallingPid(),
11421 Binder.getCallingUid(), receiver);
11422 if (rl.app != null) {
11423 rl.app.receivers.add(rl);
11424 } else {
11425 try {
11426 receiver.asBinder().linkToDeath(rl, 0);
11427 } catch (RemoteException e) {
11428 return sticky;
11429 }
11430 rl.linkedToDeath = true;
11431 }
11432 mRegisteredReceivers.put(receiver.asBinder(), rl);
11433 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011434 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011435 rl.add(bf);
11436 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011437 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011438 }
11439 mReceiverResolver.addFilter(bf);
11440
11441 // Enqueue broadcasts for all existing stickies that match
11442 // this filter.
11443 if (allSticky != null) {
11444 ArrayList receivers = new ArrayList();
11445 receivers.add(bf);
11446
11447 int N = allSticky.size();
11448 for (int i=0; i<N; i++) {
11449 Intent intent = (Intent)allSticky.get(i);
11450 BroadcastRecord r = new BroadcastRecord(intent, null,
11451 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011452 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 if (mParallelBroadcasts.size() == 0) {
11454 scheduleBroadcastsLocked();
11455 }
11456 mParallelBroadcasts.add(r);
11457 }
11458 }
11459
11460 return sticky;
11461 }
11462 }
11463
11464 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011465 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011466
11467 boolean doNext = false;
11468
11469 synchronized(this) {
11470 ReceiverList rl
11471 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11472 if (rl != null) {
11473 if (rl.curBroadcast != null) {
11474 BroadcastRecord r = rl.curBroadcast;
11475 doNext = finishReceiverLocked(
11476 receiver.asBinder(), r.resultCode, r.resultData,
11477 r.resultExtras, r.resultAbort, true);
11478 }
11479
11480 if (rl.app != null) {
11481 rl.app.receivers.remove(rl);
11482 }
11483 removeReceiverLocked(rl);
11484 if (rl.linkedToDeath) {
11485 rl.linkedToDeath = false;
11486 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11487 }
11488 }
11489 }
11490
11491 if (!doNext) {
11492 return;
11493 }
11494
11495 final long origId = Binder.clearCallingIdentity();
11496 processNextBroadcast(false);
11497 trimApplications();
11498 Binder.restoreCallingIdentity(origId);
11499 }
11500
11501 void removeReceiverLocked(ReceiverList rl) {
11502 mRegisteredReceivers.remove(rl.receiver.asBinder());
11503 int N = rl.size();
11504 for (int i=0; i<N; i++) {
11505 mReceiverResolver.removeFilter(rl.get(i));
11506 }
11507 }
11508
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011509 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11510 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11511 ProcessRecord r = mLruProcesses.get(i);
11512 if (r.thread != null) {
11513 try {
11514 r.thread.dispatchPackageBroadcast(cmd, packages);
11515 } catch (RemoteException ex) {
11516 }
11517 }
11518 }
11519 }
11520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011521 private final int broadcastIntentLocked(ProcessRecord callerApp,
11522 String callerPackage, Intent intent, String resolvedType,
11523 IIntentReceiver resultTo, int resultCode, String resultData,
11524 Bundle map, String requiredPermission,
11525 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11526 intent = new Intent(intent);
11527
Dianne Hackborne7f97212011-02-24 14:40:20 -080011528 // By default broadcasts do not go to stopped apps.
11529 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11530
Joe Onorato8a9b2202010-02-26 18:56:32 -080011531 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011532 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11533 + " ordered=" + ordered);
11534 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011535 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011536 }
11537
11538 // Handle special intents: if this broadcast is from the package
11539 // manager about a package being removed, we need to remove all of
11540 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011541 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011543 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11544 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011545 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011546 || uidRemoved) {
11547 if (checkComponentPermission(
11548 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011549 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 == PackageManager.PERMISSION_GRANTED) {
11551 if (uidRemoved) {
11552 final Bundle intentExtras = intent.getExtras();
11553 final int uid = intentExtras != null
11554 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11555 if (uid >= 0) {
11556 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11557 synchronized (bs) {
11558 bs.removeUidStatsLocked(uid);
11559 }
11560 }
11561 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011562 // If resources are unvailble just force stop all
11563 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011564 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011565 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11566 if (list != null && (list.length > 0)) {
11567 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011568 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011569 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011570 sendPackageBroadcastLocked(
11571 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011572 }
11573 } else {
11574 Uri data = intent.getData();
11575 String ssp;
11576 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11577 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11578 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011579 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011580 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011581 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011582 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11583 new String[] {ssp});
11584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 }
11586 }
11587 }
11588 } else {
11589 String msg = "Permission Denial: " + intent.getAction()
11590 + " broadcast from " + callerPackage + " (pid=" + callingPid
11591 + ", uid=" + callingUid + ")"
11592 + " requires "
11593 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011594 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011595 throw new SecurityException(msg);
11596 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011597
11598 // Special case for adding a package: by default turn on compatibility
11599 // mode.
11600 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011601 Uri data = intent.getData();
11602 String ssp;
11603 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11604 mCompatModePackages.handlePackageAddedLocked(ssp,
11605 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011607 }
11608
11609 /*
11610 * If this is the time zone changed action, queue up a message that will reset the timezone
11611 * of all currently running processes. This message will get queued up before the broadcast
11612 * happens.
11613 */
11614 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11615 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11616 }
11617
Robert Greenwalt03595d02010-11-02 14:08:23 -070011618 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11619 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11620 }
11621
Robert Greenwalt434203a2010-10-11 16:00:27 -070011622 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11623 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11624 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11625 }
11626
Dianne Hackborn854060af2009-07-09 18:14:31 -070011627 /*
11628 * Prevent non-system code (defined here to be non-persistent
11629 * processes) from sending protected broadcasts.
11630 */
11631 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11632 || callingUid == Process.SHELL_UID || callingUid == 0) {
11633 // Always okay.
11634 } else if (callerApp == null || !callerApp.persistent) {
11635 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011636 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011637 intent.getAction())) {
11638 String msg = "Permission Denial: not allowed to send broadcast "
11639 + intent.getAction() + " from pid="
11640 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011641 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011642 throw new SecurityException(msg);
11643 }
11644 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011645 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011646 return BROADCAST_SUCCESS;
11647 }
11648 }
11649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011650 // Add to the sticky list if requested.
11651 if (sticky) {
11652 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11653 callingPid, callingUid)
11654 != PackageManager.PERMISSION_GRANTED) {
11655 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11656 + callingPid + ", uid=" + callingUid
11657 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011658 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011659 throw new SecurityException(msg);
11660 }
11661 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011662 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011663 + " and enforce permission " + requiredPermission);
11664 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11665 }
11666 if (intent.getComponent() != null) {
11667 throw new SecurityException(
11668 "Sticky broadcasts can't target a specific component");
11669 }
11670 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11671 if (list == null) {
11672 list = new ArrayList<Intent>();
11673 mStickyBroadcasts.put(intent.getAction(), list);
11674 }
11675 int N = list.size();
11676 int i;
11677 for (i=0; i<N; i++) {
11678 if (intent.filterEquals(list.get(i))) {
11679 // This sticky already exists, replace it.
11680 list.set(i, new Intent(intent));
11681 break;
11682 }
11683 }
11684 if (i >= N) {
11685 list.add(new Intent(intent));
11686 }
11687 }
11688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011689 // Figure out who all will receive this broadcast.
11690 List receivers = null;
11691 List<BroadcastFilter> registeredReceivers = null;
11692 try {
11693 if (intent.getComponent() != null) {
11694 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011695 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011696 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011697 if (ai != null) {
11698 receivers = new ArrayList();
11699 ResolveInfo ri = new ResolveInfo();
11700 ri.activityInfo = ai;
11701 receivers.add(ri);
11702 }
11703 } else {
11704 // Need to resolve the intent to interested receivers...
11705 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11706 == 0) {
11707 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011708 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011709 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011710 }
Mihai Preda074edef2009-05-18 17:13:31 +020011711 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011712 }
11713 } catch (RemoteException ex) {
11714 // pm is in same process, this will never happen.
11715 }
11716
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011717 final boolean replacePending =
11718 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11719
Joe Onorato8a9b2202010-02-26 18:56:32 -080011720 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011721 + " replacePending=" + replacePending);
11722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011723 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11724 if (!ordered && NR > 0) {
11725 // If we are not serializing this broadcast, then send the
11726 // registered receivers separately so they don't wait for the
11727 // components to be launched.
11728 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11729 callerPackage, callingPid, callingUid, requiredPermission,
11730 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011731 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011732 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011733 TAG, "Enqueueing parallel broadcast " + r
11734 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011735 boolean replaced = false;
11736 if (replacePending) {
11737 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11738 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011739 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011740 "***** DROPPING PARALLEL: " + intent);
11741 mParallelBroadcasts.set(i, r);
11742 replaced = true;
11743 break;
11744 }
11745 }
11746 }
11747 if (!replaced) {
11748 mParallelBroadcasts.add(r);
11749 scheduleBroadcastsLocked();
11750 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 registeredReceivers = null;
11752 NR = 0;
11753 }
11754
11755 // Merge into one list.
11756 int ir = 0;
11757 if (receivers != null) {
11758 // A special case for PACKAGE_ADDED: do not allow the package
11759 // being added to see this broadcast. This prevents them from
11760 // using this as a back door to get run as soon as they are
11761 // installed. Maybe in the future we want to have a special install
11762 // broadcast or such for apps, but we'd like to deliberately make
11763 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011764 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011765 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11766 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11767 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011768 Uri data = intent.getData();
11769 if (data != null) {
11770 String pkgName = data.getSchemeSpecificPart();
11771 if (pkgName != null) {
11772 skipPackages = new String[] { pkgName };
11773 }
11774 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011775 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011776 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011777 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011778 if (skipPackages != null && (skipPackages.length > 0)) {
11779 for (String skipPackage : skipPackages) {
11780 if (skipPackage != null) {
11781 int NT = receivers.size();
11782 for (int it=0; it<NT; it++) {
11783 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11784 if (curt.activityInfo.packageName.equals(skipPackage)) {
11785 receivers.remove(it);
11786 it--;
11787 NT--;
11788 }
11789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011790 }
11791 }
11792 }
11793
11794 int NT = receivers != null ? receivers.size() : 0;
11795 int it = 0;
11796 ResolveInfo curt = null;
11797 BroadcastFilter curr = null;
11798 while (it < NT && ir < NR) {
11799 if (curt == null) {
11800 curt = (ResolveInfo)receivers.get(it);
11801 }
11802 if (curr == null) {
11803 curr = registeredReceivers.get(ir);
11804 }
11805 if (curr.getPriority() >= curt.priority) {
11806 // Insert this broadcast record into the final list.
11807 receivers.add(it, curr);
11808 ir++;
11809 curr = null;
11810 it++;
11811 NT++;
11812 } else {
11813 // Skip to the next ResolveInfo in the final list.
11814 it++;
11815 curt = null;
11816 }
11817 }
11818 }
11819 while (ir < NR) {
11820 if (receivers == null) {
11821 receivers = new ArrayList();
11822 }
11823 receivers.add(registeredReceivers.get(ir));
11824 ir++;
11825 }
11826
11827 if ((receivers != null && receivers.size() > 0)
11828 || resultTo != null) {
11829 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11830 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011831 receivers, resultTo, resultCode, resultData, map, ordered,
11832 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011833 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 TAG, "Enqueueing ordered broadcast " + r
11835 + ": prev had " + mOrderedBroadcasts.size());
11836 if (DEBUG_BROADCAST) {
11837 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011838 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011839 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011840 boolean replaced = false;
11841 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011842 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011843 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011844 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011845 "***** DROPPING ORDERED: " + intent);
11846 mOrderedBroadcasts.set(i, r);
11847 replaced = true;
11848 break;
11849 }
11850 }
11851 }
11852 if (!replaced) {
11853 mOrderedBroadcasts.add(r);
11854 scheduleBroadcastsLocked();
11855 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011856 }
11857
11858 return BROADCAST_SUCCESS;
11859 }
11860
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011861 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011862 // Refuse possible leaked file descriptors
11863 if (intent != null && intent.hasFileDescriptors() == true) {
11864 throw new IllegalArgumentException("File descriptors passed in Intent");
11865 }
11866
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011867 int flags = intent.getFlags();
11868
11869 if (!mProcessesReady) {
11870 // if the caller really truly claims to know what they're doing, go
11871 // ahead and allow the broadcast without launching any receivers
11872 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11873 intent = new Intent(intent);
11874 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11875 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11876 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11877 + " before boot completion");
11878 throw new IllegalStateException("Cannot broadcast before boot completed");
11879 }
11880 }
11881
11882 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11883 throw new IllegalArgumentException(
11884 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11885 }
11886
11887 return intent;
11888 }
11889
11890 public final int broadcastIntent(IApplicationThread caller,
11891 Intent intent, String resolvedType, IIntentReceiver resultTo,
11892 int resultCode, String resultData, Bundle map,
11893 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011894 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011895 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011897 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11898 final int callingPid = Binder.getCallingPid();
11899 final int callingUid = Binder.getCallingUid();
11900 final long origId = Binder.clearCallingIdentity();
11901 int res = broadcastIntentLocked(callerApp,
11902 callerApp != null ? callerApp.info.packageName : null,
11903 intent, resolvedType, resultTo,
11904 resultCode, resultData, map, requiredPermission, serialized,
11905 sticky, callingPid, callingUid);
11906 Binder.restoreCallingIdentity(origId);
11907 return res;
11908 }
11909 }
11910
11911 int broadcastIntentInPackage(String packageName, int uid,
11912 Intent intent, String resolvedType, IIntentReceiver resultTo,
11913 int resultCode, String resultData, Bundle map,
11914 String requiredPermission, boolean serialized, boolean sticky) {
11915 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011916 intent = verifyBroadcastLocked(intent);
11917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011918 final long origId = Binder.clearCallingIdentity();
11919 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11920 resultTo, resultCode, resultData, map, requiredPermission,
11921 serialized, sticky, -1, uid);
11922 Binder.restoreCallingIdentity(origId);
11923 return res;
11924 }
11925 }
11926
11927 public final void unbroadcastIntent(IApplicationThread caller,
11928 Intent intent) {
11929 // Refuse possible leaked file descriptors
11930 if (intent != null && intent.hasFileDescriptors() == true) {
11931 throw new IllegalArgumentException("File descriptors passed in Intent");
11932 }
11933
11934 synchronized(this) {
11935 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11936 != PackageManager.PERMISSION_GRANTED) {
11937 String msg = "Permission Denial: unbroadcastIntent() from pid="
11938 + Binder.getCallingPid()
11939 + ", uid=" + Binder.getCallingUid()
11940 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011941 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 throw new SecurityException(msg);
11943 }
11944 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11945 if (list != null) {
11946 int N = list.size();
11947 int i;
11948 for (i=0; i<N; i++) {
11949 if (intent.filterEquals(list.get(i))) {
11950 list.remove(i);
11951 break;
11952 }
11953 }
11954 }
11955 }
11956 }
11957
11958 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11959 String resultData, Bundle resultExtras, boolean resultAbort,
11960 boolean explicit) {
11961 if (mOrderedBroadcasts.size() == 0) {
11962 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011963 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 }
11965 return false;
11966 }
11967 BroadcastRecord r = mOrderedBroadcasts.get(0);
11968 if (r.receiver == null) {
11969 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011970 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011971 }
11972 return false;
11973 }
11974 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011975 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976 return false;
11977 }
11978 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011979 r.state = BroadcastRecord.IDLE;
11980 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011981 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011982 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011983 }
11984 }
11985 r.receiver = null;
11986 r.intent.setComponent(null);
11987 if (r.curApp != null) {
11988 r.curApp.curReceiver = null;
11989 }
11990 if (r.curFilter != null) {
11991 r.curFilter.receiverList.curBroadcast = null;
11992 }
11993 r.curFilter = null;
11994 r.curApp = null;
11995 r.curComponent = null;
11996 r.curReceiver = null;
11997 mPendingBroadcast = null;
11998
11999 r.resultCode = resultCode;
12000 r.resultData = resultData;
12001 r.resultExtras = resultExtras;
12002 r.resultAbort = resultAbort;
12003
12004 // We will process the next receiver right now if this is finishing
12005 // an app receiver (which is always asynchronous) or after we have
12006 // come back from calling a receiver.
12007 return state == BroadcastRecord.APP_RECEIVE
12008 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12009 }
12010
12011 public void finishReceiver(IBinder who, int resultCode, String resultData,
12012 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012013 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012014
12015 // Refuse possible leaked file descriptors
12016 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12017 throw new IllegalArgumentException("File descriptors passed in Bundle");
12018 }
12019
12020 boolean doNext;
12021
12022 final long origId = Binder.clearCallingIdentity();
12023
12024 synchronized(this) {
12025 doNext = finishReceiverLocked(
12026 who, resultCode, resultData, resultExtras, resultAbort, true);
12027 }
12028
12029 if (doNext) {
12030 processNextBroadcast(false);
12031 }
12032 trimApplications();
12033
12034 Binder.restoreCallingIdentity(origId);
12035 }
12036
Jeff Brown4d94a762010-09-23 11:33:28 -070012037 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012038 if (r.nextReceiver > 0) {
12039 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12040 if (curReceiver instanceof BroadcastFilter) {
12041 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012042 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012043 System.identityHashCode(r),
12044 r.intent.getAction(),
12045 r.nextReceiver - 1,
12046 System.identityHashCode(bf));
12047 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012048 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012049 System.identityHashCode(r),
12050 r.intent.getAction(),
12051 r.nextReceiver - 1,
12052 ((ResolveInfo)curReceiver).toString());
12053 }
12054 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012055 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012056 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012057 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 System.identityHashCode(r),
12059 r.intent.getAction(),
12060 r.nextReceiver,
12061 "NONE");
12062 }
12063 }
12064
Jeff Brown4d94a762010-09-23 11:33:28 -070012065 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12066 if (! mPendingBroadcastTimeoutMessage) {
12067 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12068 mHandler.sendMessageAtTime(msg, timeoutTime);
12069 mPendingBroadcastTimeoutMessage = true;
12070 }
12071 }
12072
12073 private final void cancelBroadcastTimeoutLocked() {
12074 if (mPendingBroadcastTimeoutMessage) {
12075 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12076 mPendingBroadcastTimeoutMessage = false;
12077 }
12078 }
12079
12080 private final void broadcastTimeoutLocked(boolean fromMsg) {
12081 if (fromMsg) {
12082 mPendingBroadcastTimeoutMessage = false;
12083 }
12084
12085 if (mOrderedBroadcasts.size() == 0) {
12086 return;
12087 }
12088
12089 long now = SystemClock.uptimeMillis();
12090 BroadcastRecord r = mOrderedBroadcasts.get(0);
12091 if (fromMsg) {
12092 if (mDidDexOpt) {
12093 // Delay timeouts until dexopt finishes.
12094 mDidDexOpt = false;
12095 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12096 setBroadcastTimeoutLocked(timeoutTime);
12097 return;
12098 }
12099 if (! mProcessesReady) {
12100 // Only process broadcast timeouts if the system is ready. That way
12101 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12102 // to do heavy lifting for system up.
12103 return;
12104 }
12105
12106 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12107 if (timeoutTime > now) {
12108 // We can observe premature timeouts because we do not cancel and reset the
12109 // broadcast timeout message after each receiver finishes. Instead, we set up
12110 // an initial timeout then kick it down the road a little further as needed
12111 // when it expires.
12112 if (DEBUG_BROADCAST) Slog.v(TAG,
12113 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12114 + timeoutTime);
12115 setBroadcastTimeoutLocked(timeoutTime);
12116 return;
12117 }
12118 }
12119
12120 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12121 + ", started " + (now - r.receiverTime) + "ms ago");
12122 r.receiverTime = now;
12123 r.anrCount++;
12124
12125 // Current receiver has passed its expiration date.
12126 if (r.nextReceiver <= 0) {
12127 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12128 return;
12129 }
12130
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012131 ProcessRecord app = null;
12132 String anrMessage = null;
12133
Jeff Brown4d94a762010-09-23 11:33:28 -070012134 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12135 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12136 logBroadcastReceiverDiscardLocked(r);
12137 if (curReceiver instanceof BroadcastFilter) {
12138 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12139 if (bf.receiverList.pid != 0
12140 && bf.receiverList.pid != MY_PID) {
12141 synchronized (this.mPidsSelfLocked) {
12142 app = this.mPidsSelfLocked.get(
12143 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012145 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012146 } else {
12147 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012148 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012149
Jeff Brown4d94a762010-09-23 11:33:28 -070012150 if (app != null) {
12151 anrMessage = "Broadcast of " + r.intent.toString();
12152 }
12153
12154 if (mPendingBroadcast == r) {
12155 mPendingBroadcast = null;
12156 }
12157
12158 // Move on to the next receiver.
12159 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12160 r.resultExtras, r.resultAbort, true);
12161 scheduleBroadcastsLocked();
12162
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012163 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012164 // Post the ANR to the handler since we do not want to process ANRs while
12165 // potentially holding our lock.
12166 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012168 }
12169
12170 private final void processCurBroadcastLocked(BroadcastRecord r,
12171 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012172 if (DEBUG_BROADCAST) Slog.v(TAG,
12173 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012174 if (app.thread == null) {
12175 throw new RemoteException();
12176 }
12177 r.receiver = app.thread.asBinder();
12178 r.curApp = app;
12179 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012180 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012181
12182 // Tell the application to launch this receiver.
12183 r.intent.setComponent(r.curComponent);
12184
12185 boolean started = false;
12186 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012187 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 "Delivering to component " + r.curComponent
12189 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012190 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012191 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012192 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012193 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012194 if (DEBUG_BROADCAST) Slog.v(TAG,
12195 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 started = true;
12197 } finally {
12198 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012199 if (DEBUG_BROADCAST) Slog.v(TAG,
12200 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 r.receiver = null;
12202 r.curApp = null;
12203 app.curReceiver = null;
12204 }
12205 }
12206
12207 }
12208
Jeff Brown4d94a762010-09-23 11:33:28 -070012209 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012210 Intent intent, int resultCode, String data, Bundle extras,
12211 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012212 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012213 if (app != null && app.thread != null) {
12214 // If we have an app thread, do the call through that so it is
12215 // correctly ordered with other one-way calls.
12216 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012217 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012218 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012219 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 }
12221 }
12222
Jeff Brown4d94a762010-09-23 11:33:28 -070012223 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 BroadcastFilter filter, boolean ordered) {
12225 boolean skip = false;
12226 if (filter.requiredPermission != null) {
12227 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012228 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012229 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012230 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012231 + r.intent.toString()
12232 + " from " + r.callerPackage + " (pid="
12233 + r.callingPid + ", uid=" + r.callingUid + ")"
12234 + " requires " + filter.requiredPermission
12235 + " due to registered receiver " + filter);
12236 skip = true;
12237 }
12238 }
12239 if (r.requiredPermission != null) {
12240 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012241 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012242 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012243 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012244 + r.intent.toString()
12245 + " to " + filter.receiverList.app
12246 + " (pid=" + filter.receiverList.pid
12247 + ", uid=" + filter.receiverList.uid + ")"
12248 + " requires " + r.requiredPermission
12249 + " due to sender " + r.callerPackage
12250 + " (uid " + r.callingUid + ")");
12251 skip = true;
12252 }
12253 }
12254
12255 if (!skip) {
12256 // If this is not being sent as an ordered broadcast, then we
12257 // don't want to touch the fields that keep track of the current
12258 // state of ordered broadcasts.
12259 if (ordered) {
12260 r.receiver = filter.receiverList.receiver.asBinder();
12261 r.curFilter = filter;
12262 filter.receiverList.curBroadcast = r;
12263 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012264 if (filter.receiverList.app != null) {
12265 // Bump hosting application to no longer be in background
12266 // scheduling class. Note that we can't do that if there
12267 // isn't an app... but we can only be in that case for
12268 // things that directly call the IActivityManager API, which
12269 // are already core system stuff so don't matter for this.
12270 r.curApp = filter.receiverList.app;
12271 filter.receiverList.app.curReceiver = r;
12272 updateOomAdjLocked();
12273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012274 }
12275 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012276 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012277 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012278 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012279 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012280 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012281 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012282 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012283 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 if (ordered) {
12285 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12286 }
12287 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012288 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289 if (ordered) {
12290 r.receiver = null;
12291 r.curFilter = null;
12292 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012293 if (filter.receiverList.app != null) {
12294 filter.receiverList.app.curReceiver = null;
12295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012296 }
12297 }
12298 }
12299 }
12300
Dianne Hackborn12527f92009-11-11 17:39:50 -080012301 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12302 if (r.callingUid < 0) {
12303 // This was from a registerReceiver() call; ignore it.
12304 return;
12305 }
12306 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12307 MAX_BROADCAST_HISTORY-1);
12308 r.finishTime = SystemClock.uptimeMillis();
12309 mBroadcastHistory[0] = r;
12310 }
12311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012312 private final void processNextBroadcast(boolean fromMsg) {
12313 synchronized(this) {
12314 BroadcastRecord r;
12315
Joe Onorato8a9b2202010-02-26 18:56:32 -080012316 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012317 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012318 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012319
12320 updateCpuStats();
12321
12322 if (fromMsg) {
12323 mBroadcastsScheduled = false;
12324 }
12325
12326 // First, deliver any non-serialized broadcasts right away.
12327 while (mParallelBroadcasts.size() > 0) {
12328 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012329 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012330 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012331 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012332 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012333 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012334 for (int i=0; i<N; i++) {
12335 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012336 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012337 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012339 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012340 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012341 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012342 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012343 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012344 }
12345
12346 // Now take care of the next serialized one...
12347
12348 // If we are waiting for a process to come up to handle the next
12349 // broadcast, then do nothing at this point. Just in case, we
12350 // check that the process we're waiting for still exists.
12351 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012352 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012353 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012354 + mPendingBroadcast.curApp);
12355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012356
12357 boolean isDead;
12358 synchronized (mPidsSelfLocked) {
12359 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12360 }
12361 if (!isDead) {
12362 // It's still alive, so keep waiting
12363 return;
12364 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012365 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012366 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012367 mPendingBroadcast.state = BroadcastRecord.IDLE;
12368 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012369 mPendingBroadcast = null;
12370 }
12371 }
12372
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012373 boolean looped = false;
12374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012375 do {
12376 if (mOrderedBroadcasts.size() == 0) {
12377 // No more broadcasts pending, so all done!
12378 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012379 if (looped) {
12380 // If we had finished the last ordered broadcast, then
12381 // make sure all processes have correct oom and sched
12382 // adjustments.
12383 updateOomAdjLocked();
12384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012385 return;
12386 }
12387 r = mOrderedBroadcasts.get(0);
12388 boolean forceReceive = false;
12389
12390 // Ensure that even if something goes awry with the timeout
12391 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012392 // and continue to make progress.
12393 //
12394 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012395 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012396 // one time heavy lifting after system upgrades and can take
12397 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012398 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012399 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012400 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012401 if ((numReceivers > 0) &&
12402 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012403 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012404 + " now=" + now
12405 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012406 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012407 + " intent=" + r.intent
12408 + " numReceivers=" + numReceivers
12409 + " nextReceiver=" + r.nextReceiver
12410 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012411 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 forceReceive = true;
12413 r.state = BroadcastRecord.IDLE;
12414 }
12415 }
12416
12417 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012418 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012419 "processNextBroadcast() called when not idle (state="
12420 + r.state + ")");
12421 return;
12422 }
12423
12424 if (r.receivers == null || r.nextReceiver >= numReceivers
12425 || r.resultAbort || forceReceive) {
12426 // No more receivers for this broadcast! Send the final
12427 // result if requested...
12428 if (r.resultTo != null) {
12429 try {
12430 if (DEBUG_BROADCAST) {
12431 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012432 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012433 + " seq=" + seq + " app=" + r.callerApp);
12434 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012435 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012436 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012437 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012438 // Set this to null so that the reference
12439 // (local and remote) isnt kept in the mBroadcastHistory.
12440 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012441 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012442 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 }
12444 }
12445
Joe Onorato8a9b2202010-02-26 18:56:32 -080012446 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012447 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012448
Joe Onorato8a9b2202010-02-26 18:56:32 -080012449 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012450 + r);
12451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012452 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012453 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 mOrderedBroadcasts.remove(0);
12455 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012456 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012457 continue;
12458 }
12459 } while (r == null);
12460
12461 // Get the next receiver...
12462 int recIdx = r.nextReceiver++;
12463
12464 // Keep track of when this receiver started, and make sure there
12465 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012466 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012467 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012468 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012469 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012470 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012471 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012472 }
12473 if (! mPendingBroadcastTimeoutMessage) {
12474 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012475 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012476 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12477 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012478 }
12479
12480 Object nextReceiver = r.receivers.get(recIdx);
12481 if (nextReceiver instanceof BroadcastFilter) {
12482 // Simple case: this is a registered receiver who gets
12483 // a direct call.
12484 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012485 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012486 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012487 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012488 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012489 if (r.receiver == null || !r.ordered) {
12490 // The receiver has already finished, so schedule to
12491 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012492 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12493 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012494 r.state = BroadcastRecord.IDLE;
12495 scheduleBroadcastsLocked();
12496 }
12497 return;
12498 }
12499
12500 // Hard case: need to instantiate the receiver, possibly
12501 // starting its application process to host it.
12502
12503 ResolveInfo info =
12504 (ResolveInfo)nextReceiver;
12505
12506 boolean skip = false;
12507 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012508 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12509 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012510 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012511 if (!info.activityInfo.exported) {
12512 Slog.w(TAG, "Permission Denial: broadcasting "
12513 + r.intent.toString()
12514 + " from " + r.callerPackage + " (pid=" + r.callingPid
12515 + ", uid=" + r.callingUid + ")"
12516 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12517 + " due to receiver " + info.activityInfo.packageName
12518 + "/" + info.activityInfo.name);
12519 } else {
12520 Slog.w(TAG, "Permission Denial: broadcasting "
12521 + r.intent.toString()
12522 + " from " + r.callerPackage + " (pid=" + r.callingPid
12523 + ", uid=" + r.callingUid + ")"
12524 + " requires " + info.activityInfo.permission
12525 + " due to receiver " + info.activityInfo.packageName
12526 + "/" + info.activityInfo.name);
12527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012528 skip = true;
12529 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012530 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012531 r.requiredPermission != null) {
12532 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012533 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012534 checkPermission(r.requiredPermission,
12535 info.activityInfo.applicationInfo.packageName);
12536 } catch (RemoteException e) {
12537 perm = PackageManager.PERMISSION_DENIED;
12538 }
12539 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012540 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012541 + r.intent + " to "
12542 + info.activityInfo.applicationInfo.packageName
12543 + " requires " + r.requiredPermission
12544 + " due to sender " + r.callerPackage
12545 + " (uid " + r.callingUid + ")");
12546 skip = true;
12547 }
12548 }
12549 if (r.curApp != null && r.curApp.crashing) {
12550 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012551 if (DEBUG_BROADCAST) Slog.v(TAG,
12552 "Skipping deliver ordered " + r + " to " + r.curApp
12553 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012554 skip = true;
12555 }
12556
12557 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012558 if (DEBUG_BROADCAST) Slog.v(TAG,
12559 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012560 r.receiver = null;
12561 r.curFilter = null;
12562 r.state = BroadcastRecord.IDLE;
12563 scheduleBroadcastsLocked();
12564 return;
12565 }
12566
12567 r.state = BroadcastRecord.APP_RECEIVE;
12568 String targetProcess = info.activityInfo.processName;
12569 r.curComponent = new ComponentName(
12570 info.activityInfo.applicationInfo.packageName,
12571 info.activityInfo.name);
12572 r.curReceiver = info.activityInfo;
12573
Dianne Hackborne7f97212011-02-24 14:40:20 -080012574 // Broadcast is being executed, its package can't be stopped.
12575 try {
12576 AppGlobals.getPackageManager().setPackageStoppedState(
12577 r.curComponent.getPackageName(), false);
12578 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012579 } catch (IllegalArgumentException e) {
12580 Slog.w(TAG, "Failed trying to unstop package "
12581 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012582 }
12583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012584 // Is this receiver's application already running?
12585 ProcessRecord app = getProcessRecordLocked(targetProcess,
12586 info.activityInfo.applicationInfo.uid);
12587 if (app != null && app.thread != null) {
12588 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012589 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012590 processCurBroadcastLocked(r, app);
12591 return;
12592 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012593 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012594 + r.curComponent, e);
12595 }
12596
12597 // If a dead object exception was thrown -- fall through to
12598 // restart the application.
12599 }
12600
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012601 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012602 if (DEBUG_BROADCAST) Slog.v(TAG,
12603 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012604 if ((r.curApp=startProcessLocked(targetProcess,
12605 info.activityInfo.applicationInfo, true,
12606 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012607 "broadcast", r.curComponent,
12608 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12609 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012610 // Ah, this recipient is unavailable. Finish it if necessary,
12611 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012612 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012613 + info.activityInfo.applicationInfo.packageName + "/"
12614 + info.activityInfo.applicationInfo.uid + " for broadcast "
12615 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012616 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012617 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12618 r.resultExtras, r.resultAbort, true);
12619 scheduleBroadcastsLocked();
12620 r.state = BroadcastRecord.IDLE;
12621 return;
12622 }
12623
12624 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012625 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012626 }
12627 }
12628
12629 // =========================================================
12630 // INSTRUMENTATION
12631 // =========================================================
12632
12633 public boolean startInstrumentation(ComponentName className,
12634 String profileFile, int flags, Bundle arguments,
12635 IInstrumentationWatcher watcher) {
12636 // Refuse possible leaked file descriptors
12637 if (arguments != null && arguments.hasFileDescriptors()) {
12638 throw new IllegalArgumentException("File descriptors passed in Bundle");
12639 }
12640
12641 synchronized(this) {
12642 InstrumentationInfo ii = null;
12643 ApplicationInfo ai = null;
12644 try {
12645 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012646 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012647 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012648 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012649 } catch (PackageManager.NameNotFoundException e) {
12650 }
12651 if (ii == null) {
12652 reportStartInstrumentationFailure(watcher, className,
12653 "Unable to find instrumentation info for: " + className);
12654 return false;
12655 }
12656 if (ai == null) {
12657 reportStartInstrumentationFailure(watcher, className,
12658 "Unable to find instrumentation target package: " + ii.targetPackage);
12659 return false;
12660 }
12661
12662 int match = mContext.getPackageManager().checkSignatures(
12663 ii.targetPackage, ii.packageName);
12664 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12665 String msg = "Permission Denial: starting instrumentation "
12666 + className + " from pid="
12667 + Binder.getCallingPid()
12668 + ", uid=" + Binder.getCallingPid()
12669 + " not allowed because package " + ii.packageName
12670 + " does not have a signature matching the target "
12671 + ii.targetPackage;
12672 reportStartInstrumentationFailure(watcher, className, msg);
12673 throw new SecurityException(msg);
12674 }
12675
12676 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012677 // Instrumentation can kill and relaunch even persistent processes
12678 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012679 ProcessRecord app = addAppLocked(ai);
12680 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012681 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012682 app.instrumentationProfileFile = profileFile;
12683 app.instrumentationArguments = arguments;
12684 app.instrumentationWatcher = watcher;
12685 app.instrumentationResultClass = className;
12686 Binder.restoreCallingIdentity(origId);
12687 }
12688
12689 return true;
12690 }
12691
12692 /**
12693 * Report errors that occur while attempting to start Instrumentation. Always writes the
12694 * error to the logs, but if somebody is watching, send the report there too. This enables
12695 * the "am" command to report errors with more information.
12696 *
12697 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12698 * @param cn The component name of the instrumentation.
12699 * @param report The error report.
12700 */
12701 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12702 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012703 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012704 try {
12705 if (watcher != null) {
12706 Bundle results = new Bundle();
12707 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12708 results.putString("Error", report);
12709 watcher.instrumentationStatus(cn, -1, results);
12710 }
12711 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012712 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012713 }
12714 }
12715
12716 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12717 if (app.instrumentationWatcher != null) {
12718 try {
12719 // NOTE: IInstrumentationWatcher *must* be oneway here
12720 app.instrumentationWatcher.instrumentationFinished(
12721 app.instrumentationClass,
12722 resultCode,
12723 results);
12724 } catch (RemoteException e) {
12725 }
12726 }
12727 app.instrumentationWatcher = null;
12728 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012729 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012730 app.instrumentationProfileFile = null;
12731 app.instrumentationArguments = null;
12732
Christopher Tate3dacd842011-08-19 14:56:15 -070012733 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012734 }
12735
12736 public void finishInstrumentation(IApplicationThread target,
12737 int resultCode, Bundle results) {
12738 // Refuse possible leaked file descriptors
12739 if (results != null && results.hasFileDescriptors()) {
12740 throw new IllegalArgumentException("File descriptors passed in Intent");
12741 }
12742
12743 synchronized(this) {
12744 ProcessRecord app = getRecordForAppLocked(target);
12745 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012746 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012747 return;
12748 }
12749 final long origId = Binder.clearCallingIdentity();
12750 finishInstrumentationLocked(app, resultCode, results);
12751 Binder.restoreCallingIdentity(origId);
12752 }
12753 }
12754
12755 // =========================================================
12756 // CONFIGURATION
12757 // =========================================================
12758
12759 public ConfigurationInfo getDeviceConfigurationInfo() {
12760 ConfigurationInfo config = new ConfigurationInfo();
12761 synchronized (this) {
12762 config.reqTouchScreen = mConfiguration.touchscreen;
12763 config.reqKeyboardType = mConfiguration.keyboard;
12764 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012765 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12766 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012767 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12768 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012769 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12770 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012771 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12772 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012773 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012774 }
12775 return config;
12776 }
12777
12778 public Configuration getConfiguration() {
12779 Configuration ci;
12780 synchronized(this) {
12781 ci = new Configuration(mConfiguration);
12782 }
12783 return ci;
12784 }
12785
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012786 public void updatePersistentConfiguration(Configuration values) {
12787 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12788 "updateConfiguration()");
12789 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12790 "updateConfiguration()");
12791 if (values == null) {
12792 throw new NullPointerException("Configuration must not be null");
12793 }
12794
12795 synchronized(this) {
12796 final long origId = Binder.clearCallingIdentity();
12797 updateConfigurationLocked(values, null, true);
12798 Binder.restoreCallingIdentity(origId);
12799 }
12800 }
12801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 public void updateConfiguration(Configuration values) {
12803 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12804 "updateConfiguration()");
12805
12806 synchronized(this) {
12807 if (values == null && mWindowManager != null) {
12808 // sentinel: fetch the current configuration from the window manager
12809 values = mWindowManager.computeNewConfiguration();
12810 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012811
12812 if (mWindowManager != null) {
12813 mProcessList.applyDisplaySize(mWindowManager);
12814 }
12815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012816 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012817 if (values != null) {
12818 Settings.System.clearConfiguration(values);
12819 }
12820 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012821 Binder.restoreCallingIdentity(origId);
12822 }
12823 }
12824
12825 /**
12826 * Do either or both things: (1) change the current configuration, and (2)
12827 * make sure the given activity is running with the (now) current
12828 * configuration. Returns true if the activity has been left running, or
12829 * false if <var>starting</var> is being destroyed to match the new
12830 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012831 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832 */
12833 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012834 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012835 int changes = 0;
12836
12837 boolean kept = true;
12838
12839 if (values != null) {
12840 Configuration newConfig = new Configuration(mConfiguration);
12841 changes = newConfig.updateFrom(values);
12842 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012843 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012844 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845 }
12846
Doug Zongker2bec3d42009-12-04 12:52:44 -080012847 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012848
12849 if (values.locale != null) {
12850 saveLocaleLocked(values.locale,
12851 !values.locale.equals(mConfiguration.locale),
12852 values.userSetLocale);
12853 }
12854
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012855 mConfigurationSeq++;
12856 if (mConfigurationSeq <= 0) {
12857 mConfigurationSeq = 1;
12858 }
12859 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012860 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012861 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012862
12863 AttributeCache ac = AttributeCache.instance();
12864 if (ac != null) {
12865 ac.updateConfiguration(mConfiguration);
12866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012867
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012868 // Make sure all resources in our process are updated
12869 // right now, so that anyone who is going to retrieve
12870 // resource values after we return will be sure to get
12871 // the new ones. This is especially important during
12872 // boot, where the first config change needs to guarantee
12873 // all resources have that config before following boot
12874 // code is executed.
12875 mSystemThread.applyConfigurationToResources(newConfig);
12876
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012877 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012878 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12879 msg.obj = new Configuration(mConfiguration);
12880 mHandler.sendMessage(msg);
12881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012882
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012883 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12884 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012885 try {
12886 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012887 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012888 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012889 app.thread.scheduleConfigurationChanged(mConfiguration);
12890 }
12891 } catch (Exception e) {
12892 }
12893 }
12894 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012895 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12896 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012897 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12898 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012899 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12900 broadcastIntentLocked(null, null,
12901 new Intent(Intent.ACTION_LOCALE_CHANGED),
12902 null, null, 0, null, null,
12903 null, false, false, MY_PID, Process.SYSTEM_UID);
12904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012905 }
12906 }
12907
12908 if (changes != 0 && starting == null) {
12909 // If the configuration changed, and the caller is not already
12910 // in the process of starting an activity, then find the top
12911 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012912 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012913 }
12914
12915 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012916 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012917 // And we need to make sure at this point that all other activities
12918 // are made visible with the correct configuration.
12919 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012920 }
12921
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012922 if (values != null && mWindowManager != null) {
12923 mWindowManager.setNewConfiguration(mConfiguration);
12924 }
12925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012926 return kept;
12927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012928
12929 /**
12930 * Save the locale. You must be inside a synchronized (this) block.
12931 */
12932 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12933 if(isDiff) {
12934 SystemProperties.set("user.language", l.getLanguage());
12935 SystemProperties.set("user.region", l.getCountry());
12936 }
12937
12938 if(isPersist) {
12939 SystemProperties.set("persist.sys.language", l.getLanguage());
12940 SystemProperties.set("persist.sys.country", l.getCountry());
12941 SystemProperties.set("persist.sys.localevar", l.getVariant());
12942 }
12943 }
12944
12945 // =========================================================
12946 // LIFETIME MANAGEMENT
12947 // =========================================================
12948
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012949 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012950 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012951 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012952 // This adjustment has already been computed. If we are calling
12953 // from the top, we may have already computed our adjustment with
12954 // an earlier hidden adjustment that isn't really for us... if
12955 // so, use the new hidden adjustment.
12956 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012957 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012958 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012959 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012960 }
12961
12962 if (app.thread == null) {
12963 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012964 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012965 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966 }
12967
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012968 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12969 app.adjSource = null;
12970 app.adjTarget = null;
12971 app.empty = false;
12972 app.hidden = false;
12973
12974 final int activitiesSize = app.activities.size();
12975
Dianne Hackborn7d608422011-08-07 16:24:18 -070012976 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012977 // The max adjustment doesn't allow this app to be anything
12978 // below foreground, so it is not worth doing work for it.
12979 app.adjType = "fixed";
12980 app.adjSeq = mAdjSeq;
12981 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012982 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012983 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012984 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012985 // System process can do UI, and when they do we want to have
12986 // them trim their memory after the user leaves the UI. To
12987 // facilitate this, here we need to determine whether or not it
12988 // is currently showing UI.
12989 app.systemNoUi = true;
12990 if (app == TOP_APP) {
12991 app.systemNoUi = false;
12992 } else if (activitiesSize > 0) {
12993 for (int j = 0; j < activitiesSize; j++) {
12994 final ActivityRecord r = app.activities.get(j);
12995 if (r.visible) {
12996 app.systemNoUi = false;
12997 break;
12998 }
12999 }
13000 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013001 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013002 }
13003
13004 final boolean hadForegroundActivities = app.foregroundActivities;
13005
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013006 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013007 app.keeping = false;
13008 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013009
The Android Open Source Project4df24232009-03-05 14:34:35 -080013010 // Determine the importance of the process, starting with most
13011 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013012 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013013 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013014 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013015 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013016 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013017 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013018 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013019 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013020 } else if (app.instrumentationClass != null) {
13021 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013022 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013023 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013024 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013025 } else if (app.curReceiver != null ||
13026 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13027 // An app that is currently receiving a broadcast also
13028 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013029 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013030 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013031 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013032 } else if (app.executingServices.size() > 0) {
13033 // An app that is currently executing a service callback also
13034 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013035 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013036 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013037 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013038 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013039 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013040 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013041 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013042 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013043 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013044 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013045 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013046 // A very not-needed process. If this is lower in the lru list,
13047 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013048 adj = hiddenAdj;
13049 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013050 app.hidden = true;
13051 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013052 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013054
13055 // Examine all activities if not already foreground.
13056 if (!app.foregroundActivities && activitiesSize > 0) {
13057 for (int j = 0; j < activitiesSize; j++) {
13058 final ActivityRecord r = app.activities.get(j);
13059 if (r.visible) {
13060 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013061 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13062 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013063 app.adjType = "visible";
13064 }
13065 schedGroup = Process.THREAD_GROUP_DEFAULT;
13066 app.hidden = false;
13067 app.foregroundActivities = true;
13068 break;
13069 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13070 || r.state == ActivityState.STOPPING) {
13071 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013072 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13073 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013074 app.adjType = "stopping";
13075 }
13076 app.foregroundActivities = true;
13077 }
13078 }
13079 }
13080
Dianne Hackborn7d608422011-08-07 16:24:18 -070013081 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013082 if (app.foregroundServices) {
13083 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013084 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013085 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013086 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013087 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013088 } else if (app.forcingToForeground != null) {
13089 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013090 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013091 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013092 app.adjType = "force-foreground";
13093 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013094 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013095 }
13096 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013097
Dianne Hackborn7d608422011-08-07 16:24:18 -070013098 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013099 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013100 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013101 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013102 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013103 app.adjType = "heavy";
13104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013105
Dianne Hackborn7d608422011-08-07 16:24:18 -070013106 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013107 // This process is hosting what we currently consider to be the
13108 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013109 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013110 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013111 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013112 app.adjType = "home";
13113 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013114
13115 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13116 + " reason=" + app.adjType);
13117
The Android Open Source Project4df24232009-03-05 14:34:35 -080013118 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013119 // there are applications dependent on our services or providers, but
13120 // this gives us a baseline and makes sure we don't get into an
13121 // infinite recursion.
13122 app.adjSeq = mAdjSeq;
13123 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013124
Christopher Tate6fa95972009-06-05 18:43:55 -070013125 if (mBackupTarget != null && app == mBackupTarget.app) {
13126 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013127 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013128 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013129 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013130 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013131 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013132 }
13133 }
13134
Dianne Hackborn7d608422011-08-07 16:24:18 -070013135 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013136 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013137 final long now = SystemClock.uptimeMillis();
13138 // This process is more important if the top activity is
13139 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013140 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013141 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013142 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013143 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013144 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013145 // If this process has shown some UI, let it immediately
13146 // go to the LRU list because it may be pretty heavy with
13147 // UI stuff. We'll tag it with a label just to help
13148 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013149 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013150 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013152 } else {
13153 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13154 // This service has seen some activity within
13155 // recent memory, so we will keep its process ahead
13156 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013157 if (adj > ProcessList.SERVICE_ADJ) {
13158 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013159 app.adjType = "started-services";
13160 app.hidden = false;
13161 }
13162 }
13163 // If we have let the service slide into the background
13164 // state, still have some text describing what it is doing
13165 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013166 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013167 app.adjType = "started-bg-services";
13168 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013169 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013170 // Don't kill this process because it is doing work; it
13171 // has said it is doing work.
13172 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013173 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013174 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013175 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013176 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013177 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013178 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013179 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013180 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013181 // XXX should compute this based on the max of
13182 // all connected clients.
13183 ConnectionRecord cr = clist.get(i);
13184 if (cr.binding.client == app) {
13185 // Binding to ourself is not interesting.
13186 continue;
13187 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013188 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013189 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013190 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013191 int myHiddenAdj = hiddenAdj;
13192 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013193 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013194 myHiddenAdj = client.hiddenAdj;
13195 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013196 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013197 }
13198 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013199 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013200 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013201 String adjType = null;
13202 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13203 // Not doing bind OOM management, so treat
13204 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013205 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013206 // If this process has shown some UI, let it immediately
13207 // go to the LRU list because it may be pretty heavy with
13208 // UI stuff. We'll tag it with a label just to help
13209 // debug and understand what is going on.
13210 if (adj > clientAdj) {
13211 adjType = "bound-bg-ui-services";
13212 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013213 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013214 clientAdj = adj;
13215 } else {
13216 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13217 // This service has not seen activity within
13218 // recent memory, so allow it to drop to the
13219 // LRU list if there is no other reason to keep
13220 // it around. We'll also tag it with a label just
13221 // to help debug and undertand what is going on.
13222 if (adj > clientAdj) {
13223 adjType = "bound-bg-services";
13224 }
13225 clientAdj = adj;
13226 }
13227 }
13228 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013229 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013230 // If this process has recently shown UI, and
13231 // the process that is binding to it is less
13232 // important than being visible, then we don't
13233 // care about the binding as much as we care
13234 // about letting this process get into the LRU
13235 // list to be killed and restarted if needed for
13236 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013237 if (app.hasShownUi && app != mHomeProcess
13238 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013239 adjType = "bound-bg-ui-services";
13240 } else {
13241 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13242 |Context.BIND_IMPORTANT)) != 0) {
13243 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013244 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013245 adj = clientAdj;
13246 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013247 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013248 }
13249 if (!client.hidden) {
13250 app.hidden = false;
13251 }
13252 if (client.keeping) {
13253 app.keeping = true;
13254 }
13255 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013256 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013257 }
13258 if (adjType != null) {
13259 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013260 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13261 .REASON_SERVICE_IN_USE;
13262 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013263 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013264 app.adjTarget = s.name;
13265 }
13266 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13267 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13268 schedGroup = Process.THREAD_GROUP_DEFAULT;
13269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013270 }
13271 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013272 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13273 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013274 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013275 (a.visible || a.state == ActivityState.RESUMED
13276 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013277 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013278 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13279 schedGroup = Process.THREAD_GROUP_DEFAULT;
13280 }
13281 app.hidden = false;
13282 app.adjType = "service";
13283 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13284 .REASON_SERVICE_IN_USE;
13285 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013286 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013287 app.adjTarget = s.name;
13288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013290 }
13291 }
13292 }
13293 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013294
Dianne Hackborn287952c2010-09-22 22:34:31 -070013295 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013296 // would like to avoid killing it unless it would prevent the current
13297 // application from running. By default we put the process in
13298 // with the rest of the background processes; as we scan through
13299 // its services we may bump it up from there.
13300 if (adj > hiddenAdj) {
13301 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013302 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013303 app.adjType = "bg-services";
13304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013305 }
13306
Dianne Hackborn7d608422011-08-07 16:24:18 -070013307 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013308 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013309 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013310 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013311 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013312 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013313 if (cpr.clients.size() != 0) {
13314 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013315 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013316 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013317 if (client == app) {
13318 // Being our own client is not interesting.
13319 continue;
13320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013321 int myHiddenAdj = hiddenAdj;
13322 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013323 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013324 myHiddenAdj = client.hiddenAdj;
13325 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013326 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013327 }
13328 }
13329 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013330 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013331 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013332 if (app.hasShownUi && app != mHomeProcess
13333 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013334 app.adjType = "bg-ui-provider";
13335 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013336 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13337 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013338 app.adjType = "provider";
13339 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013340 if (!client.hidden) {
13341 app.hidden = false;
13342 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013343 if (client.keeping) {
13344 app.keeping = true;
13345 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013346 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13347 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013348 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013349 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013350 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013351 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013352 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13353 schedGroup = Process.THREAD_GROUP_DEFAULT;
13354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013355 }
13356 }
13357 // If the provider has external (non-framework) process
13358 // dependencies, ensure that its adjustment is at least
13359 // FOREGROUND_APP_ADJ.
13360 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013361 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13362 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013363 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013364 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013365 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013366 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013367 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013368 }
13369 }
13370 }
13371 }
13372
13373 app.curRawAdj = adj;
13374
Joe Onorato8a9b2202010-02-26 18:56:32 -080013375 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013376 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13377 if (adj > app.maxAdj) {
13378 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013379 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013380 schedGroup = Process.THREAD_GROUP_DEFAULT;
13381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013382 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013383 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013384 app.keeping = true;
13385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013386
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013387 if (app.hasAboveClient) {
13388 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13389 // then we need to drop its adjustment to be lower than the service's
13390 // in order to honor the request. We want to drop it by one adjustment
13391 // level... but there is special meaning applied to various levels so
13392 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013393 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013394 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013395 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13396 adj = ProcessList.VISIBLE_APP_ADJ;
13397 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13398 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13399 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13400 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013401 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013402 adj++;
13403 }
13404 }
13405
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013406 if (adj == ProcessList.SERVICE_ADJ) {
13407 if (doingAll) {
13408 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13409 mNewNumServiceProcs++;
13410 }
13411 if (app.serviceb) {
13412 adj = ProcessList.SERVICE_B_ADJ;
13413 }
13414 } else {
13415 app.serviceb = false;
13416 }
13417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013418 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013419 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013420
13421 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013422 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13423 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013424 }
13425
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013426 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013427 }
13428
13429 /**
13430 * Ask a given process to GC right now.
13431 */
13432 final void performAppGcLocked(ProcessRecord app) {
13433 try {
13434 app.lastRequestedGc = SystemClock.uptimeMillis();
13435 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013436 if (app.reportLowMemory) {
13437 app.reportLowMemory = false;
13438 app.thread.scheduleLowMemory();
13439 } else {
13440 app.thread.processInBackground();
13441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013442 }
13443 } catch (Exception e) {
13444 // whatever.
13445 }
13446 }
13447
13448 /**
13449 * Returns true if things are idle enough to perform GCs.
13450 */
Josh Bartel7f208742010-02-25 11:01:44 -060013451 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013452 return mParallelBroadcasts.size() == 0
13453 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013454 && (mSleeping || (mMainStack.mResumedActivity != null &&
13455 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013456 }
13457
13458 /**
13459 * Perform GCs on all processes that are waiting for it, but only
13460 * if things are idle.
13461 */
13462 final void performAppGcsLocked() {
13463 final int N = mProcessesToGc.size();
13464 if (N <= 0) {
13465 return;
13466 }
Josh Bartel7f208742010-02-25 11:01:44 -060013467 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013468 while (mProcessesToGc.size() > 0) {
13469 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013470 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013471 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13472 <= SystemClock.uptimeMillis()) {
13473 // To avoid spamming the system, we will GC processes one
13474 // at a time, waiting a few seconds between each.
13475 performAppGcLocked(proc);
13476 scheduleAppGcsLocked();
13477 return;
13478 } else {
13479 // It hasn't been long enough since we last GCed this
13480 // process... put it in the list to wait for its time.
13481 addProcessToGcListLocked(proc);
13482 break;
13483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013484 }
13485 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013486
13487 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013488 }
13489 }
13490
13491 /**
13492 * If all looks good, perform GCs on all processes waiting for them.
13493 */
13494 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013495 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013496 performAppGcsLocked();
13497 return;
13498 }
13499 // Still not idle, wait some more.
13500 scheduleAppGcsLocked();
13501 }
13502
13503 /**
13504 * Schedule the execution of all pending app GCs.
13505 */
13506 final void scheduleAppGcsLocked() {
13507 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013508
13509 if (mProcessesToGc.size() > 0) {
13510 // Schedule a GC for the time to the next process.
13511 ProcessRecord proc = mProcessesToGc.get(0);
13512 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13513
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013514 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013515 long now = SystemClock.uptimeMillis();
13516 if (when < (now+GC_TIMEOUT)) {
13517 when = now + GC_TIMEOUT;
13518 }
13519 mHandler.sendMessageAtTime(msg, when);
13520 }
13521 }
13522
13523 /**
13524 * Add a process to the array of processes waiting to be GCed. Keeps the
13525 * list in sorted order by the last GC time. The process can't already be
13526 * on the list.
13527 */
13528 final void addProcessToGcListLocked(ProcessRecord proc) {
13529 boolean added = false;
13530 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13531 if (mProcessesToGc.get(i).lastRequestedGc <
13532 proc.lastRequestedGc) {
13533 added = true;
13534 mProcessesToGc.add(i+1, proc);
13535 break;
13536 }
13537 }
13538 if (!added) {
13539 mProcessesToGc.add(0, proc);
13540 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013541 }
13542
13543 /**
13544 * Set up to ask a process to GC itself. This will either do it
13545 * immediately, or put it on the list of processes to gc the next
13546 * time things are idle.
13547 */
13548 final void scheduleAppGcLocked(ProcessRecord app) {
13549 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013550 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013551 return;
13552 }
13553 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013554 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013555 scheduleAppGcsLocked();
13556 }
13557 }
13558
Dianne Hackborn287952c2010-09-22 22:34:31 -070013559 final void checkExcessivePowerUsageLocked(boolean doKills) {
13560 updateCpuStatsNow();
13561
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013562 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013563 boolean doWakeKills = doKills;
13564 boolean doCpuKills = doKills;
13565 if (mLastPowerCheckRealtime == 0) {
13566 doWakeKills = false;
13567 }
13568 if (mLastPowerCheckUptime == 0) {
13569 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013570 }
13571 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013572 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013573 }
13574 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013575 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13576 final long curUptime = SystemClock.uptimeMillis();
13577 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13578 mLastPowerCheckRealtime = curRealtime;
13579 mLastPowerCheckUptime = curUptime;
13580 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13581 doWakeKills = false;
13582 }
13583 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13584 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013585 }
13586 int i = mLruProcesses.size();
13587 while (i > 0) {
13588 i--;
13589 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013590 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013591 long wtime;
13592 synchronized (stats) {
13593 wtime = stats.getProcessWakeTime(app.info.uid,
13594 app.pid, curRealtime);
13595 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013596 long wtimeUsed = wtime - app.lastWakeTime;
13597 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13598 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013599 StringBuilder sb = new StringBuilder(128);
13600 sb.append("Wake for ");
13601 app.toShortString(sb);
13602 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013603 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013604 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013605 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013606 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013607 sb.append((wtimeUsed*100)/realtimeSince);
13608 sb.append("%)");
13609 Slog.i(TAG, sb.toString());
13610 sb.setLength(0);
13611 sb.append("CPU for ");
13612 app.toShortString(sb);
13613 sb.append(": over ");
13614 TimeUtils.formatDuration(uptimeSince, sb);
13615 sb.append(" used ");
13616 TimeUtils.formatDuration(cputimeUsed, sb);
13617 sb.append(" (");
13618 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013619 sb.append("%)");
13620 Slog.i(TAG, sb.toString());
13621 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013622 // If a process has held a wake lock for more
13623 // than 50% of the time during this period,
13624 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013625 if (doWakeKills && realtimeSince > 0
13626 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13627 synchronized (stats) {
13628 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13629 realtimeSince, wtimeUsed);
13630 }
13631 Slog.w(TAG, "Excessive wake lock in " + app.processName
13632 + " (pid " + app.pid + "): held " + wtimeUsed
13633 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013634 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13635 app.processName, app.setAdj, "excessive wake lock");
13636 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013637 } else if (doCpuKills && uptimeSince > 0
13638 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13639 synchronized (stats) {
13640 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13641 uptimeSince, cputimeUsed);
13642 }
13643 Slog.w(TAG, "Excessive CPU in " + app.processName
13644 + " (pid " + app.pid + "): used " + cputimeUsed
13645 + " during " + uptimeSince);
13646 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13647 app.processName, app.setAdj, "excessive cpu");
13648 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013649 } else {
13650 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013651 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013652 }
13653 }
13654 }
13655 }
13656
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013657 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013658 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013659 app.hiddenAdj = hiddenAdj;
13660
13661 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013662 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013663 }
13664
Dianne Hackborn287952c2010-09-22 22:34:31 -070013665 final boolean wasKeeping = app.keeping;
13666
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013667 boolean success = true;
13668
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013669 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013670
Jeff Brown10e89712011-07-08 18:52:57 -070013671 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013672 if (false) {
13673 // Removing for now. Forcing GCs is not so useful anymore
13674 // with Dalvik, and the new memory level hint facility is
13675 // better for what we need to do these days.
13676 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13677 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13678 // If this app is transitioning from foreground to
13679 // non-foreground, have it do a gc.
13680 scheduleAppGcLocked(app);
13681 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13682 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13683 // Likewise do a gc when an app is moving in to the
13684 // background (such as a service stopping).
13685 scheduleAppGcLocked(app);
13686 }
Jeff Brown10e89712011-07-08 18:52:57 -070013687 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013688
Jeff Brown10e89712011-07-08 18:52:57 -070013689 if (wasKeeping && !app.keeping) {
13690 // This app is no longer something we want to keep. Note
13691 // its current wake lock time to later know to kill it if
13692 // it is not behaving well.
13693 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13694 synchronized (stats) {
13695 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13696 app.pid, SystemClock.elapsedRealtime());
13697 }
13698 app.lastCpuTime = app.curCpuTime;
13699 }
13700
13701 app.setRawAdj = app.curRawAdj;
13702 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013703
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013704 if (app.curAdj != app.setAdj) {
13705 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013706 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13707 TAG, "Set " + app.pid + " " + app.processName +
13708 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013709 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013710 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013711 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013712 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013713 }
13714 }
13715 if (app.setSchedGroup != app.curSchedGroup) {
13716 app.setSchedGroup = app.curSchedGroup;
13717 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13718 "Setting process group of " + app.processName
13719 + " to " + app.curSchedGroup);
13720 if (app.waitingToKill != null &&
13721 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13722 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13723 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13724 app.processName, app.setAdj, app.waitingToKill);
13725 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013726 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013727 } else {
13728 if (true) {
13729 long oldId = Binder.clearCallingIdentity();
13730 try {
13731 Process.setProcessGroup(app.pid, app.curSchedGroup);
13732 } catch (Exception e) {
13733 Slog.w(TAG, "Failed setting process group of " + app.pid
13734 + " to " + app.curSchedGroup);
13735 e.printStackTrace();
13736 } finally {
13737 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013738 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013739 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013740 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013741 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013742 app.thread.setSchedulingGroup(app.curSchedGroup);
13743 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013744 }
13745 }
13746 }
13747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013748 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013749 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013750 }
13751
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013752 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013753 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013754 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013755 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013756 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013757 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013758 }
13759 }
13760 return resumedActivity;
13761 }
13762
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013763 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013764 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013765 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13766 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013767 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13768 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013769
13770 mAdjSeq++;
13771
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013772 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013773 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13774 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013775 if (nowHidden != wasHidden) {
13776 // Changed to/from hidden state, so apps after it in the LRU
13777 // list may also be changed.
13778 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013779 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013780 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013781 }
13782
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013783 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013784 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013785 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13786
13787 if (false) {
13788 RuntimeException e = new RuntimeException();
13789 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013790 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013791 }
13792
13793 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013794 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013795
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013796 // Let's determine how many processes we have running vs.
13797 // how many slots we have for background processes; we may want
13798 // to put multiple processes in a slot of there are enough of
13799 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013800 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013801 int factor = (mLruProcesses.size()-4)/numSlots;
13802 if (factor < 1) factor = 1;
13803 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013804 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013805
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013806 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013807 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013808 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013809 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013810 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013811 while (i > 0) {
13812 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013813 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013814 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013815 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
13816 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013817 && app.curAdj == curHiddenAdj) {
13818 step++;
13819 if (step >= factor) {
13820 step = 0;
13821 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013822 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013823 }
13824 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013825 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013826 numHidden++;
13827 if (numHidden > mProcessLimit) {
13828 Slog.i(TAG, "No longer want " + app.processName
13829 + " (pid " + app.pid + "): hidden #" + numHidden);
13830 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13831 app.processName, app.setAdj, "too many background");
13832 app.killedBackground = true;
13833 Process.killProcessQuiet(app.pid);
13834 } else {
13835 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013836 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013837 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013838 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013840 }
13841 }
13842
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013843 mNumServiceProcs = mNewNumServiceProcs;
13844
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013845 // Now determine the memory trimming level of background processes.
13846 // Unfortunately we need to start at the back of the list to do this
13847 // properly. We only do this if the number of background apps we
13848 // are managing to keep around is less than half the maximum we desire;
13849 // if we are keeping a good number around, we'll let them use whatever
13850 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013851 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013852 final int N = mLruProcesses.size();
13853 factor = numBg/3;
13854 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013855 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013856 for (i=0; i<N; i++) {
13857 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013858 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013859 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13860 try {
13861 app.thread.scheduleTrimMemory(curLevel);
13862 } catch (RemoteException e) {
13863 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013864 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013865 // For these apps we will also finish their activities
13866 // to help them free memory.
13867 mMainStack.destroyActivitiesLocked(app, false);
13868 }
13869 }
13870 app.trimMemoryLevel = curLevel;
13871 step++;
13872 if (step >= factor) {
13873 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013874 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13875 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013876 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013877 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13878 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013879 break;
13880 }
13881 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013882 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013883 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013884 && app.thread != null) {
13885 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013886 app.thread.scheduleTrimMemory(
13887 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013888 } catch (RemoteException e) {
13889 }
13890 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013891 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013892 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013893 && app.pendingUiClean) {
13894 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13895 && app.thread != null) {
13896 try {
13897 app.thread.scheduleTrimMemory(
13898 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13899 } catch (RemoteException e) {
13900 }
13901 }
13902 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13903 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013904 } else {
13905 app.trimMemoryLevel = 0;
13906 }
13907 }
13908 } else {
13909 final int N = mLruProcesses.size();
13910 for (i=0; i<N; i++) {
13911 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013912 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013913 && app.pendingUiClean) {
13914 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13915 && app.thread != null) {
13916 try {
13917 app.thread.scheduleTrimMemory(
13918 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13919 } catch (RemoteException e) {
13920 }
13921 }
13922 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13923 app.pendingUiClean = false;
13924 } else {
13925 app.trimMemoryLevel = 0;
13926 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013927 }
13928 }
13929
13930 if (mAlwaysFinishActivities) {
13931 mMainStack.destroyActivitiesLocked(null, false);
13932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013933 }
13934
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013935 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013936 synchronized (this) {
13937 int i;
13938
13939 // First remove any unused application processes whose package
13940 // has been removed.
13941 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13942 final ProcessRecord app = mRemovedProcesses.get(i);
13943 if (app.activities.size() == 0
13944 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013945 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013946 TAG, "Exiting empty application process "
13947 + app.processName + " ("
13948 + (app.thread != null ? app.thread.asBinder() : null)
13949 + ")\n");
13950 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013951 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13952 app.processName, app.setAdj, "empty");
13953 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013954 } else {
13955 try {
13956 app.thread.scheduleExit();
13957 } catch (Exception e) {
13958 // Ignore exceptions.
13959 }
13960 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013961 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013962 mRemovedProcesses.remove(i);
13963
13964 if (app.persistent) {
13965 if (app.persistent) {
13966 addAppLocked(app.info);
13967 }
13968 }
13969 }
13970 }
13971
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013972 // Now update the oom adj for all processes.
13973 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013974 }
13975 }
13976
13977 /** This method sends the specified signal to each of the persistent apps */
13978 public void signalPersistentProcesses(int sig) throws RemoteException {
13979 if (sig != Process.SIGNAL_USR1) {
13980 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13981 }
13982
13983 synchronized (this) {
13984 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13985 != PackageManager.PERMISSION_GRANTED) {
13986 throw new SecurityException("Requires permission "
13987 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13988 }
13989
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013990 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13991 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013992 if (r.thread != null && r.persistent) {
13993 Process.sendSignal(r.pid, sig);
13994 }
13995 }
13996 }
13997 }
13998
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013999 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14000 if (proc == null || proc == mProfileProc) {
14001 proc = mProfileProc;
14002 path = mProfileFile;
14003 profileType = mProfileType;
14004 clearProfilerLocked();
14005 }
14006 if (proc == null) {
14007 return;
14008 }
14009 try {
14010 proc.thread.profilerControl(false, path, null, profileType);
14011 } catch (RemoteException e) {
14012 throw new IllegalStateException("Process disappeared");
14013 }
14014 }
14015
14016 private void clearProfilerLocked() {
14017 if (mProfileFd != null) {
14018 try {
14019 mProfileFd.close();
14020 } catch (IOException e) {
14021 }
14022 }
14023 mProfileApp = null;
14024 mProfileProc = null;
14025 mProfileFile = null;
14026 mProfileType = 0;
14027 mAutoStopProfiler = false;
14028 }
14029
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014030 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014031 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014032
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014033 try {
14034 synchronized (this) {
14035 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14036 // its own permission.
14037 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14038 != PackageManager.PERMISSION_GRANTED) {
14039 throw new SecurityException("Requires permission "
14040 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014041 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014042
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014043 if (start && fd == null) {
14044 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014045 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014046
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014047 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014048 if (process != null) {
14049 try {
14050 int pid = Integer.parseInt(process);
14051 synchronized (mPidsSelfLocked) {
14052 proc = mPidsSelfLocked.get(pid);
14053 }
14054 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014055 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014056
14057 if (proc == null) {
14058 HashMap<String, SparseArray<ProcessRecord>> all
14059 = mProcessNames.getMap();
14060 SparseArray<ProcessRecord> procs = all.get(process);
14061 if (procs != null && procs.size() > 0) {
14062 proc = procs.valueAt(0);
14063 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014064 }
14065 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014066
14067 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014068 throw new IllegalArgumentException("Unknown process: " + process);
14069 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014070
14071 if (start) {
14072 stopProfilerLocked(null, null, 0);
14073 setProfileApp(proc.info, proc.processName, path, fd, false);
14074 mProfileProc = proc;
14075 mProfileType = profileType;
14076 try {
14077 fd = fd.dup();
14078 } catch (IOException e) {
14079 fd = null;
14080 }
14081 proc.thread.profilerControl(start, path, fd, profileType);
14082 fd = null;
14083 mProfileFd = null;
14084 } else {
14085 stopProfilerLocked(proc, path, profileType);
14086 if (fd != null) {
14087 try {
14088 fd.close();
14089 } catch (IOException e) {
14090 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014091 }
14092 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014093
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014094 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014095 }
14096 } catch (RemoteException e) {
14097 throw new IllegalStateException("Process disappeared");
14098 } finally {
14099 if (fd != null) {
14100 try {
14101 fd.close();
14102 } catch (IOException e) {
14103 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014104 }
14105 }
14106 }
Andy McFadden824c5102010-07-09 16:26:57 -070014107
14108 public boolean dumpHeap(String process, boolean managed,
14109 String path, ParcelFileDescriptor fd) throws RemoteException {
14110
14111 try {
14112 synchronized (this) {
14113 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14114 // its own permission (same as profileControl).
14115 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14116 != PackageManager.PERMISSION_GRANTED) {
14117 throw new SecurityException("Requires permission "
14118 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14119 }
14120
14121 if (fd == null) {
14122 throw new IllegalArgumentException("null fd");
14123 }
14124
14125 ProcessRecord proc = null;
14126 try {
14127 int pid = Integer.parseInt(process);
14128 synchronized (mPidsSelfLocked) {
14129 proc = mPidsSelfLocked.get(pid);
14130 }
14131 } catch (NumberFormatException e) {
14132 }
14133
14134 if (proc == null) {
14135 HashMap<String, SparseArray<ProcessRecord>> all
14136 = mProcessNames.getMap();
14137 SparseArray<ProcessRecord> procs = all.get(process);
14138 if (procs != null && procs.size() > 0) {
14139 proc = procs.valueAt(0);
14140 }
14141 }
14142
14143 if (proc == null || proc.thread == null) {
14144 throw new IllegalArgumentException("Unknown process: " + process);
14145 }
14146
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014147 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14148 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014149 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14150 throw new SecurityException("Process not debuggable: " + proc);
14151 }
14152 }
14153
14154 proc.thread.dumpHeap(managed, path, fd);
14155 fd = null;
14156 return true;
14157 }
14158 } catch (RemoteException e) {
14159 throw new IllegalStateException("Process disappeared");
14160 } finally {
14161 if (fd != null) {
14162 try {
14163 fd.close();
14164 } catch (IOException e) {
14165 }
14166 }
14167 }
14168 }
14169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014170 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14171 public void monitor() {
14172 synchronized (this) { }
14173 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014174
14175 public void onCoreSettingsChange(Bundle settings) {
14176 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14177 ProcessRecord processRecord = mLruProcesses.get(i);
14178 try {
14179 if (processRecord.thread != null) {
14180 processRecord.thread.setCoreSettings(settings);
14181 }
14182 } catch (RemoteException re) {
14183 /* ignore */
14184 }
14185 }
14186 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014187
14188 // Multi-user methods
14189
14190 public boolean switchUser(int userid) {
14191 // TODO
14192 return true;
14193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014194}