blob: 310ace0764a66fc2e97f485f871c263ffca98dba [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 Hackbornf35fe232011-11-01 19:25:20 -0700411 * This is the process holding the activity the user last visited that
412 * is in a different process from the one they are currently in.
413 */
414 ProcessRecord mPreviousProcess;
415
416 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400417 * Packages that the user has asked to have run in screen size
418 * compatibility mode instead of filling the screen.
419 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700420 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400421
422 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 * Set of PendingResultRecord objects that are currently active.
424 */
425 final HashSet mPendingResultRecords = new HashSet();
426
427 /**
428 * Set of IntentSenderRecord objects that are currently active.
429 */
430 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
431 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
432
433 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800434 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700435 * already logged DropBox entries for. Guarded by itself. If
436 * something (rogue user app) forces this over
437 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
438 */
439 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
440 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
441
442 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700443 * Strict Mode background batched logging state.
444 *
445 * The string buffer is guarded by itself, and its lock is also
446 * used to determine if another batched write is already
447 * in-flight.
448 */
449 private final StringBuilder mStrictModeBuffer = new StringBuilder();
450
451 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700452 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
453 */
454 private boolean mPendingBroadcastTimeoutMessage;
455
456 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 * Intent broadcast that we have tried to start, but are
458 * waiting for its application's process to be created. We only
459 * need one (instead of a list) because we always process broadcasts
460 * one at a time, so no others can be started while waiting for this
461 * one.
462 */
463 BroadcastRecord mPendingBroadcast = null;
464
465 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700466 * The receiver index that is pending, to restart the broadcast if needed.
467 */
468 int mPendingBroadcastRecvIndex;
469
470 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 * Keeps track of all IIntentReceivers that have been registered for
472 * broadcasts. Hash keys are the receiver IBinder, hash value is
473 * a ReceiverList.
474 */
475 final HashMap mRegisteredReceivers = new HashMap();
476
477 /**
478 * Resolver for broadcast intents to registered receivers.
479 * Holds BroadcastFilter (subclass of IntentFilter).
480 */
481 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
482 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
483 @Override
484 protected boolean allowFilterResult(
485 BroadcastFilter filter, List<BroadcastFilter> dest) {
486 IBinder target = filter.receiverList.receiver.asBinder();
487 for (int i=dest.size()-1; i>=0; i--) {
488 if (dest.get(i).receiverList.receiver.asBinder() == target) {
489 return false;
490 }
491 }
492 return true;
493 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700494
495 @Override
496 protected String packageForFilter(BroadcastFilter filter) {
497 return filter.packageName;
498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 };
500
501 /**
502 * State of all active sticky broadcasts. Keys are the action of the
503 * sticky Intent, values are an ArrayList of all broadcasted intents with
504 * that action (which should usually be one).
505 */
506 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
507 new HashMap<String, ArrayList<Intent>>();
508
509 /**
510 * All currently running services.
511 */
512 final HashMap<ComponentName, ServiceRecord> mServices =
513 new HashMap<ComponentName, ServiceRecord>();
514
515 /**
516 * All currently running services indexed by the Intent used to start them.
517 */
518 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
519 new HashMap<Intent.FilterComparison, ServiceRecord>();
520
521 /**
522 * All currently bound service connections. Keys are the IBinder of
523 * the client's IServiceConnection.
524 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700525 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
526 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527
528 /**
529 * List of services that we have been asked to start,
530 * but haven't yet been able to. It is used to hold start requests
531 * while waiting for their corresponding application thread to get
532 * going.
533 */
534 final ArrayList<ServiceRecord> mPendingServices
535 = new ArrayList<ServiceRecord>();
536
537 /**
538 * List of services that are scheduled to restart following a crash.
539 */
540 final ArrayList<ServiceRecord> mRestartingServices
541 = new ArrayList<ServiceRecord>();
542
543 /**
544 * List of services that are in the process of being stopped.
545 */
546 final ArrayList<ServiceRecord> mStoppingServices
547 = new ArrayList<ServiceRecord>();
548
549 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700550 * Backup/restore process management
551 */
552 String mBackupAppName = null;
553 BackupRecord mBackupTarget = null;
554
555 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 * List of PendingThumbnailsRecord objects of clients who are still
557 * waiting to receive all of the thumbnails for a task.
558 */
559 final ArrayList mPendingThumbnails = new ArrayList();
560
561 /**
562 * List of HistoryRecord objects that have been finished and must
563 * still report back to a pending thumbnail receiver.
564 */
565 final ArrayList mCancelledThumbnails = new ArrayList();
566
567 /**
568 * All of the currently running global content providers. Keys are a
569 * string containing the provider name and values are a
570 * ContentProviderRecord object containing the data about it. Note
571 * that a single provider may be published under multiple names, so
572 * there may be multiple entries here for a single one in mProvidersByClass.
573 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700574 final HashMap<String, ContentProviderRecord> mProvidersByName
575 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576
577 /**
578 * All of the currently running global content providers. Keys are a
579 * string containing the provider's implementation class and values are a
580 * ContentProviderRecord object containing the data about it.
581 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700582 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
583 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584
585 /**
586 * List of content providers who have clients waiting for them. The
587 * application is currently being launched and the provider will be
588 * removed from this list once it is published.
589 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700590 final ArrayList<ContentProviderRecord> mLaunchingProviders
591 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592
593 /**
594 * Global set of specific Uri permissions that have been granted.
595 */
596 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
597 = new SparseArray<HashMap<Uri, UriPermission>>();
598
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800599 CoreSettingsObserver mCoreSettingsObserver;
600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 /**
602 * Thread-local storage used to carry caller permissions over through
603 * indirect content-provider access.
604 * @see #ActivityManagerService.openContentUri()
605 */
606 private class Identity {
607 public int pid;
608 public int uid;
609
610 Identity(int _pid, int _uid) {
611 pid = _pid;
612 uid = _uid;
613 }
614 }
615 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
616
617 /**
618 * All information we have collected about the runtime performance of
619 * any user id that can impact battery performance.
620 */
621 final BatteryStatsService mBatteryStatsService;
622
623 /**
624 * information about component usage
625 */
626 final UsageStatsService mUsageStatsService;
627
628 /**
629 * Current configuration information. HistoryRecord objects are given
630 * a reference to this object to indicate which configuration they are
631 * currently running in, so this object must be kept immutable.
632 */
633 Configuration mConfiguration = new Configuration();
634
635 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800636 * Current sequencing integer of the configuration, for skipping old
637 * configurations.
638 */
639 int mConfigurationSeq = 0;
640
641 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700642 * Hardware-reported OpenGLES version.
643 */
644 final int GL_ES_VERSION;
645
646 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 * List of initialization arguments to pass to all processes when binding applications to them.
648 * For example, references to the commonly used services.
649 */
650 HashMap<String, IBinder> mAppBindArgs;
651
652 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700653 * Temporary to avoid allocations. Protected by main lock.
654 */
655 final StringBuilder mStringBuilder = new StringBuilder(256);
656
657 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 * Used to control how we initialize the service.
659 */
660 boolean mStartRunning = false;
661 ComponentName mTopComponent;
662 String mTopAction;
663 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700664 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 boolean mSystemReady = false;
666 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700667 boolean mWaitingUpdate = false;
668 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700669 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700670 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671
672 Context mContext;
673
674 int mFactoryTest;
675
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700676 boolean mCheckedForSetup;
677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700679 * The time at which we will allow normal application switches again,
680 * after a call to {@link #stopAppSwitches()}.
681 */
682 long mAppSwitchesAllowedTime;
683
684 /**
685 * This is set to true after the first switch after mAppSwitchesAllowedTime
686 * is set; any switches after that will clear the time.
687 */
688 boolean mDidAppSwitch;
689
690 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700691 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700692 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700693 long mLastPowerCheckRealtime;
694
695 /**
696 * Last time (in uptime) at which we checked for power usage.
697 */
698 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700699
700 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 * Set while we are wanting to sleep, to prevent any
702 * activities from being started/resumed.
703 */
704 boolean mSleeping = false;
705
706 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700707 * Set if we are shutting down the system, similar to sleeping.
708 */
709 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710
711 /**
712 * Task identifier that activities are currently being started
713 * in. Incremented each time a new task is created.
714 * todo: Replace this with a TokenSpace class that generates non-repeating
715 * integers that won't wrap.
716 */
717 int mCurTask = 1;
718
719 /**
720 * Current sequence id for oom_adj computation traversal.
721 */
722 int mAdjSeq = 0;
723
724 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700725 * Current sequence id for process LRU updating.
726 */
727 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728
729 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700730 * Keep track of the number of service processes we last found, to
731 * determine on the next iteration which should be B services.
732 */
733 int mNumServiceProcs = 0;
734 int mNewNumServiceProcs = 0;
735
736 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 * System monitoring: number of processes that died since the last
738 * N procs were started.
739 */
740 int[] mProcDeaths = new int[20];
741
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700742 /**
743 * This is set if we had to do a delayed dexopt of an app before launching
744 * it, to increasing the ANR timeouts in that case.
745 */
746 boolean mDidDexOpt;
747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 String mDebugApp = null;
749 boolean mWaitForDebugger = false;
750 boolean mDebugTransient = false;
751 String mOrigDebugApp = null;
752 boolean mOrigWaitForDebugger = false;
753 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700754 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700755 String mProfileApp = null;
756 ProcessRecord mProfileProc = null;
757 String mProfileFile;
758 ParcelFileDescriptor mProfileFd;
759 int mProfileType = 0;
760 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700762 final RemoteCallbackList<IActivityWatcher> mWatchers
763 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700764
765 final RemoteCallbackList<IProcessObserver> mProcessObservers
766 = new RemoteCallbackList<IProcessObserver>();
767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 /**
769 * Callback of last caller to {@link #requestPss}.
770 */
771 Runnable mRequestPssCallback;
772
773 /**
774 * Remaining processes for which we are waiting results from the last
775 * call to {@link #requestPss}.
776 */
777 final ArrayList<ProcessRecord> mRequestPssList
778 = new ArrayList<ProcessRecord>();
779
780 /**
781 * Runtime statistics collection thread. This object's lock is used to
782 * protect all related state.
783 */
784 final Thread mProcessStatsThread;
785
786 /**
787 * Used to collect process stats when showing not responding dialog.
788 * Protected by mProcessStatsThread.
789 */
790 final ProcessStats mProcessStats = new ProcessStats(
791 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700792 final AtomicLong mLastCpuTime = new AtomicLong(0);
793 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 long mLastWriteTime = 0;
796
797 /**
798 * Set to true after the system has finished booting.
799 */
800 boolean mBooted = false;
801
Dianne Hackborn7d608422011-08-07 16:24:18 -0700802 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700803 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804
805 WindowManagerService mWindowManager;
806
807 static ActivityManagerService mSelf;
808 static ActivityThread mSystemThread;
809
810 private final class AppDeathRecipient implements IBinder.DeathRecipient {
811 final ProcessRecord mApp;
812 final int mPid;
813 final IApplicationThread mAppThread;
814
815 AppDeathRecipient(ProcessRecord app, int pid,
816 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800817 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818 TAG, "New death recipient " + this
819 + " for thread " + thread.asBinder());
820 mApp = app;
821 mPid = pid;
822 mAppThread = thread;
823 }
824
825 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800826 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 TAG, "Death received in " + this
828 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 synchronized(ActivityManagerService.this) {
830 appDiedLocked(mApp, mPid, mAppThread);
831 }
832 }
833 }
834
835 static final int SHOW_ERROR_MSG = 1;
836 static final int SHOW_NOT_RESPONDING_MSG = 2;
837 static final int SHOW_FACTORY_ERROR_MSG = 3;
838 static final int UPDATE_CONFIGURATION_MSG = 4;
839 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
840 static final int WAIT_FOR_DEBUGGER_MSG = 6;
841 static final int BROADCAST_INTENT_MSG = 7;
842 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 static final int SERVICE_TIMEOUT_MSG = 12;
844 static final int UPDATE_TIME_ZONE = 13;
845 static final int SHOW_UID_ERROR_MSG = 14;
846 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700848 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700849 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800850 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700851 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
852 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700853 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700854 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700855 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700856 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700857 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700858 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
859 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860
861 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700862 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863
864 final Handler mHandler = new Handler() {
865 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800866 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 //}
868
869 public void handleMessage(Message msg) {
870 switch (msg.what) {
871 case SHOW_ERROR_MSG: {
872 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 synchronized (ActivityManagerService.this) {
874 ProcessRecord proc = (ProcessRecord)data.get("app");
875 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800876 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 return;
878 }
879 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700880 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800881 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 d.show();
883 proc.crashDialog = d;
884 } else {
885 // The device is asleep, so just pretend that the user
886 // saw a crash dialog and hit "force quit".
887 res.set(0);
888 }
889 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700890
891 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 } break;
893 case SHOW_NOT_RESPONDING_MSG: {
894 synchronized (ActivityManagerService.this) {
895 HashMap data = (HashMap) msg.obj;
896 ProcessRecord proc = (ProcessRecord)data.get("app");
897 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800898 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 return;
900 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800901
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700902 Intent intent = new Intent("android.intent.action.ANR");
903 if (!mProcessesReady) {
904 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
905 }
906 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800907 null, null, 0, null, null, null,
908 false, false, MY_PID, Process.SYSTEM_UID);
909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700911 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 d.show();
913 proc.anrDialog = d;
914 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700915
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700916 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700918 case SHOW_STRICT_MODE_VIOLATION_MSG: {
919 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
920 synchronized (ActivityManagerService.this) {
921 ProcessRecord proc = (ProcessRecord) data.get("app");
922 if (proc == null) {
923 Slog.e(TAG, "App not found when showing strict mode dialog.");
924 break;
925 }
926 if (proc.crashDialog != null) {
927 Slog.e(TAG, "App already has strict mode dialog: " + proc);
928 return;
929 }
930 AppErrorResult res = (AppErrorResult) data.get("result");
931 if (!mSleeping && !mShuttingDown) {
932 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
933 d.show();
934 proc.crashDialog = d;
935 } else {
936 // The device is asleep, so just pretend that the user
937 // saw a crash dialog and hit "force quit".
938 res.set(0);
939 }
940 }
941 ensureBootCompleted();
942 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 case SHOW_FACTORY_ERROR_MSG: {
944 Dialog d = new FactoryErrorDialog(
945 mContext, msg.getData().getCharSequence("msg"));
946 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700947 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 } break;
949 case UPDATE_CONFIGURATION_MSG: {
950 final ContentResolver resolver = mContext.getContentResolver();
951 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
952 } break;
953 case GC_BACKGROUND_PROCESSES_MSG: {
954 synchronized (ActivityManagerService.this) {
955 performAppGcsIfAppropriateLocked();
956 }
957 } break;
958 case WAIT_FOR_DEBUGGER_MSG: {
959 synchronized (ActivityManagerService.this) {
960 ProcessRecord app = (ProcessRecord)msg.obj;
961 if (msg.arg1 != 0) {
962 if (!app.waitedForDebugger) {
963 Dialog d = new AppWaitingForDebuggerDialog(
964 ActivityManagerService.this,
965 mContext, app);
966 app.waitDialog = d;
967 app.waitedForDebugger = true;
968 d.show();
969 }
970 } else {
971 if (app.waitDialog != null) {
972 app.waitDialog.dismiss();
973 app.waitDialog = null;
974 }
975 }
976 }
977 } break;
978 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800979 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 TAG, "Received BROADCAST_INTENT_MSG");
981 processNextBroadcast(true);
982 } break;
983 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700984 synchronized (ActivityManagerService.this) {
985 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700989 if (mDidDexOpt) {
990 mDidDexOpt = false;
991 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
992 nmsg.obj = msg.obj;
993 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
994 return;
995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 serviceTimeout((ProcessRecord)msg.obj);
997 } break;
998 case UPDATE_TIME_ZONE: {
999 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001000 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1001 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 if (r.thread != null) {
1003 try {
1004 r.thread.updateTimeZone();
1005 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001006 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 }
1008 }
1009 }
1010 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001011 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001012 case CLEAR_DNS_CACHE: {
1013 synchronized (ActivityManagerService.this) {
1014 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1015 ProcessRecord r = mLruProcesses.get(i);
1016 if (r.thread != null) {
1017 try {
1018 r.thread.clearDnsCache();
1019 } catch (RemoteException ex) {
1020 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1021 }
1022 }
1023 }
1024 }
1025 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001026 case UPDATE_HTTP_PROXY: {
1027 ProxyProperties proxy = (ProxyProperties)msg.obj;
1028 String host = "";
1029 String port = "";
1030 String exclList = "";
1031 if (proxy != null) {
1032 host = proxy.getHost();
1033 port = Integer.toString(proxy.getPort());
1034 exclList = proxy.getExclusionList();
1035 }
1036 synchronized (ActivityManagerService.this) {
1037 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1038 ProcessRecord r = mLruProcesses.get(i);
1039 if (r.thread != null) {
1040 try {
1041 r.thread.setHttpProxy(host, port, exclList);
1042 } catch (RemoteException ex) {
1043 Slog.w(TAG, "Failed to update http proxy for: " +
1044 r.info.processName);
1045 }
1046 }
1047 }
1048 }
1049 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 case SHOW_UID_ERROR_MSG: {
1051 // XXX This is a temporary dialog, no need to localize.
1052 AlertDialog d = new BaseErrorDialog(mContext);
1053 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1054 d.setCancelable(false);
1055 d.setTitle("System UIDs Inconsistent");
1056 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 +02001057 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1059 mUidAlert = d;
1060 d.show();
1061 } break;
1062 case IM_FEELING_LUCKY_MSG: {
1063 if (mUidAlert != null) {
1064 mUidAlert.dismiss();
1065 mUidAlert = null;
1066 }
1067 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001068 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001069 if (mDidDexOpt) {
1070 mDidDexOpt = false;
1071 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1072 nmsg.obj = msg.obj;
1073 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1074 return;
1075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001076 ProcessRecord app = (ProcessRecord)msg.obj;
1077 synchronized (ActivityManagerService.this) {
1078 processStartTimedOutLocked(app);
1079 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001080 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001081 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1082 synchronized (ActivityManagerService.this) {
1083 doPendingActivityLaunchesLocked(true);
1084 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001085 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001086 case KILL_APPLICATION_MSG: {
1087 synchronized (ActivityManagerService.this) {
1088 int uid = msg.arg1;
1089 boolean restart = (msg.arg2 == 1);
1090 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001091 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001092 }
1093 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001094 case FINALIZE_PENDING_INTENT_MSG: {
1095 ((PendingIntentRecord)msg.obj).completeFinalize();
1096 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001097 case POST_HEAVY_NOTIFICATION_MSG: {
1098 INotificationManager inm = NotificationManager.getService();
1099 if (inm == null) {
1100 return;
1101 }
1102
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001103 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001104 ProcessRecord process = root.app;
1105 if (process == null) {
1106 return;
1107 }
1108
1109 try {
1110 Context context = mContext.createPackageContext(process.info.packageName, 0);
1111 String text = mContext.getString(R.string.heavy_weight_notification,
1112 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1113 Notification notification = new Notification();
1114 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1115 notification.when = 0;
1116 notification.flags = Notification.FLAG_ONGOING_EVENT;
1117 notification.tickerText = text;
1118 notification.defaults = 0; // please be quiet
1119 notification.sound = null;
1120 notification.vibrate = null;
1121 notification.setLatestEventInfo(context, text,
1122 mContext.getText(R.string.heavy_weight_notification_detail),
1123 PendingIntent.getActivity(mContext, 0, root.intent,
1124 PendingIntent.FLAG_CANCEL_CURRENT));
1125
1126 try {
1127 int[] outId = new int[1];
1128 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1129 notification, outId);
1130 } catch (RuntimeException e) {
1131 Slog.w(ActivityManagerService.TAG,
1132 "Error showing notification for heavy-weight app", e);
1133 } catch (RemoteException e) {
1134 }
1135 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001136 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001137 }
1138 } break;
1139 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1140 INotificationManager inm = NotificationManager.getService();
1141 if (inm == null) {
1142 return;
1143 }
1144 try {
1145 inm.cancelNotification("android",
1146 R.string.heavy_weight_notification);
1147 } catch (RuntimeException e) {
1148 Slog.w(ActivityManagerService.TAG,
1149 "Error canceling notification for service", e);
1150 } catch (RemoteException e) {
1151 }
1152 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001153 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1154 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001155 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001156 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001157 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1158 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001159 }
1160 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001161 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1162 synchronized (ActivityManagerService.this) {
1163 ActivityRecord ar = (ActivityRecord)msg.obj;
1164 if (mCompatModeDialog != null) {
1165 if (mCompatModeDialog.mAppInfo.packageName.equals(
1166 ar.info.applicationInfo.packageName)) {
1167 return;
1168 }
1169 mCompatModeDialog.dismiss();
1170 mCompatModeDialog = null;
1171 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001172 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001173 if (mCompatModePackages.getPackageAskCompatModeLocked(
1174 ar.packageName)) {
1175 int mode = mCompatModePackages.computeCompatModeLocked(
1176 ar.info.applicationInfo);
1177 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1178 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1179 mCompatModeDialog = new CompatModeDialog(
1180 ActivityManagerService.this, mContext,
1181 ar.info.applicationInfo);
1182 mCompatModeDialog.show();
1183 }
1184 }
1185 }
1186 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001187 break;
1188 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001189 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001190 final int pid = msg.arg1;
1191 final int uid = msg.arg2;
1192 final boolean foregroundActivities = (Boolean) msg.obj;
1193 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001194 break;
1195 }
1196 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001197 final int pid = msg.arg1;
1198 final int uid = msg.arg2;
1199 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001200 break;
1201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 }
1203 }
1204 };
1205
1206 public static void setSystemProcess() {
1207 try {
1208 ActivityManagerService m = mSelf;
1209
1210 ServiceManager.addService("activity", m);
1211 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001212 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 if (MONITOR_CPU_USAGE) {
1214 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 ServiceManager.addService("permission", new PermissionController(m));
1217
1218 ApplicationInfo info =
1219 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001220 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001221 mSystemThread.installSystemApplicationInfo(info);
1222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 synchronized (mSelf) {
1224 ProcessRecord app = mSelf.newProcessRecordLocked(
1225 mSystemThread.getApplicationThread(), info,
1226 info.processName);
1227 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001228 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001229 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1231 synchronized (mSelf.mPidsSelfLocked) {
1232 mSelf.mPidsSelfLocked.put(app.pid, app);
1233 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001234 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 }
1236 } catch (PackageManager.NameNotFoundException e) {
1237 throw new RuntimeException(
1238 "Unable to find android system package", e);
1239 }
1240 }
1241
1242 public void setWindowManager(WindowManagerService wm) {
1243 mWindowManager = wm;
1244 }
1245
1246 public static final Context main(int factoryTest) {
1247 AThread thr = new AThread();
1248 thr.start();
1249
1250 synchronized (thr) {
1251 while (thr.mService == null) {
1252 try {
1253 thr.wait();
1254 } catch (InterruptedException e) {
1255 }
1256 }
1257 }
1258
1259 ActivityManagerService m = thr.mService;
1260 mSelf = m;
1261 ActivityThread at = ActivityThread.systemMain();
1262 mSystemThread = at;
1263 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001264 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 m.mContext = context;
1266 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001267 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268
1269 m.mBatteryStatsService.publish(context);
1270 m.mUsageStatsService.publish(context);
1271
1272 synchronized (thr) {
1273 thr.mReady = true;
1274 thr.notifyAll();
1275 }
1276
1277 m.startRunning(null, null, null, null);
1278
1279 return context;
1280 }
1281
1282 public static ActivityManagerService self() {
1283 return mSelf;
1284 }
1285
1286 static class AThread extends Thread {
1287 ActivityManagerService mService;
1288 boolean mReady = false;
1289
1290 public AThread() {
1291 super("ActivityManager");
1292 }
1293
1294 public void run() {
1295 Looper.prepare();
1296
1297 android.os.Process.setThreadPriority(
1298 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001299 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300
1301 ActivityManagerService m = new ActivityManagerService();
1302
1303 synchronized (this) {
1304 mService = m;
1305 notifyAll();
1306 }
1307
1308 synchronized (this) {
1309 while (!mReady) {
1310 try {
1311 wait();
1312 } catch (InterruptedException e) {
1313 }
1314 }
1315 }
1316
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001317 // For debug builds, log event loop stalls to dropbox for analysis.
1318 if (StrictMode.conditionallyEnableDebugLogging()) {
1319 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1320 }
1321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 Looper.loop();
1323 }
1324 }
1325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 static class MemBinder extends Binder {
1327 ActivityManagerService mActivityManagerService;
1328 MemBinder(ActivityManagerService activityManagerService) {
1329 mActivityManagerService = activityManagerService;
1330 }
1331
1332 @Override
1333 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001334 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1335 != PackageManager.PERMISSION_GRANTED) {
1336 pw.println("Permission Denial: can't dump meminfo from from pid="
1337 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1338 + " without permission " + android.Manifest.permission.DUMP);
1339 return;
1340 }
1341
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001342 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 }
1344 }
1345
Chet Haase9c1e23b2011-03-24 10:51:31 -07001346 static class GraphicsBinder extends Binder {
1347 ActivityManagerService mActivityManagerService;
1348 GraphicsBinder(ActivityManagerService activityManagerService) {
1349 mActivityManagerService = activityManagerService;
1350 }
1351
1352 @Override
1353 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001354 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1355 != PackageManager.PERMISSION_GRANTED) {
1356 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1357 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1358 + " without permission " + android.Manifest.permission.DUMP);
1359 return;
1360 }
1361
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001362 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001363 }
1364 }
1365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 static class CpuBinder extends Binder {
1367 ActivityManagerService mActivityManagerService;
1368 CpuBinder(ActivityManagerService activityManagerService) {
1369 mActivityManagerService = activityManagerService;
1370 }
1371
1372 @Override
1373 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001374 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1375 != PackageManager.PERMISSION_GRANTED) {
1376 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1377 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1378 + " without permission " + android.Manifest.permission.DUMP);
1379 return;
1380 }
1381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001383 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1384 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1385 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 }
1387 }
1388 }
1389
1390 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 File dataDir = Environment.getDataDirectory();
1394 File systemDir = new File(dataDir, "system");
1395 systemDir.mkdirs();
1396 mBatteryStatsService = new BatteryStatsService(new File(
1397 systemDir, "batterystats.bin").toString());
1398 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001399 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001400 mOnBattery = DEBUG_POWER ? true
1401 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001402 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001404 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001405 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406
Jack Palevichb90d28c2009-07-22 15:35:24 -07001407 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1408 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1409
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001410 mConfiguration.setToDefaults();
1411 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 mProcessStats.init();
1413
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001414 mCompatModePackages = new CompatModePackages(this, systemDir);
1415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 // Add ourself to the Watchdog monitors.
1417 Watchdog.getInstance().addMonitor(this);
1418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 mProcessStatsThread = new Thread("ProcessStats") {
1420 public void run() {
1421 while (true) {
1422 try {
1423 try {
1424 synchronized(this) {
1425 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001426 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001428 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 // + ", write delay=" + nextWriteDelay);
1430 if (nextWriteDelay < nextCpuDelay) {
1431 nextCpuDelay = nextWriteDelay;
1432 }
1433 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001434 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 this.wait(nextCpuDelay);
1436 }
1437 }
1438 } catch (InterruptedException e) {
1439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 updateCpuStatsNow();
1441 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001442 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 }
1444 }
1445 }
1446 };
1447 mProcessStatsThread.start();
1448 }
1449
1450 @Override
1451 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1452 throws RemoteException {
1453 try {
1454 return super.onTransact(code, data, reply, flags);
1455 } catch (RuntimeException e) {
1456 // The activity manager only throws security exceptions, so let's
1457 // log all others.
1458 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001459 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 }
1461 throw e;
1462 }
1463 }
1464
1465 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001466 final long now = SystemClock.uptimeMillis();
1467 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1468 return;
1469 }
1470 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1471 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 mProcessStatsThread.notify();
1473 }
1474 }
1475 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 void updateCpuStatsNow() {
1478 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001479 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 final long now = SystemClock.uptimeMillis();
1481 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001484 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1485 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 haveNewCpuStats = true;
1487 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001488 //Slog.i(TAG, mProcessStats.printCurrentState());
1489 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 // + mProcessStats.getTotalCpuPercent() + "%");
1491
Joe Onorato8a9b2202010-02-26 18:56:32 -08001492 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 if ("true".equals(SystemProperties.get("events.cpu"))) {
1494 int user = mProcessStats.getLastUserTime();
1495 int system = mProcessStats.getLastSystemTime();
1496 int iowait = mProcessStats.getLastIoWaitTime();
1497 int irq = mProcessStats.getLastIrqTime();
1498 int softIrq = mProcessStats.getLastSoftIrqTime();
1499 int idle = mProcessStats.getLastIdleTime();
1500
1501 int total = user + system + iowait + irq + softIrq + idle;
1502 if (total == 0) total = 1;
1503
Doug Zongker2bec3d42009-12-04 12:52:44 -08001504 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 ((user+system+iowait+irq+softIrq) * 100) / total,
1506 (user * 100) / total,
1507 (system * 100) / total,
1508 (iowait * 100) / total,
1509 (irq * 100) / total,
1510 (softIrq * 100) / total);
1511 }
1512 }
1513
Amith Yamasanie43530a2009-08-21 13:11:37 -07001514 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001515 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001516 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 synchronized(mPidsSelfLocked) {
1518 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001519 if (mOnBattery) {
1520 int perc = bstats.startAddingCpuLocked();
1521 int totalUTime = 0;
1522 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001523 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001525 ProcessStats.Stats st = mProcessStats.getStats(i);
1526 if (!st.working) {
1527 continue;
1528 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001530 int otherUTime = (st.rel_utime*perc)/100;
1531 int otherSTime = (st.rel_stime*perc)/100;
1532 totalUTime += otherUTime;
1533 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 if (pr != null) {
1535 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001536 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1537 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001538 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001539 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001540 } else {
1541 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001542 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001543 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001544 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1545 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001546 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 }
1549 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001550 bstats.finishAddingCpuLocked(perc, totalUTime,
1551 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 }
1553 }
1554 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1557 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001558 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 }
1560 }
1561 }
1562 }
1563
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001564 @Override
1565 public void batteryNeedsCpuUpdate() {
1566 updateCpuStatsNow();
1567 }
1568
1569 @Override
1570 public void batteryPowerChanged(boolean onBattery) {
1571 // When plugging in, update the CPU stats first before changing
1572 // the plug state.
1573 updateCpuStatsNow();
1574 synchronized (this) {
1575 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001576 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001577 }
1578 }
1579 }
1580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 /**
1582 * Initialize the application bind args. These are passed to each
1583 * process when the bindApplication() IPC is sent to the process. They're
1584 * lazily setup to make sure the services are running when they're asked for.
1585 */
1586 private HashMap<String, IBinder> getCommonServicesLocked() {
1587 if (mAppBindArgs == null) {
1588 mAppBindArgs = new HashMap<String, IBinder>();
1589
1590 // Setup the application init args
1591 mAppBindArgs.put("package", ServiceManager.getService("package"));
1592 mAppBindArgs.put("window", ServiceManager.getService("window"));
1593 mAppBindArgs.put(Context.ALARM_SERVICE,
1594 ServiceManager.getService(Context.ALARM_SERVICE));
1595 }
1596 return mAppBindArgs;
1597 }
1598
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001599 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 if (mFocusedActivity != r) {
1601 mFocusedActivity = r;
1602 mWindowManager.setFocusedApp(r, true);
1603 }
1604 }
1605
Dianne Hackborn906497c2010-05-10 15:57:38 -07001606 private final void updateLruProcessInternalLocked(ProcessRecord app,
1607 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001609 int lrui = mLruProcesses.indexOf(app);
1610 if (lrui >= 0) mLruProcesses.remove(lrui);
1611
1612 int i = mLruProcesses.size()-1;
1613 int skipTop = 0;
1614
Dianne Hackborn906497c2010-05-10 15:57:38 -07001615 app.lruSeq = mLruSeq;
1616
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001617 // compute the new weight for this process.
1618 if (updateActivityTime) {
1619 app.lastActivityTime = SystemClock.uptimeMillis();
1620 }
1621 if (app.activities.size() > 0) {
1622 // If this process has activities, we more strongly want to keep
1623 // it around.
1624 app.lruWeight = app.lastActivityTime;
1625 } else if (app.pubProviders.size() > 0) {
1626 // If this process contains content providers, we want to keep
1627 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001628 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001629 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001630 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001631 } else {
1632 // If this process doesn't have activities, we less strongly
1633 // want to keep it around, and generally want to avoid getting
1634 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001635 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001636 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001637 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001638 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001639
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001640 while (i >= 0) {
1641 ProcessRecord p = mLruProcesses.get(i);
1642 // If this app shouldn't be in front of the first N background
1643 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001644 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001645 skipTop--;
1646 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001647 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001648 mLruProcesses.add(i+1, app);
1649 break;
1650 }
1651 i--;
1652 }
1653 if (i < 0) {
1654 mLruProcesses.add(0, app);
1655 }
1656
Dianne Hackborn906497c2010-05-10 15:57:38 -07001657 // If the app is currently using a content provider or service,
1658 // bump those processes as well.
1659 if (app.connections.size() > 0) {
1660 for (ConnectionRecord cr : app.connections) {
1661 if (cr.binding != null && cr.binding.service != null
1662 && cr.binding.service.app != null
1663 && cr.binding.service.app.lruSeq != mLruSeq) {
1664 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1665 updateActivityTime, i+1);
1666 }
1667 }
1668 }
1669 if (app.conProviders.size() > 0) {
1670 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001671 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1672 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001673 updateActivityTime, i+1);
1674 }
1675 }
1676 }
1677
Joe Onorato8a9b2202010-02-26 18:56:32 -08001678 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 if (oomAdj) {
1680 updateOomAdjLocked();
1681 }
1682 }
1683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001685 boolean oomAdj, boolean updateActivityTime) {
1686 mLruSeq++;
1687 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1688 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001689
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001690 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 String processName, int uid) {
1692 if (uid == Process.SYSTEM_UID) {
1693 // The system gets to run in any process. If there are multiple
1694 // processes with the same uid, just pick the first (this
1695 // should never happen).
1696 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1697 processName);
1698 return procs != null ? procs.valueAt(0) : null;
1699 }
1700 ProcessRecord proc = mProcessNames.get(processName, uid);
1701 return proc;
1702 }
1703
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001704 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001705 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001706 try {
1707 if (pm.performDexOpt(packageName)) {
1708 mDidDexOpt = true;
1709 }
1710 } catch (RemoteException e) {
1711 }
1712 }
1713
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001714 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001715 int transit = mWindowManager.getPendingAppTransition();
1716 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1717 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1718 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1719 }
1720
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001721 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001723 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1725 // We don't have to do anything more if:
1726 // (1) There is an existing application record; and
1727 // (2) The caller doesn't think it is dead, OR there is no thread
1728 // object attached to it so we know it couldn't have crashed; and
1729 // (3) There is a pid assigned to it, so it is either starting or
1730 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001731 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 + " app=" + app + " knownToBeDead=" + knownToBeDead
1733 + " thread=" + (app != null ? app.thread : null)
1734 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001735 if (app != null && app.pid > 0) {
1736 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001737 // We already have the app running, or are waiting for it to
1738 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001739 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001740 // If this is a new package in the process, add the package to the list
1741 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001742 return app;
1743 } else {
1744 // An application record is attached to a previous process,
1745 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001746 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001747 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 String hostingNameStr = hostingName != null
1752 ? hostingName.flattenToShortString() : null;
1753
1754 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1755 // If we are in the background, then check to see if this process
1756 // is bad. If so, we will just silently fail.
1757 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001758 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1759 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 return null;
1761 }
1762 } else {
1763 // When the user is explicitly starting a process, then clear its
1764 // crash count so that we won't make it bad until they see at
1765 // least one crash dialog again, and make the process good again
1766 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001767 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1768 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001769 mProcessCrashTimes.remove(info.processName, info.uid);
1770 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001771 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001772 info.processName);
1773 mBadProcesses.remove(info.processName, info.uid);
1774 if (app != null) {
1775 app.bad = false;
1776 }
1777 }
1778 }
1779
1780 if (app == null) {
1781 app = newProcessRecordLocked(null, info, processName);
1782 mProcessNames.put(processName, info.uid, app);
1783 } else {
1784 // If this is a new package in the process, add the package to the list
1785 app.addPackage(info.packageName);
1786 }
1787
1788 // If the system is not ready yet, then hold off on starting this
1789 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001790 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001791 && !isAllowedWhileBooting(info)
1792 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 if (!mProcessesOnHold.contains(app)) {
1794 mProcessesOnHold.add(app);
1795 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001796 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 return app;
1798 }
1799
1800 startProcessLocked(app, hostingType, hostingNameStr);
1801 return (app.pid != 0) ? app : null;
1802 }
1803
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001804 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1805 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1806 }
1807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 private final void startProcessLocked(ProcessRecord app,
1809 String hostingType, String hostingNameStr) {
1810 if (app.pid > 0 && app.pid != MY_PID) {
1811 synchronized (mPidsSelfLocked) {
1812 mPidsSelfLocked.remove(app.pid);
1813 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1814 }
1815 app.pid = 0;
1816 }
1817
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001818 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1819 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001820 mProcessesOnHold.remove(app);
1821
1822 updateCpuStats();
1823
1824 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1825 mProcDeaths[0] = 0;
1826
1827 try {
1828 int uid = app.info.uid;
1829 int[] gids = null;
1830 try {
1831 gids = mContext.getPackageManager().getPackageGids(
1832 app.info.packageName);
1833 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001834 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 }
1836 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1837 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1838 && mTopComponent != null
1839 && app.processName.equals(mTopComponent.getPackageName())) {
1840 uid = 0;
1841 }
1842 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1843 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1844 uid = 0;
1845 }
1846 }
1847 int debugFlags = 0;
1848 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1849 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001850 // Also turn on CheckJNI for debuggable apps. It's quite
1851 // awkward to turn on otherwise.
1852 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001854 // Run the app in safe mode if its manifest requests so or the
1855 // system is booted in safe mode.
1856 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1857 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001858 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1861 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1862 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001863 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1864 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1865 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 if ("1".equals(SystemProperties.get("debug.assert"))) {
1867 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1868 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001869
1870 // Start the process. It will either succeed and return a result containing
1871 // the PID of the new process, or else throw a RuntimeException.
1872 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001873 app.processName, uid, uid, gids, debugFlags,
1874 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1877 synchronized (bs) {
1878 if (bs.isOnBattery()) {
1879 app.batteryStats.incStartsLocked();
1880 }
1881 }
1882
Jeff Brown3f9dd282011-07-08 20:02:19 -07001883 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 app.processName, hostingType,
1885 hostingNameStr != null ? hostingNameStr : "");
1886
1887 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001888 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001889 }
1890
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001891 StringBuilder buf = mStringBuilder;
1892 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 buf.append("Start proc ");
1894 buf.append(app.processName);
1895 buf.append(" for ");
1896 buf.append(hostingType);
1897 if (hostingNameStr != null) {
1898 buf.append(" ");
1899 buf.append(hostingNameStr);
1900 }
1901 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001902 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001903 buf.append(" uid=");
1904 buf.append(uid);
1905 buf.append(" gids={");
1906 if (gids != null) {
1907 for (int gi=0; gi<gids.length; gi++) {
1908 if (gi != 0) buf.append(", ");
1909 buf.append(gids[gi]);
1910
1911 }
1912 }
1913 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001914 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001915 app.pid = startResult.pid;
1916 app.usingWrapper = startResult.usingWrapper;
1917 app.removed = false;
1918 synchronized (mPidsSelfLocked) {
1919 this.mPidsSelfLocked.put(startResult.pid, app);
1920 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1921 msg.obj = app;
1922 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1923 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001924 }
1925 } catch (RuntimeException e) {
1926 // XXX do better error recovery.
1927 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001928 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001929 }
1930 }
1931
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001932 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001933 if (resumed) {
1934 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1935 } else {
1936 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1937 }
1938 }
1939
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001940 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001941 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1942 && mTopAction == null) {
1943 // We are running in factory test mode, but unable to find
1944 // the factory test app, so just sit around displaying the
1945 // error message and don't try to start anything.
1946 return false;
1947 }
1948 Intent intent = new Intent(
1949 mTopAction,
1950 mTopData != null ? Uri.parse(mTopData) : null);
1951 intent.setComponent(mTopComponent);
1952 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1953 intent.addCategory(Intent.CATEGORY_HOME);
1954 }
1955 ActivityInfo aInfo =
1956 intent.resolveActivityInfo(mContext.getPackageManager(),
1957 STOCK_PM_FLAGS);
1958 if (aInfo != null) {
1959 intent.setComponent(new ComponentName(
1960 aInfo.applicationInfo.packageName, aInfo.name));
1961 // Don't do this if the home app is currently being
1962 // instrumented.
1963 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1964 aInfo.applicationInfo.uid);
1965 if (app == null || app.instrumentationClass == null) {
1966 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001967 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001968 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001969 }
1970 }
1971
1972
1973 return true;
1974 }
1975
1976 /**
1977 * Starts the "new version setup screen" if appropriate.
1978 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001979 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001980 // Only do this once per boot.
1981 if (mCheckedForSetup) {
1982 return;
1983 }
1984
1985 // We will show this screen if the current one is a different
1986 // version than the last one shown, and we are not running in
1987 // low-level factory test mode.
1988 final ContentResolver resolver = mContext.getContentResolver();
1989 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1990 Settings.Secure.getInt(resolver,
1991 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1992 mCheckedForSetup = true;
1993
1994 // See if we should be showing the platform update setup UI.
1995 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1996 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1997 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1998
1999 // We don't allow third party apps to replace this.
2000 ResolveInfo ri = null;
2001 for (int i=0; ris != null && i<ris.size(); i++) {
2002 if ((ris.get(i).activityInfo.applicationInfo.flags
2003 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2004 ri = ris.get(i);
2005 break;
2006 }
2007 }
2008
2009 if (ri != null) {
2010 String vers = ri.activityInfo.metaData != null
2011 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2012 : null;
2013 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2014 vers = ri.activityInfo.applicationInfo.metaData.getString(
2015 Intent.METADATA_SETUP_VERSION);
2016 }
2017 String lastVers = Settings.Secure.getString(
2018 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2019 if (vers != null && !vers.equals(lastVers)) {
2020 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2021 intent.setComponent(new ComponentName(
2022 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002023 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002024 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002025 }
2026 }
2027 }
2028 }
2029
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002030 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002031 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002032 }
2033
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002034 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002035 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002036 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2037 }
2038 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002039
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002040 public void setFrontActivityScreenCompatMode(int mode) {
2041 synchronized (this) {
2042 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2043 }
2044 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002045
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002046 public int getPackageScreenCompatMode(String packageName) {
2047 synchronized (this) {
2048 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2049 }
2050 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002051
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002052 public void setPackageScreenCompatMode(String packageName, int mode) {
2053 synchronized (this) {
2054 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002055 }
2056 }
2057
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002058 public boolean getPackageAskScreenCompat(String packageName) {
2059 synchronized (this) {
2060 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2061 }
2062 }
2063
2064 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2065 synchronized (this) {
2066 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2067 }
2068 }
2069
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002070 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002071 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002072
2073 final int identHash = System.identityHashCode(r);
2074 updateUsageStats(r, true);
2075
2076 int i = mWatchers.beginBroadcast();
2077 while (i > 0) {
2078 i--;
2079 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2080 if (w != null) {
2081 try {
2082 w.activityResuming(identHash);
2083 } catch (RemoteException e) {
2084 }
2085 }
2086 }
2087 mWatchers.finishBroadcast();
2088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002089
Jeff Sharkeya4620792011-05-20 15:29:23 -07002090 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2091 int i = mProcessObservers.beginBroadcast();
2092 while (i > 0) {
2093 i--;
2094 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2095 if (observer != null) {
2096 try {
2097 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2098 } catch (RemoteException e) {
2099 }
2100 }
2101 }
2102 mProcessObservers.finishBroadcast();
2103 }
2104
2105 private void dispatchProcessDied(int pid, int uid) {
2106 int i = mProcessObservers.beginBroadcast();
2107 while (i > 0) {
2108 i--;
2109 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2110 if (observer != null) {
2111 try {
2112 observer.onProcessDied(pid, uid);
2113 } catch (RemoteException e) {
2114 }
2115 }
2116 }
2117 mProcessObservers.finishBroadcast();
2118 }
2119
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002120 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002121 final int N = mPendingActivityLaunches.size();
2122 if (N <= 0) {
2123 return;
2124 }
2125 for (int i=0; i<N; i++) {
2126 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002127 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002128 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2129 doResume && i == (N-1));
2130 }
2131 mPendingActivityLaunches.clear();
2132 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002133
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002134 public final int startActivity(IApplicationThread caller,
2135 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2136 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002137 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2138 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002139 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002140 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002141 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2142 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002143 }
2144
2145 public final WaitResult startActivityAndWait(IApplicationThread caller,
2146 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2147 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002148 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2149 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002150 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002151 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002152 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002153 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2154 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002155 return res;
2156 }
2157
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002158 public final int startActivityWithConfig(IApplicationThread caller,
2159 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2160 int grantedMode, IBinder resultTo,
2161 String resultWho, int requestCode, boolean onlyIfNeeded,
2162 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002163 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002164 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002165 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002166 }
2167
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002168 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002169 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002170 IBinder resultTo, String resultWho, int requestCode,
2171 int flagsMask, int flagsValues) {
2172 // Refuse possible leaked file descriptors
2173 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2174 throw new IllegalArgumentException("File descriptors passed in Intent");
2175 }
2176
2177 IIntentSender sender = intent.getTarget();
2178 if (!(sender instanceof PendingIntentRecord)) {
2179 throw new IllegalArgumentException("Bad PendingIntent object");
2180 }
2181
2182 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002183
2184 synchronized (this) {
2185 // If this is coming from the currently resumed activity, it is
2186 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002187 if (mMainStack.mResumedActivity != null
2188 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002189 Binder.getCallingUid()) {
2190 mAppSwitchesAllowedTime = 0;
2191 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002192 }
2193
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002194 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002195 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2196 }
2197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 public boolean startNextMatchingActivity(IBinder callingActivity,
2199 Intent intent) {
2200 // Refuse possible leaked file descriptors
2201 if (intent != null && intent.hasFileDescriptors() == true) {
2202 throw new IllegalArgumentException("File descriptors passed in Intent");
2203 }
2204
2205 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002206 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2207 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002208 return false;
2209 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 if (r.app == null || r.app.thread == null) {
2211 // The caller is not running... d'oh!
2212 return false;
2213 }
2214 intent = new Intent(intent);
2215 // The caller is not allowed to change the data.
2216 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2217 // And we are resetting to find the next component...
2218 intent.setComponent(null);
2219
2220 ActivityInfo aInfo = null;
2221 try {
2222 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002223 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002224 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002225 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226
2227 // Look for the original activity in the list...
2228 final int N = resolves != null ? resolves.size() : 0;
2229 for (int i=0; i<N; i++) {
2230 ResolveInfo rInfo = resolves.get(i);
2231 if (rInfo.activityInfo.packageName.equals(r.packageName)
2232 && rInfo.activityInfo.name.equals(r.info.name)) {
2233 // We found the current one... the next matching is
2234 // after it.
2235 i++;
2236 if (i<N) {
2237 aInfo = resolves.get(i).activityInfo;
2238 }
2239 break;
2240 }
2241 }
2242 } catch (RemoteException e) {
2243 }
2244
2245 if (aInfo == null) {
2246 // Nobody who is next!
2247 return false;
2248 }
2249
2250 intent.setComponent(new ComponentName(
2251 aInfo.applicationInfo.packageName, aInfo.name));
2252 intent.setFlags(intent.getFlags()&~(
2253 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2254 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2255 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2256 Intent.FLAG_ACTIVITY_NEW_TASK));
2257
2258 // Okay now we need to start the new activity, replacing the
2259 // currently running activity. This is a little tricky because
2260 // we want to start the new one as if the current one is finished,
2261 // but not finish the current one first so that there is no flicker.
2262 // And thus...
2263 final boolean wasFinishing = r.finishing;
2264 r.finishing = true;
2265
2266 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002267 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 final String resultWho = r.resultWho;
2269 final int requestCode = r.requestCode;
2270 r.resultTo = null;
2271 if (resultTo != null) {
2272 resultTo.removeResultsLocked(r, resultWho, requestCode);
2273 }
2274
2275 final long origId = Binder.clearCallingIdentity();
2276 // XXX we are not dealing with propagating grantedUriPermissions...
2277 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002278 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002280 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 Binder.restoreCallingIdentity(origId);
2282
2283 r.finishing = wasFinishing;
2284 if (res != START_SUCCESS) {
2285 return false;
2286 }
2287 return true;
2288 }
2289 }
2290
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002291 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 Intent intent, String resolvedType, IBinder resultTo,
2293 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002294
2295 // This is so super not safe, that only the system (or okay root)
2296 // can do it.
2297 final int callingUid = Binder.getCallingUid();
2298 if (callingUid != 0 && callingUid != Process.myUid()) {
2299 throw new SecurityException(
2300 "startActivityInPackage only available to the system");
2301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002303 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002304 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2305 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002306 }
2307
2308 public final int startActivities(IApplicationThread caller,
2309 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2310 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2311 }
2312
2313 public final int startActivitiesInPackage(int uid,
2314 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2315
2316 // This is so super not safe, that only the system (or okay root)
2317 // can do it.
2318 final int callingUid = Binder.getCallingUid();
2319 if (callingUid != 0 && callingUid != Process.myUid()) {
2320 throw new SecurityException(
2321 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 }
2323
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002324 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 }
2326
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002327 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002329 // Quick case: check if the top-most recent task is the same.
2330 if (N > 0 && mRecentTasks.get(0) == task) {
2331 return;
2332 }
2333 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 for (int i=0; i<N; i++) {
2335 TaskRecord tr = mRecentTasks.get(i);
2336 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2337 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2338 mRecentTasks.remove(i);
2339 i--;
2340 N--;
2341 if (task.intent == null) {
2342 // If the new recent task we are adding is not fully
2343 // specified, then replace it with the existing recent task.
2344 task = tr;
2345 }
2346 }
2347 }
2348 if (N >= MAX_RECENT_TASKS) {
2349 mRecentTasks.remove(N-1);
2350 }
2351 mRecentTasks.add(0, task);
2352 }
2353
2354 public void setRequestedOrientation(IBinder token,
2355 int requestedOrientation) {
2356 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002357 ActivityRecord r = mMainStack.isInStackLocked(token);
2358 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 return;
2360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361 final long origId = Binder.clearCallingIdentity();
2362 mWindowManager.setAppOrientation(r, requestedOrientation);
2363 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002364 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 r.mayFreezeScreenLocked(r.app) ? r : null);
2366 if (config != null) {
2367 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002368 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002369 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
2371 }
2372 Binder.restoreCallingIdentity(origId);
2373 }
2374 }
2375
2376 public int getRequestedOrientation(IBinder token) {
2377 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002378 ActivityRecord r = mMainStack.isInStackLocked(token);
2379 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002382 return mWindowManager.getAppOrientation(r);
2383 }
2384 }
2385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 /**
2387 * This is the internal entry point for handling Activity.finish().
2388 *
2389 * @param token The Binder token referencing the Activity we want to finish.
2390 * @param resultCode Result code, if any, from this Activity.
2391 * @param resultData Result data (Intent), if any, from this Activity.
2392 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002393 * @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 -08002394 */
2395 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2396 // Refuse possible leaked file descriptors
2397 if (resultData != null && resultData.hasFileDescriptors() == true) {
2398 throw new IllegalArgumentException("File descriptors passed in Intent");
2399 }
2400
2401 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002402 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002404 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 if (next != null) {
2406 // ask watcher if this is allowed
2407 boolean resumeOK = true;
2408 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002409 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002410 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002411 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002412 }
2413
2414 if (!resumeOK) {
2415 return false;
2416 }
2417 }
2418 }
2419 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002420 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 resultData, "app-request");
2422 Binder.restoreCallingIdentity(origId);
2423 return res;
2424 }
2425 }
2426
Dianne Hackborn860755f2010-06-03 18:47:52 -07002427 public final void finishHeavyWeightApp() {
2428 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2429 != PackageManager.PERMISSION_GRANTED) {
2430 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2431 + Binder.getCallingPid()
2432 + ", uid=" + Binder.getCallingUid()
2433 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2434 Slog.w(TAG, msg);
2435 throw new SecurityException(msg);
2436 }
2437
2438 synchronized(this) {
2439 if (mHeavyWeightProcess == null) {
2440 return;
2441 }
2442
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002443 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002444 mHeavyWeightProcess.activities);
2445 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002446 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002447 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002448 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002449 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002450 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002451 null, "finish-heavy");
2452 }
2453 }
2454 }
2455
2456 mHeavyWeightProcess = null;
2457 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2458 }
2459 }
2460
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002461 public void crashApplication(int uid, int initialPid, String packageName,
2462 String message) {
2463 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2464 != PackageManager.PERMISSION_GRANTED) {
2465 String msg = "Permission Denial: crashApplication() from pid="
2466 + Binder.getCallingPid()
2467 + ", uid=" + Binder.getCallingUid()
2468 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2469 Slog.w(TAG, msg);
2470 throw new SecurityException(msg);
2471 }
2472
2473 synchronized(this) {
2474 ProcessRecord proc = null;
2475
2476 // Figure out which process to kill. We don't trust that initialPid
2477 // still has any relation to current pids, so must scan through the
2478 // list.
2479 synchronized (mPidsSelfLocked) {
2480 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2481 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2482 if (p.info.uid != uid) {
2483 continue;
2484 }
2485 if (p.pid == initialPid) {
2486 proc = p;
2487 break;
2488 }
2489 for (String str : p.pkgList) {
2490 if (str.equals(packageName)) {
2491 proc = p;
2492 }
2493 }
2494 }
2495 }
2496
2497 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002498 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002499 + " initialPid=" + initialPid
2500 + " packageName=" + packageName);
2501 return;
2502 }
2503
2504 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002505 if (proc.pid == Process.myPid()) {
2506 Log.w(TAG, "crashApplication: trying to crash self!");
2507 return;
2508 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002509 long ident = Binder.clearCallingIdentity();
2510 try {
2511 proc.thread.scheduleCrash(message);
2512 } catch (RemoteException e) {
2513 }
2514 Binder.restoreCallingIdentity(ident);
2515 }
2516 }
2517 }
2518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 public final void finishSubActivity(IBinder token, String resultWho,
2520 int requestCode) {
2521 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002522 ActivityRecord self = mMainStack.isInStackLocked(token);
2523 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 return;
2525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526
2527 final long origId = Binder.clearCallingIdentity();
2528
2529 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002530 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2531 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002532 if (r.resultTo == self && r.requestCode == requestCode) {
2533 if ((r.resultWho == null && resultWho == null) ||
2534 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002535 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 Activity.RESULT_CANCELED, null, "request-sub");
2537 }
2538 }
2539 }
2540
2541 Binder.restoreCallingIdentity(origId);
2542 }
2543 }
2544
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002545 public boolean willActivityBeVisible(IBinder token) {
2546 synchronized(this) {
2547 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002548 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2549 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002550 if (r == token) {
2551 return true;
2552 }
2553 if (r.fullscreen && !r.finishing) {
2554 return false;
2555 }
2556 }
2557 return true;
2558 }
2559 }
2560
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002561 public void overridePendingTransition(IBinder token, String packageName,
2562 int enterAnim, int exitAnim) {
2563 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002564 ActivityRecord self = mMainStack.isInStackLocked(token);
2565 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002566 return;
2567 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002568
2569 final long origId = Binder.clearCallingIdentity();
2570
2571 if (self.state == ActivityState.RESUMED
2572 || self.state == ActivityState.PAUSING) {
2573 mWindowManager.overridePendingAppTransition(packageName,
2574 enterAnim, exitAnim);
2575 }
2576
2577 Binder.restoreCallingIdentity(origId);
2578 }
2579 }
2580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002582 * Main function for removing an existing process from the activity manager
2583 * as a result of that process going away. Clears out all connections
2584 * to the process.
2585 */
2586 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002587 boolean restarting, boolean allowRestart) {
2588 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002589 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002590 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 }
2592
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002593 if (mProfileProc == app) {
2594 clearProfilerLocked();
2595 }
2596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002598 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2599 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2600 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002602 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2603 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002604 }
2605
2606 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002607 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608
2609 boolean atTop = true;
2610 boolean hasVisibleActivities = false;
2611
2612 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002613 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002614 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 TAG, "Removing app " + app + " from history with " + i + " entries");
2616 while (i > 0) {
2617 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002618 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002619 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2621 if (r.app == app) {
2622 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002623 if (ActivityStack.DEBUG_ADD_REMOVE) {
2624 RuntimeException here = new RuntimeException("here");
2625 here.fillInStackTrace();
2626 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2627 + ": haveState=" + r.haveState
2628 + " stateNotNeeded=" + r.stateNotNeeded
2629 + " finishing=" + r.finishing
2630 + " state=" + r.state, here);
2631 }
2632 if (!r.finishing) {
2633 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2634 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002635 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002637 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 mWindowManager.removeAppToken(r);
2639 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002640 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002641 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002642 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643
2644 } else {
2645 // We have the current state for this activity, so
2646 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002647 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 TAG, "Keeping entry, setting app to null");
2649 if (r.visible) {
2650 hasVisibleActivities = true;
2651 }
2652 r.app = null;
2653 r.nowVisible = false;
2654 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002655 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2656 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 r.icicle = null;
2658 }
2659 }
2660
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002661 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 }
2663 atTop = false;
2664 }
2665
2666 app.activities.clear();
2667
2668 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002669 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 + " running instrumentation " + app.instrumentationClass);
2671 Bundle info = new Bundle();
2672 info.putString("shortMsg", "Process crashed.");
2673 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2674 }
2675
2676 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002677 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 // If there was nothing to resume, and we are not already
2679 // restarting this process, but there is a visible activity that
2680 // is hosted by the process... then make sure all visible
2681 // activities are running, taking care of restarting this
2682 // process.
2683 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002684 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 }
2686 }
2687 }
2688 }
2689
2690 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2691 IBinder threadBinder = thread.asBinder();
2692
2693 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002694 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2695 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2697 return i;
2698 }
2699 }
2700 return -1;
2701 }
2702
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002703 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 IApplicationThread thread) {
2705 if (thread == null) {
2706 return null;
2707 }
2708
2709 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002710 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 }
2712
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002713 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 IApplicationThread thread) {
2715
2716 mProcDeaths[0]++;
2717
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002718 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2719 synchronized (stats) {
2720 stats.noteProcessDiedLocked(app.info.uid, pid);
2721 }
2722
Magnus Edlund7bb25812010-02-24 15:45:06 +01002723 // Clean up already done if the process has been re-started.
2724 if (app.pid == pid && app.thread != null &&
2725 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002726 if (!app.killedBackground) {
2727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2728 + ") has died.");
2729 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002731 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 TAG, "Dying app: " + app + ", pid: " + pid
2733 + ", thread: " + thread.asBinder());
2734 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002735 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736
2737 if (doLowMem) {
2738 // If there are no longer any background processes running,
2739 // and the app that died was not running instrumentation,
2740 // then tell everyone we are now low on memory.
2741 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002742 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2743 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002744 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 haveBg = true;
2746 break;
2747 }
2748 }
2749
2750 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002751 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002752 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002753 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2754 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002755 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002756 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2757 // The low memory report is overriding any current
2758 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002759 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002760 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002761 rec.lastRequestedGc = 0;
2762 } else {
2763 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002765 rec.reportLowMemory = true;
2766 rec.lastLowMemory = now;
2767 mProcessesToGc.remove(rec);
2768 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 }
2770 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002771 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 }
2773 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002774 } else if (app.pid != pid) {
2775 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002776 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002777 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002778 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002779 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002780 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002781 + thread.asBinder());
2782 }
2783 }
2784
Dan Egnor42471dd2010-01-07 17:25:22 -08002785 /**
2786 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002787 * @param clearTraces causes the dump file to be erased prior to the new
2788 * traces being written, if true; when false, the new traces will be
2789 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002790 * @param firstPids of dalvik VM processes to dump stack traces for first
2791 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002792 * @return file containing stack traces, or null if no dump file is configured
2793 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002794 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2795 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002796 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2797 if (tracesPath == null || tracesPath.length() == 0) {
2798 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002799 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002800
2801 File tracesFile = new File(tracesPath);
2802 try {
2803 File tracesDir = tracesFile.getParentFile();
2804 if (!tracesDir.exists()) tracesFile.mkdirs();
2805 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2806
Christopher Tate6ee412d2010-05-28 12:01:56 -07002807 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002808 tracesFile.createNewFile();
2809 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2810 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002811 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002812 return null;
2813 }
2814
2815 // Use a FileObserver to detect when traces finish writing.
2816 // The order of traces is considered important to maintain for legibility.
2817 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2818 public synchronized void onEvent(int event, String path) { notify(); }
2819 };
2820
2821 try {
2822 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002823
2824 // First collect all of the stacks of the most important pids.
2825 try {
2826 int num = firstPids.size();
2827 for (int i = 0; i < num; i++) {
2828 synchronized (observer) {
2829 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2830 observer.wait(200); // Wait for write-close, give up after 200msec
2831 }
2832 }
2833 } catch (InterruptedException e) {
2834 Log.wtf(TAG, e);
2835 }
2836
2837 // Next measure CPU usage.
2838 if (processStats != null) {
2839 processStats.init();
2840 System.gc();
2841 processStats.update();
2842 try {
2843 synchronized (processStats) {
2844 processStats.wait(500); // measure over 1/2 second.
2845 }
2846 } catch (InterruptedException e) {
2847 }
2848 processStats.update();
2849
2850 // We'll take the stack crawls of just the top apps using CPU.
2851 final int N = processStats.countWorkingStats();
2852 int numProcs = 0;
2853 for (int i=0; i<N && numProcs<5; i++) {
2854 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2855 if (lastPids.indexOfKey(stats.pid) >= 0) {
2856 numProcs++;
2857 try {
2858 synchronized (observer) {
2859 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2860 observer.wait(200); // Wait for write-close, give up after 200msec
2861 }
2862 } catch (InterruptedException e) {
2863 Log.wtf(TAG, e);
2864 }
2865
2866 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002867 }
2868 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002869
2870 return tracesFile;
2871
Dan Egnor42471dd2010-01-07 17:25:22 -08002872 } finally {
2873 observer.stopWatching();
2874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 }
2876
Jeff Brown4d94a762010-09-23 11:33:28 -07002877 private final class AppNotResponding implements Runnable {
2878 private final ProcessRecord mApp;
2879 private final String mAnnotation;
2880
2881 public AppNotResponding(ProcessRecord app, String annotation) {
2882 mApp = app;
2883 mAnnotation = annotation;
2884 }
2885
2886 @Override
2887 public void run() {
2888 appNotResponding(mApp, null, null, mAnnotation);
2889 }
2890 }
2891
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002892 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2893 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002894 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2895 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2896
Dianne Hackborn287952c2010-09-22 22:34:31 -07002897 if (mController != null) {
2898 try {
2899 // 0 == continue, -1 = kill process immediately
2900 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2901 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2902 } catch (RemoteException e) {
2903 mController = null;
2904 }
2905 }
2906
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002907 long anrTime = SystemClock.uptimeMillis();
2908 if (MONITOR_CPU_USAGE) {
2909 updateCpuStatsNow();
2910 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002911
2912 synchronized (this) {
2913 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2914 if (mShuttingDown) {
2915 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2916 return;
2917 } else if (app.notResponding) {
2918 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2919 return;
2920 } else if (app.crashing) {
2921 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2922 return;
2923 }
2924
2925 // In case we come through here for the same app before completing
2926 // this one, mark as anring now so we will bail out.
2927 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002928
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002929 // Log the ANR to the event log.
2930 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2931 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002932
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002935
2936 int parentPid = app.pid;
2937 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002939
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002940 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002941
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002942 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2943 ProcessRecord r = mLruProcesses.get(i);
2944 if (r != null && r.thread != null) {
2945 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002946 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2947 if (r.persistent) {
2948 firstPids.add(pid);
2949 } else {
2950 lastPids.put(pid, Boolean.TRUE);
2951 }
2952 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
2955 }
2956
Dan Egnor42471dd2010-01-07 17:25:22 -08002957 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002958 StringBuilder info = mStringBuilder;
2959 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002960 info.append("ANR in ").append(app.processName);
2961 if (activity != null && activity.shortComponentName != null) {
2962 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002963 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002964 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002966 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002968 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002969 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971
Dianne Hackborn287952c2010-09-22 22:34:31 -07002972 final ProcessStats processStats = new ProcessStats(true);
2973
2974 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2975
Dan Egnor42471dd2010-01-07 17:25:22 -08002976 String cpuInfo = null;
2977 if (MONITOR_CPU_USAGE) {
2978 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002979 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002980 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002981 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002982 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002983 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002984 }
2985
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002986 info.append(processStats.printCurrentState(anrTime));
2987
Joe Onorato8a9b2202010-02-26 18:56:32 -08002988 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002989 if (tracesFile == null) {
2990 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2991 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2992 }
2993
Jeff Sharkeya353d262011-10-28 11:12:06 -07002994 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
2995 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08002996
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002997 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002999 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3000 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003002 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3003 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 }
3005 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003006 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003007 }
3008 }
3009
Dan Egnor42471dd2010-01-07 17:25:22 -08003010 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3011 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3012 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003013
3014 synchronized (this) {
3015 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003016 Slog.w(TAG, "Killing " + app + ": background ANR");
3017 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3018 app.processName, app.setAdj, "background ANR");
3019 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003020 return;
3021 }
3022
3023 // Set the app's notResponding state, and look up the errorReportReceiver
3024 makeAppNotRespondingLocked(app,
3025 activity != null ? activity.shortComponentName : null,
3026 annotation != null ? "ANR " + annotation : "ANR",
3027 info.toString());
3028
3029 // Bring up the infamous App Not Responding dialog
3030 Message msg = Message.obtain();
3031 HashMap map = new HashMap();
3032 msg.what = SHOW_NOT_RESPONDING_MSG;
3033 msg.obj = map;
3034 map.put("app", app);
3035 if (activity != null) {
3036 map.put("activity", activity);
3037 }
3038
3039 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 }
3042
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003043 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3044 if (!mLaunchWarningShown) {
3045 mLaunchWarningShown = true;
3046 mHandler.post(new Runnable() {
3047 @Override
3048 public void run() {
3049 synchronized (ActivityManagerService.this) {
3050 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3051 d.show();
3052 mHandler.postDelayed(new Runnable() {
3053 @Override
3054 public void run() {
3055 synchronized (ActivityManagerService.this) {
3056 d.dismiss();
3057 mLaunchWarningShown = false;
3058 }
3059 }
3060 }, 4000);
3061 }
3062 }
3063 });
3064 }
3065 }
3066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003067 public boolean clearApplicationUserData(final String packageName,
3068 final IPackageDataObserver observer) {
3069 int uid = Binder.getCallingUid();
3070 int pid = Binder.getCallingPid();
3071 long callingId = Binder.clearCallingIdentity();
3072 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003073 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 int pkgUid = -1;
3075 synchronized(this) {
3076 try {
3077 pkgUid = pm.getPackageUid(packageName);
3078 } catch (RemoteException e) {
3079 }
3080 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003081 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003082 return false;
3083 }
3084 if (uid == pkgUid || checkComponentPermission(
3085 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003086 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003088 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003089 } else {
3090 throw new SecurityException(pid+" does not have permission:"+
3091 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3092 "for process:"+packageName);
3093 }
3094 }
3095
3096 try {
3097 //clear application user data
3098 pm.clearApplicationUserData(packageName, observer);
3099 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3100 Uri.fromParts("package", packageName, null));
3101 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003102 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3103 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 } catch (RemoteException e) {
3105 }
3106 } finally {
3107 Binder.restoreCallingIdentity(callingId);
3108 }
3109 return true;
3110 }
3111
Dianne Hackborn03abb812010-01-04 18:43:19 -08003112 public void killBackgroundProcesses(final String packageName) {
3113 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3114 != PackageManager.PERMISSION_GRANTED &&
3115 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3116 != PackageManager.PERMISSION_GRANTED) {
3117 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 + Binder.getCallingPid()
3119 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003120 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003121 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003122 throw new SecurityException(msg);
3123 }
3124
3125 long callingId = Binder.clearCallingIdentity();
3126 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003127 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 int pkgUid = -1;
3129 synchronized(this) {
3130 try {
3131 pkgUid = pm.getPackageUid(packageName);
3132 } catch (RemoteException e) {
3133 }
3134 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003135 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003136 return;
3137 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003138 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne02c88a2011-10-28 13:58:15 -07003139 ProcessList.SERVICE_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003140 }
3141 } finally {
3142 Binder.restoreCallingIdentity(callingId);
3143 }
3144 }
3145
3146 public void forceStopPackage(final String packageName) {
3147 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3148 != PackageManager.PERMISSION_GRANTED) {
3149 String msg = "Permission Denial: forceStopPackage() from pid="
3150 + Binder.getCallingPid()
3151 + ", uid=" + Binder.getCallingUid()
3152 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003153 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003154 throw new SecurityException(msg);
3155 }
3156
3157 long callingId = Binder.clearCallingIdentity();
3158 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003159 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003160 int pkgUid = -1;
3161 synchronized(this) {
3162 try {
3163 pkgUid = pm.getPackageUid(packageName);
3164 } catch (RemoteException e) {
3165 }
3166 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003167 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003168 return;
3169 }
3170 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003171 try {
3172 pm.setPackageStoppedState(packageName, true);
3173 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003174 } catch (IllegalArgumentException e) {
3175 Slog.w(TAG, "Failed trying to unstop package "
3176 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 }
3179 } finally {
3180 Binder.restoreCallingIdentity(callingId);
3181 }
3182 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003183
3184 /*
3185 * The pkg name and uid have to be specified.
3186 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3187 */
3188 public void killApplicationWithUid(String pkg, int uid) {
3189 if (pkg == null) {
3190 return;
3191 }
3192 // Make sure the uid is valid.
3193 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003194 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003195 return;
3196 }
3197 int callerUid = Binder.getCallingUid();
3198 // Only the system server can kill an application
3199 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003200 // Post an aysnc message to kill the application
3201 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3202 msg.arg1 = uid;
3203 msg.arg2 = 0;
3204 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003205 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003206 } else {
3207 throw new SecurityException(callerUid + " cannot kill pkg: " +
3208 pkg);
3209 }
3210 }
3211
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003212 public void closeSystemDialogs(String reason) {
3213 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003214 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003215 if (reason != null) {
3216 intent.putExtra("reason", reason);
3217 }
3218
3219 final int uid = Binder.getCallingUid();
3220 final long origId = Binder.clearCallingIdentity();
3221 synchronized (this) {
3222 int i = mWatchers.beginBroadcast();
3223 while (i > 0) {
3224 i--;
3225 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3226 if (w != null) {
3227 try {
3228 w.closingSystemDialogs(reason);
3229 } catch (RemoteException e) {
3230 }
3231 }
3232 }
3233 mWatchers.finishBroadcast();
3234
Dianne Hackbornffa42482009-09-23 22:20:11 -07003235 mWindowManager.closeSystemDialogs(reason);
3236
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003237 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3238 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003239 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003240 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003241 Activity.RESULT_CANCELED, null, "close-sys");
3242 }
3243 }
3244
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003245 broadcastIntentLocked(null, null, intent, null,
3246 null, 0, null, null, null, false, false, -1, uid);
3247 }
3248 Binder.restoreCallingIdentity(origId);
3249 }
3250
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003251 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003252 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003253 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3254 for (int i=pids.length-1; i>=0; i--) {
3255 infos[i] = new Debug.MemoryInfo();
3256 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003257 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003258 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003259 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003260
Dianne Hackbornb437e092011-08-05 17:50:29 -07003261 public long[] getProcessPss(int[] pids) throws RemoteException {
3262 long[] pss = new long[pids.length];
3263 for (int i=pids.length-1; i>=0; i--) {
3264 pss[i] = Debug.getPss(pids[i]);
3265 }
3266 return pss;
3267 }
3268
Christopher Tate5e1ab332009-09-01 20:32:49 -07003269 public void killApplicationProcess(String processName, int uid) {
3270 if (processName == null) {
3271 return;
3272 }
3273
3274 int callerUid = Binder.getCallingUid();
3275 // Only the system server can kill an application
3276 if (callerUid == Process.SYSTEM_UID) {
3277 synchronized (this) {
3278 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003279 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003280 try {
3281 app.thread.scheduleSuicide();
3282 } catch (RemoteException e) {
3283 // If the other end already died, then our work here is done.
3284 }
3285 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003286 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003287 + processName + " / " + uid);
3288 }
3289 }
3290 } else {
3291 throw new SecurityException(callerUid + " cannot kill app process: " +
3292 processName);
3293 }
3294 }
3295
Dianne Hackborn03abb812010-01-04 18:43:19 -08003296 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003297 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3299 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003300 if (!mProcessesReady) {
3301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 intent.putExtra(Intent.EXTRA_UID, uid);
3304 broadcastIntentLocked(null, null, intent,
3305 null, null, 0, null, null, null,
3306 false, false, MY_PID, Process.SYSTEM_UID);
3307 }
3308
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003309 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003310 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3311 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003312 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003313
Dianne Hackborn03abb812010-01-04 18:43:19 -08003314 // Remove all processes this package may have touched: all with the
3315 // same UID (except for the system or root user), and all whose name
3316 // matches the package name.
3317 final String procNamePrefix = packageName + ":";
3318 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3319 final int NA = apps.size();
3320 for (int ia=0; ia<NA; ia++) {
3321 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003322 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003323 // we don't kill persistent processes
3324 continue;
3325 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003326 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003327 if (doit) {
3328 procs.add(app);
3329 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003330 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3331 || app.processName.equals(packageName)
3332 || app.processName.startsWith(procNamePrefix)) {
3333 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003334 if (!doit) {
3335 return true;
3336 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003337 app.removed = true;
3338 procs.add(app);
3339 }
3340 }
3341 }
3342 }
3343
3344 int N = procs.size();
3345 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003346 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003347 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003348 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003349 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003350
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003351 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003352 boolean callerWillRestart, boolean purgeCache, boolean doit,
3353 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003354 int i;
3355 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 if (uid < 0) {
3358 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003359 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 } catch (RemoteException e) {
3361 }
3362 }
3363
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003364 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003365 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003366
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003367 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3368 while (badApps.hasNext()) {
3369 SparseArray<Long> ba = badApps.next();
3370 if (ba.get(uid) != null) {
3371 badApps.remove();
3372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 }
3374 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003375
3376 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003377 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003378
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003379 TaskRecord lastTask = null;
3380 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003381 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003382 final boolean samePackage = r.packageName.equals(name);
3383 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003384 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003385 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003386 if (r.finishing) {
3387 // If this activity is just finishing, then it is not
3388 // interesting as far as something to stop.
3389 continue;
3390 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003391 return true;
3392 }
3393 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003394 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003395 if (samePackage) {
3396 if (r.app != null) {
3397 r.app.removed = true;
3398 }
3399 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003401 lastTask = r.task;
3402 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3403 null, "force-stop")) {
3404 i--;
3405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 }
3407 }
3408
3409 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3410 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003411 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003412 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003413 if (!doit) {
3414 return true;
3415 }
3416 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003417 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 if (service.app != null) {
3419 service.app.removed = true;
3420 }
3421 service.app = null;
3422 services.add(service);
3423 }
3424 }
3425
3426 N = services.size();
3427 for (i=0; i<N; i++) {
3428 bringDownServiceLocked(services.get(i), true);
3429 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003430
3431 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3432 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3433 if (provider.info.packageName.equals(name)
3434 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3435 if (!doit) {
3436 return true;
3437 }
3438 didSomething = true;
3439 providers.add(provider);
3440 }
3441 }
3442
3443 N = providers.size();
3444 for (i=0; i<N; i++) {
3445 removeDyingProviderLocked(null, providers.get(i));
3446 }
3447
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003448 if (doit) {
3449 if (purgeCache) {
3450 AttributeCache ac = AttributeCache.instance();
3451 if (ac != null) {
3452 ac.removePackage(name);
3453 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003454 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003455 if (mBooted) {
3456 mMainStack.resumeTopActivityLocked(null);
3457 mMainStack.scheduleIdleLocked();
3458 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003459 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003460
3461 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003462 }
3463
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003464 private final boolean removeProcessLocked(ProcessRecord app,
3465 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 final String name = app.processName;
3467 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003468 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 TAG, "Force removing process " + app + " (" + name
3470 + "/" + uid + ")");
3471
3472 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003473 if (mHeavyWeightProcess == app) {
3474 mHeavyWeightProcess = null;
3475 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003477 boolean needRestart = false;
3478 if (app.pid > 0 && app.pid != MY_PID) {
3479 int pid = app.pid;
3480 synchronized (mPidsSelfLocked) {
3481 mPidsSelfLocked.remove(pid);
3482 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3483 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003484 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003485 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003486 Process.killProcess(pid);
3487
3488 if (app.persistent) {
3489 if (!callerWillRestart) {
3490 addAppLocked(app.info);
3491 } else {
3492 needRestart = true;
3493 }
3494 }
3495 } else {
3496 mRemovedProcesses.add(app);
3497 }
3498
3499 return needRestart;
3500 }
3501
3502 private final void processStartTimedOutLocked(ProcessRecord app) {
3503 final int pid = app.pid;
3504 boolean gone = false;
3505 synchronized (mPidsSelfLocked) {
3506 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3507 if (knownApp != null && knownApp.thread == null) {
3508 mPidsSelfLocked.remove(pid);
3509 gone = true;
3510 }
3511 }
3512
3513 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003514 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003515 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003516 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003518 if (mHeavyWeightProcess == app) {
3519 mHeavyWeightProcess = null;
3520 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3521 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003522 // Take care of any launching providers waiting for this process.
3523 checkAppInLaunchingProvidersLocked(app, true);
3524 // Take care of any services that are waiting for the process.
3525 for (int i=0; i<mPendingServices.size(); i++) {
3526 ServiceRecord sr = mPendingServices.get(i);
3527 if (app.info.uid == sr.appInfo.uid
3528 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003529 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003530 mPendingServices.remove(i);
3531 i--;
3532 bringDownServiceLocked(sr, true);
3533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003535 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3536 app.processName, app.setAdj, "start timeout");
3537 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003538 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003539 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003540 try {
3541 IBackupManager bm = IBackupManager.Stub.asInterface(
3542 ServiceManager.getService(Context.BACKUP_SERVICE));
3543 bm.agentDisconnected(app.info.packageName);
3544 } catch (RemoteException e) {
3545 // Can't happen; the backup manager is local
3546 }
3547 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003548 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003549 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003550 mPendingBroadcast.state = BroadcastRecord.IDLE;
3551 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003552 mPendingBroadcast = null;
3553 scheduleBroadcastsLocked();
3554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003555 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003556 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 }
3558 }
3559
3560 private final boolean attachApplicationLocked(IApplicationThread thread,
3561 int pid) {
3562
3563 // Find the application record that is being attached... either via
3564 // the pid if we are running in multiple processes, or just pull the
3565 // next app record if we are emulating process with anonymous threads.
3566 ProcessRecord app;
3567 if (pid != MY_PID && pid >= 0) {
3568 synchronized (mPidsSelfLocked) {
3569 app = mPidsSelfLocked.get(pid);
3570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 } else {
3572 app = null;
3573 }
3574
3575 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003576 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003577 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003578 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003579 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003580 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 } else {
3582 try {
3583 thread.scheduleExit();
3584 } catch (Exception e) {
3585 // Ignore exceptions.
3586 }
3587 }
3588 return false;
3589 }
3590
3591 // If this application record is still attached to a previous
3592 // process, clean it up now.
3593 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003594 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 }
3596
3597 // Tell the process all about itself.
3598
Joe Onorato8a9b2202010-02-26 18:56:32 -08003599 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003600 TAG, "Binding process pid " + pid + " to record " + app);
3601
3602 String processName = app.processName;
3603 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003604 AppDeathRecipient adr = new AppDeathRecipient(
3605 app, pid, thread);
3606 thread.asBinder().linkToDeath(adr, 0);
3607 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 } catch (RemoteException e) {
3609 app.resetPackageList();
3610 startProcessLocked(app, "link fail", processName);
3611 return false;
3612 }
3613
Doug Zongker2bec3d42009-12-04 12:52:44 -08003614 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615
3616 app.thread = thread;
3617 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003618 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3619 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 app.forcingToForeground = null;
3621 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003622 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623 app.debugging = false;
3624
3625 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3626
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003627 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003628 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003630 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003631 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003632 }
3633
Joe Onorato8a9b2202010-02-26 18:56:32 -08003634 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 TAG, "New app record " + app
3636 + " thread=" + thread.asBinder() + " pid=" + pid);
3637 try {
3638 int testMode = IApplicationThread.DEBUG_OFF;
3639 if (mDebugApp != null && mDebugApp.equals(processName)) {
3640 testMode = mWaitForDebugger
3641 ? IApplicationThread.DEBUG_WAIT
3642 : IApplicationThread.DEBUG_ON;
3643 app.debugging = true;
3644 if (mDebugTransient) {
3645 mDebugApp = mOrigDebugApp;
3646 mWaitForDebugger = mOrigWaitForDebugger;
3647 }
3648 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003649 String profileFile = app.instrumentationProfileFile;
3650 ParcelFileDescriptor profileFd = null;
3651 boolean profileAutoStop = false;
3652 if (mProfileApp != null && mProfileApp.equals(processName)) {
3653 mProfileProc = app;
3654 profileFile = mProfileFile;
3655 profileFd = mProfileFd;
3656 profileAutoStop = mAutoStopProfiler;
3657 }
3658
Christopher Tate181fafa2009-05-14 11:12:14 -07003659 // If the app is being launched for restore or full backup, set it up specially
3660 boolean isRestrictedBackupMode = false;
3661 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3662 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003663 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003664 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3665 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003666
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003667 ensurePackageDexOpt(app.instrumentationInfo != null
3668 ? app.instrumentationInfo.packageName
3669 : app.info.packageName);
3670 if (app.instrumentationClass != null) {
3671 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003672 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003673 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003674 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003675 ApplicationInfo appInfo = app.instrumentationInfo != null
3676 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003677 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003678 if (profileFd != null) {
3679 profileFd = profileFd.dup();
3680 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003681 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003682 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003683 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003684 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003685 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003686 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003687 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003688 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003689 } catch (Exception e) {
3690 // todo: Yikes! What should we do? For now we will try to
3691 // start another process, but that could easily get us in
3692 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003693 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694
3695 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003696 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 startProcessLocked(app, "bind fail", processName);
3698 return false;
3699 }
3700
3701 // Remove this record from the list of starting applications.
3702 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003703 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3704 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 mProcessesOnHold.remove(app);
3706
3707 boolean badApp = false;
3708 boolean didSomething = false;
3709
3710 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003711 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003712 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3714 && processName.equals(hr.processName)) {
3715 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003716 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 didSomething = true;
3718 }
3719 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003720 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003721 + hr.intent.getComponent().flattenToShortString(), e);
3722 badApp = true;
3723 }
3724 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003725 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 }
3727 }
3728
3729 // Find any services that should be running in this process...
3730 if (!badApp && mPendingServices.size() > 0) {
3731 ServiceRecord sr = null;
3732 try {
3733 for (int i=0; i<mPendingServices.size(); i++) {
3734 sr = mPendingServices.get(i);
3735 if (app.info.uid != sr.appInfo.uid
3736 || !processName.equals(sr.processName)) {
3737 continue;
3738 }
3739
3740 mPendingServices.remove(i);
3741 i--;
3742 realStartServiceLocked(sr, app);
3743 didSomething = true;
3744 }
3745 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003746 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 + sr.shortName, e);
3748 badApp = true;
3749 }
3750 }
3751
3752 // Check if the next broadcast receiver is in this process...
3753 BroadcastRecord br = mPendingBroadcast;
3754 if (!badApp && br != null && br.curApp == app) {
3755 try {
3756 mPendingBroadcast = null;
3757 processCurBroadcastLocked(br, app);
3758 didSomething = true;
3759 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003760 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 + br.curComponent.flattenToShortString(), e);
3762 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003763 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3765 br.resultExtras, br.resultAbort, true);
3766 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003767 // We need to reset the state if we fails to start the receiver.
3768 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003769 }
3770 }
3771
Christopher Tate181fafa2009-05-14 11:12:14 -07003772 // Check whether the next backup agent is in this process...
3773 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003774 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003775 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003776 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003777 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3778 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3779 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003780 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003781 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003782 e.printStackTrace();
3783 }
3784 }
3785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003786 if (badApp) {
3787 // todo: Also need to kill application to deal with all
3788 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003789 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003790 return false;
3791 }
3792
3793 if (!didSomething) {
3794 updateOomAdjLocked();
3795 }
3796
3797 return true;
3798 }
3799
3800 public final void attachApplication(IApplicationThread thread) {
3801 synchronized (this) {
3802 int callingPid = Binder.getCallingPid();
3803 final long origId = Binder.clearCallingIdentity();
3804 attachApplicationLocked(thread, callingPid);
3805 Binder.restoreCallingIdentity(origId);
3806 }
3807 }
3808
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003809 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003811 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3812 if (stopProfiling) {
3813 synchronized (this) {
3814 if (mProfileProc == r.app) {
3815 if (mProfileFd != null) {
3816 try {
3817 mProfileFd.close();
3818 } catch (IOException e) {
3819 }
3820 clearProfilerLocked();
3821 }
3822 }
3823 }
3824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 Binder.restoreCallingIdentity(origId);
3826 }
3827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003829 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003830 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 mWindowManager.enableScreenAfterBoot();
3832 }
3833
Dianne Hackborn661cd522011-08-22 00:26:20 -07003834 public void showBootMessage(final CharSequence msg, final boolean always) {
3835 mWindowManager.showBootMessage(msg, always);
3836 }
3837
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003838 public void dismissKeyguardOnNextActivity() {
3839 synchronized (this) {
3840 mMainStack.dismissKeyguardOnNextActivityLocked();
3841 }
3842 }
3843
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003844 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003845 IntentFilter pkgFilter = new IntentFilter();
3846 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3847 pkgFilter.addDataScheme("package");
3848 mContext.registerReceiver(new BroadcastReceiver() {
3849 @Override
3850 public void onReceive(Context context, Intent intent) {
3851 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3852 if (pkgs != null) {
3853 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003854 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003855 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003856 setResultCode(Activity.RESULT_OK);
3857 return;
3858 }
3859 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003860 }
3861 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003862 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003863 }, pkgFilter);
3864
3865 synchronized (this) {
3866 // Ensure that any processes we had put on hold are now started
3867 // up.
3868 final int NP = mProcessesOnHold.size();
3869 if (NP > 0) {
3870 ArrayList<ProcessRecord> procs =
3871 new ArrayList<ProcessRecord>(mProcessesOnHold);
3872 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003873 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3874 + procs.get(ip));
3875 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003876 }
3877 }
3878
3879 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003880 // Start looking for apps that are abusing wake locks.
3881 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003882 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003883 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003884 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003885 broadcastIntentLocked(null, null,
3886 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3887 null, null, 0, null, null,
3888 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3889 false, false, MY_PID, Process.SYSTEM_UID);
3890 }
3891 }
3892 }
3893
3894 final void ensureBootCompleted() {
3895 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003896 boolean enableScreen;
3897 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003898 booting = mBooting;
3899 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003900 enableScreen = !mBooted;
3901 mBooted = true;
3902 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003903
3904 if (booting) {
3905 finishBooting();
3906 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003907
3908 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003909 enableScreenAfterBoot();
3910 }
3911 }
3912
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003913 public final void activityPaused(IBinder token) {
3914 final long origId = Binder.clearCallingIdentity();
3915 mMainStack.activityPaused(token, false);
3916 Binder.restoreCallingIdentity(origId);
3917 }
3918
3919 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3920 CharSequence description) {
3921 if (localLOGV) Slog.v(
3922 TAG, "Activity stopped: token=" + token);
3923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924 // Refuse possible leaked file descriptors
3925 if (icicle != null && icicle.hasFileDescriptors()) {
3926 throw new IllegalArgumentException("File descriptors passed in Bundle");
3927 }
3928
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003929 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930
3931 final long origId = Binder.clearCallingIdentity();
3932
3933 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003934 r = mMainStack.isInStackLocked(token);
3935 if (r != null) {
3936 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 }
3938 }
3939
3940 if (r != null) {
3941 sendPendingThumbnail(r, null, null, null, false);
3942 }
3943
3944 trimApplications();
3945
3946 Binder.restoreCallingIdentity(origId);
3947 }
3948
3949 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003950 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003951 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 }
3953
3954 public String getCallingPackage(IBinder token) {
3955 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003956 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003957 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959 }
3960
3961 public ComponentName getCallingActivity(IBinder token) {
3962 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003963 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 return r != null ? r.intent.getComponent() : null;
3965 }
3966 }
3967
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003968 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003969 ActivityRecord r = mMainStack.isInStackLocked(token);
3970 if (r == null) {
3971 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003973 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003974 }
3975
3976 public ComponentName getActivityClassForToken(IBinder token) {
3977 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003978 ActivityRecord r = mMainStack.isInStackLocked(token);
3979 if (r == null) {
3980 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003982 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003983 }
3984 }
3985
3986 public String getPackageForToken(IBinder token) {
3987 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003988 ActivityRecord r = mMainStack.isInStackLocked(token);
3989 if (r == null) {
3990 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003992 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 }
3994 }
3995
3996 public IIntentSender getIntentSender(int type,
3997 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003998 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003999 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004000 if (intents != null) {
4001 if (intents.length < 1) {
4002 throw new IllegalArgumentException("Intents array length must be >= 1");
4003 }
4004 for (int i=0; i<intents.length; i++) {
4005 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004006 if (intent != null) {
4007 if (intent.hasFileDescriptors()) {
4008 throw new IllegalArgumentException("File descriptors passed in Intent");
4009 }
4010 if (type == INTENT_SENDER_BROADCAST &&
4011 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4012 throw new IllegalArgumentException(
4013 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4014 }
4015 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004016 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004017 }
4018 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004019 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004020 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004021 }
4022 }
4023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 synchronized(this) {
4025 int callingUid = Binder.getCallingUid();
4026 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004027 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004028 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004029 .getPackageUid(packageName);
4030 if (uid != Binder.getCallingUid()) {
4031 String msg = "Permission Denial: getIntentSender() from pid="
4032 + Binder.getCallingPid()
4033 + ", uid=" + Binder.getCallingUid()
4034 + ", (need uid=" + uid + ")"
4035 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004036 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004037 throw new SecurityException(msg);
4038 }
4039 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004040
4041 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004042 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004044 } catch (RemoteException e) {
4045 throw new SecurityException(e);
4046 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004047 }
4048 }
4049
4050 IIntentSender getIntentSenderLocked(int type,
4051 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004052 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004053 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004054 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004055 activity = mMainStack.isInStackLocked(token);
4056 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004057 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004059 if (activity.finishing) {
4060 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004061 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004062 }
4063
4064 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4065 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4066 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4067 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4068 |PendingIntent.FLAG_UPDATE_CURRENT);
4069
4070 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4071 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004072 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004073 WeakReference<PendingIntentRecord> ref;
4074 ref = mIntentSenderRecords.get(key);
4075 PendingIntentRecord rec = ref != null ? ref.get() : null;
4076 if (rec != null) {
4077 if (!cancelCurrent) {
4078 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004079 if (rec.key.requestIntent != null) {
4080 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4081 }
4082 if (intents != null) {
4083 intents[intents.length-1] = rec.key.requestIntent;
4084 rec.key.allIntents = intents;
4085 rec.key.allResolvedTypes = resolvedTypes;
4086 } else {
4087 rec.key.allIntents = null;
4088 rec.key.allResolvedTypes = null;
4089 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 return rec;
4092 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004093 rec.canceled = true;
4094 mIntentSenderRecords.remove(key);
4095 }
4096 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 return rec;
4098 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004099 rec = new PendingIntentRecord(this, key, callingUid);
4100 mIntentSenderRecords.put(key, rec.ref);
4101 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4102 if (activity.pendingResults == null) {
4103 activity.pendingResults
4104 = new HashSet<WeakReference<PendingIntentRecord>>();
4105 }
4106 activity.pendingResults.add(rec.ref);
4107 }
4108 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004109 }
4110
4111 public void cancelIntentSender(IIntentSender sender) {
4112 if (!(sender instanceof PendingIntentRecord)) {
4113 return;
4114 }
4115 synchronized(this) {
4116 PendingIntentRecord rec = (PendingIntentRecord)sender;
4117 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004118 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 .getPackageUid(rec.key.packageName);
4120 if (uid != Binder.getCallingUid()) {
4121 String msg = "Permission Denial: cancelIntentSender() from pid="
4122 + Binder.getCallingPid()
4123 + ", uid=" + Binder.getCallingUid()
4124 + " is not allowed to cancel packges "
4125 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004126 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 throw new SecurityException(msg);
4128 }
4129 } catch (RemoteException e) {
4130 throw new SecurityException(e);
4131 }
4132 cancelIntentSenderLocked(rec, true);
4133 }
4134 }
4135
4136 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4137 rec.canceled = true;
4138 mIntentSenderRecords.remove(rec.key);
4139 if (cleanActivity && rec.key.activity != null) {
4140 rec.key.activity.pendingResults.remove(rec.ref);
4141 }
4142 }
4143
4144 public String getPackageForIntentSender(IIntentSender pendingResult) {
4145 if (!(pendingResult instanceof PendingIntentRecord)) {
4146 return null;
4147 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004148 try {
4149 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4150 return res.key.packageName;
4151 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 }
4153 return null;
4154 }
4155
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004156 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4157 if (!(pendingResult instanceof PendingIntentRecord)) {
4158 return false;
4159 }
4160 try {
4161 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4162 if (res.key.allIntents == null) {
4163 return false;
4164 }
4165 for (int i=0; i<res.key.allIntents.length; i++) {
4166 Intent intent = res.key.allIntents[i];
4167 if (intent.getPackage() != null && intent.getComponent() != null) {
4168 return false;
4169 }
4170 }
4171 return true;
4172 } catch (ClassCastException e) {
4173 }
4174 return false;
4175 }
4176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004177 public void setProcessLimit(int max) {
4178 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4179 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004180 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004181 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004182 mProcessLimitOverride = max;
4183 }
4184 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 }
4186
4187 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004188 synchronized (this) {
4189 return mProcessLimitOverride;
4190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 }
4192
4193 void foregroundTokenDied(ForegroundToken token) {
4194 synchronized (ActivityManagerService.this) {
4195 synchronized (mPidsSelfLocked) {
4196 ForegroundToken cur
4197 = mForegroundProcesses.get(token.pid);
4198 if (cur != token) {
4199 return;
4200 }
4201 mForegroundProcesses.remove(token.pid);
4202 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4203 if (pr == null) {
4204 return;
4205 }
4206 pr.forcingToForeground = null;
4207 pr.foregroundServices = false;
4208 }
4209 updateOomAdjLocked();
4210 }
4211 }
4212
4213 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4214 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4215 "setProcessForeground()");
4216 synchronized(this) {
4217 boolean changed = false;
4218
4219 synchronized (mPidsSelfLocked) {
4220 ProcessRecord pr = mPidsSelfLocked.get(pid);
4221 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004222 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 return;
4224 }
4225 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4226 if (oldToken != null) {
4227 oldToken.token.unlinkToDeath(oldToken, 0);
4228 mForegroundProcesses.remove(pid);
4229 pr.forcingToForeground = null;
4230 changed = true;
4231 }
4232 if (isForeground && token != null) {
4233 ForegroundToken newToken = new ForegroundToken() {
4234 public void binderDied() {
4235 foregroundTokenDied(this);
4236 }
4237 };
4238 newToken.pid = pid;
4239 newToken.token = token;
4240 try {
4241 token.linkToDeath(newToken, 0);
4242 mForegroundProcesses.put(pid, newToken);
4243 pr.forcingToForeground = token;
4244 changed = true;
4245 } catch (RemoteException e) {
4246 // If the process died while doing this, we will later
4247 // do the cleanup with the process death link.
4248 }
4249 }
4250 }
4251
4252 if (changed) {
4253 updateOomAdjLocked();
4254 }
4255 }
4256 }
4257
4258 // =========================================================
4259 // PERMISSIONS
4260 // =========================================================
4261
4262 static class PermissionController extends IPermissionController.Stub {
4263 ActivityManagerService mActivityManagerService;
4264 PermissionController(ActivityManagerService activityManagerService) {
4265 mActivityManagerService = activityManagerService;
4266 }
4267
4268 public boolean checkPermission(String permission, int pid, int uid) {
4269 return mActivityManagerService.checkPermission(permission, pid,
4270 uid) == PackageManager.PERMISSION_GRANTED;
4271 }
4272 }
4273
4274 /**
4275 * This can be called with or without the global lock held.
4276 */
4277 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004278 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 // We might be performing an operation on behalf of an indirect binder
4280 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4281 // client identity accordingly before proceeding.
4282 Identity tlsIdentity = sCallerIdentity.get();
4283 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004284 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004285 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4286 uid = tlsIdentity.uid;
4287 pid = tlsIdentity.pid;
4288 }
4289
4290 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004291 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 return PackageManager.PERMISSION_GRANTED;
4293 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004294 // If there is a uid that owns whatever is being accessed, it has
4295 // blanket access to it regardless of the permissions it requires.
4296 if (owningUid >= 0 && uid == owningUid) {
4297 return PackageManager.PERMISSION_GRANTED;
4298 }
4299 // If the target is not exported, then nobody else can get to it.
4300 if (!exported) {
4301 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 return PackageManager.PERMISSION_DENIED;
4303 }
4304 if (permission == null) {
4305 return PackageManager.PERMISSION_GRANTED;
4306 }
4307 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004308 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004309 .checkUidPermission(permission, uid);
4310 } catch (RemoteException e) {
4311 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004312 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 }
4314 return PackageManager.PERMISSION_DENIED;
4315 }
4316
4317 /**
4318 * As the only public entry point for permissions checking, this method
4319 * can enforce the semantic that requesting a check on a null global
4320 * permission is automatically denied. (Internally a null permission
4321 * string is used when calling {@link #checkComponentPermission} in cases
4322 * when only uid-based security is needed.)
4323 *
4324 * This can be called with or without the global lock held.
4325 */
4326 public int checkPermission(String permission, int pid, int uid) {
4327 if (permission == null) {
4328 return PackageManager.PERMISSION_DENIED;
4329 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004330 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 }
4332
4333 /**
4334 * Binder IPC calls go through the public entry point.
4335 * This can be called with or without the global lock held.
4336 */
4337 int checkCallingPermission(String permission) {
4338 return checkPermission(permission,
4339 Binder.getCallingPid(),
4340 Binder.getCallingUid());
4341 }
4342
4343 /**
4344 * This can be called with or without the global lock held.
4345 */
4346 void enforceCallingPermission(String permission, String func) {
4347 if (checkCallingPermission(permission)
4348 == PackageManager.PERMISSION_GRANTED) {
4349 return;
4350 }
4351
4352 String msg = "Permission Denial: " + func + " from pid="
4353 + Binder.getCallingPid()
4354 + ", uid=" + Binder.getCallingUid()
4355 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004356 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 throw new SecurityException(msg);
4358 }
4359
4360 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004361 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4362 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4363 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4364 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4365 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004367 // Is the component private from the target uid?
4368 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4369
4370 // Acceptable if the there is no read permission needed from the
4371 // target or the target is holding the read permission.
4372 if (!readPerm) {
4373 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004375 == PackageManager.PERMISSION_GRANTED)) {
4376 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 }
4378 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004379
4380 // Acceptable if the there is no write permission needed from the
4381 // target or the target is holding the read permission.
4382 if (!writePerm) {
4383 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004385 == PackageManager.PERMISSION_GRANTED)) {
4386 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 }
4388 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004389
4390 // Acceptable if there is a path permission matching the URI that
4391 // the target holds the permission on.
4392 PathPermission[] pps = pi.pathPermissions;
4393 if (pps != null && (!readPerm || !writePerm)) {
4394 final String path = uri.getPath();
4395 int i = pps.length;
4396 while (i > 0 && (!readPerm || !writePerm)) {
4397 i--;
4398 PathPermission pp = pps[i];
4399 if (!readPerm) {
4400 final String pprperm = pp.getReadPermission();
4401 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4402 + pprperm + " for " + pp.getPath()
4403 + ": match=" + pp.match(path)
4404 + " check=" + pm.checkUidPermission(pprperm, uid));
4405 if (pprperm != null && pp.match(path) &&
4406 (pm.checkUidPermission(pprperm, uid)
4407 == PackageManager.PERMISSION_GRANTED)) {
4408 readPerm = true;
4409 }
4410 }
4411 if (!writePerm) {
4412 final String ppwperm = pp.getWritePermission();
4413 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4414 + ppwperm + " for " + pp.getPath()
4415 + ": match=" + pp.match(path)
4416 + " check=" + pm.checkUidPermission(ppwperm, uid));
4417 if (ppwperm != null && pp.match(path) &&
4418 (pm.checkUidPermission(ppwperm, uid)
4419 == PackageManager.PERMISSION_GRANTED)) {
4420 writePerm = true;
4421 }
4422 }
4423 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004424 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 } catch (RemoteException e) {
4426 return false;
4427 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004428
4429 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 }
4431
4432 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4433 int modeFlags) {
4434 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004435 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 return true;
4437 }
4438 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4439 if (perms == null) return false;
4440 UriPermission perm = perms.get(uri);
4441 if (perm == null) return false;
4442 return (modeFlags&perm.modeFlags) == modeFlags;
4443 }
4444
4445 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4446 // Another redirected-binder-call permissions check as in
4447 // {@link checkComponentPermission}.
4448 Identity tlsIdentity = sCallerIdentity.get();
4449 if (tlsIdentity != null) {
4450 uid = tlsIdentity.uid;
4451 pid = tlsIdentity.pid;
4452 }
4453
4454 // Our own process gets to do everything.
4455 if (pid == MY_PID) {
4456 return PackageManager.PERMISSION_GRANTED;
4457 }
4458 synchronized(this) {
4459 return checkUriPermissionLocked(uri, uid, modeFlags)
4460 ? PackageManager.PERMISSION_GRANTED
4461 : PackageManager.PERMISSION_DENIED;
4462 }
4463 }
4464
Dianne Hackborn39792d22010-08-19 18:01:52 -07004465 /**
4466 * Check if the targetPkg can be granted permission to access uri by
4467 * the callingUid using the given modeFlags. Throws a security exception
4468 * if callingUid is not allowed to do this. Returns the uid of the target
4469 * if the URI permission grant should be performed; returns -1 if it is not
4470 * needed (for example targetPkg already has permission to access the URI).
4471 */
4472 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4473 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4475 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4476 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004477 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 }
4479
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004480 if (targetPkg != null) {
4481 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4482 "Checking grant " + targetPkg + " permission to " + uri);
4483 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004484
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004485 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486
4487 // If this is not a content: uri, we can't do anything with it.
4488 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004489 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004490 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004491 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 }
4493
4494 String name = uri.getAuthority();
4495 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004496 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 if (cpr != null) {
4498 pi = cpr.info;
4499 } else {
4500 try {
4501 pi = pm.resolveContentProvider(name,
4502 PackageManager.GET_URI_PERMISSION_PATTERNS);
4503 } catch (RemoteException ex) {
4504 }
4505 }
4506 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004507 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004508 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 }
4510
4511 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004512 if (targetPkg != null) {
4513 try {
4514 targetUid = pm.getPackageUid(targetPkg);
4515 if (targetUid < 0) {
4516 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4517 "Can't grant URI permission no uid for: " + targetPkg);
4518 return -1;
4519 }
4520 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004521 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004522 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004523 } else {
4524 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 }
4526
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004527 if (targetUid >= 0) {
4528 // First... does the target actually need this permission?
4529 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4530 // No need to grant the target this permission.
4531 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4532 "Target " + targetPkg + " already has full permission to " + uri);
4533 return -1;
4534 }
4535 } else {
4536 // First... there is no target package, so can anyone access it?
4537 boolean allowed = pi.exported;
4538 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4539 if (pi.readPermission != null) {
4540 allowed = false;
4541 }
4542 }
4543 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4544 if (pi.writePermission != null) {
4545 allowed = false;
4546 }
4547 }
4548 if (allowed) {
4549 return -1;
4550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 }
4552
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004553 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 if (!pi.grantUriPermissions) {
4555 throw new SecurityException("Provider " + pi.packageName
4556 + "/" + pi.name
4557 + " does not allow granting of Uri permissions (uri "
4558 + uri + ")");
4559 }
4560 if (pi.uriPermissionPatterns != null) {
4561 final int N = pi.uriPermissionPatterns.length;
4562 boolean allowed = false;
4563 for (int i=0; i<N; i++) {
4564 if (pi.uriPermissionPatterns[i] != null
4565 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4566 allowed = true;
4567 break;
4568 }
4569 }
4570 if (!allowed) {
4571 throw new SecurityException("Provider " + pi.packageName
4572 + "/" + pi.name
4573 + " does not allow granting of permission to path of Uri "
4574 + uri);
4575 }
4576 }
4577
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004578 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004580 if (callingUid != Process.myUid()) {
4581 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4582 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4583 throw new SecurityException("Uid " + callingUid
4584 + " does not have permission to uri " + uri);
4585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 }
4587 }
4588
Dianne Hackborn39792d22010-08-19 18:01:52 -07004589 return targetUid;
4590 }
4591
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004592 public int checkGrantUriPermission(int callingUid, String targetPkg,
4593 Uri uri, int modeFlags) {
4594 synchronized(this) {
4595 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4596 }
4597 }
4598
Dianne Hackborn39792d22010-08-19 18:01:52 -07004599 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4600 Uri uri, int modeFlags, UriPermissionOwner owner) {
4601 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4602 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4603 if (modeFlags == 0) {
4604 return;
4605 }
4606
4607 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004608 // to the uri, and the target doesn't. Let's now give this to
4609 // the target.
4610
Joe Onorato8a9b2202010-02-26 18:56:32 -08004611 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004612 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 HashMap<Uri, UriPermission> targetUris
4615 = mGrantedUriPermissions.get(targetUid);
4616 if (targetUris == null) {
4617 targetUris = new HashMap<Uri, UriPermission>();
4618 mGrantedUriPermissions.put(targetUid, targetUris);
4619 }
4620
4621 UriPermission perm = targetUris.get(uri);
4622 if (perm == null) {
4623 perm = new UriPermission(targetUid, uri);
4624 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004628 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004630 } else {
4631 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4632 perm.readOwners.add(owner);
4633 owner.addReadPermission(perm);
4634 }
4635 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4636 perm.writeOwners.add(owner);
4637 owner.addWritePermission(perm);
4638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 }
4640 }
4641
Dianne Hackborn39792d22010-08-19 18:01:52 -07004642 void grantUriPermissionLocked(int callingUid,
4643 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004644 if (targetPkg == null) {
4645 throw new NullPointerException("targetPkg");
4646 }
4647
Dianne Hackborn39792d22010-08-19 18:01:52 -07004648 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4649 if (targetUid < 0) {
4650 return;
4651 }
4652
4653 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4654 }
4655
4656 /**
4657 * Like checkGrantUriPermissionLocked, but takes an Intent.
4658 */
4659 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4660 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004661 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004662 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004663 + " from " + intent + "; flags=0x"
4664 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4665
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004666 if (targetPkg == null) {
4667 throw new NullPointerException("targetPkg");
4668 }
4669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004671 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004672 }
4673 Uri data = intent.getData();
4674 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004675 return -1;
4676 }
4677 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4678 intent.getFlags());
4679 }
4680
4681 /**
4682 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4683 */
4684 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4685 String targetPkg, Intent intent, UriPermissionOwner owner) {
4686 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4687 intent.getFlags(), owner);
4688 }
4689
4690 void grantUriPermissionFromIntentLocked(int callingUid,
4691 String targetPkg, Intent intent, UriPermissionOwner owner) {
4692 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4693 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 return;
4695 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004696
4697 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004698 }
4699
4700 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4701 Uri uri, int modeFlags) {
4702 synchronized(this) {
4703 final ProcessRecord r = getRecordForAppLocked(caller);
4704 if (r == null) {
4705 throw new SecurityException("Unable to find app for caller "
4706 + caller
4707 + " when granting permission to uri " + uri);
4708 }
4709 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004710 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 }
4712 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004713 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004714 }
4715
4716 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4717 null);
4718 }
4719 }
4720
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004721 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004722 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4723 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4724 HashMap<Uri, UriPermission> perms
4725 = mGrantedUriPermissions.get(perm.uid);
4726 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004727 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004728 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 perms.remove(perm.uri);
4730 if (perms.size() == 0) {
4731 mGrantedUriPermissions.remove(perm.uid);
4732 }
4733 }
4734 }
4735 }
4736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4738 int modeFlags) {
4739 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4740 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4741 if (modeFlags == 0) {
4742 return;
4743 }
4744
Joe Onorato8a9b2202010-02-26 18:56:32 -08004745 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004746 "Revoking all granted permissions to " + uri);
4747
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004748 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749
4750 final String authority = uri.getAuthority();
4751 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004752 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 if (cpr != null) {
4754 pi = cpr.info;
4755 } else {
4756 try {
4757 pi = pm.resolveContentProvider(authority,
4758 PackageManager.GET_URI_PERMISSION_PATTERNS);
4759 } catch (RemoteException ex) {
4760 }
4761 }
4762 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004763 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 return;
4765 }
4766
4767 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004768 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 // Right now, if you are not the original owner of the permission,
4770 // you are not allowed to revoke it.
4771 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4772 throw new SecurityException("Uid " + callingUid
4773 + " does not have permission to uri " + uri);
4774 //}
4775 }
4776
4777 // Go through all of the permissions and remove any that match.
4778 final List<String> SEGMENTS = uri.getPathSegments();
4779 if (SEGMENTS != null) {
4780 final int NS = SEGMENTS.size();
4781 int N = mGrantedUriPermissions.size();
4782 for (int i=0; i<N; i++) {
4783 HashMap<Uri, UriPermission> perms
4784 = mGrantedUriPermissions.valueAt(i);
4785 Iterator<UriPermission> it = perms.values().iterator();
4786 toploop:
4787 while (it.hasNext()) {
4788 UriPermission perm = it.next();
4789 Uri targetUri = perm.uri;
4790 if (!authority.equals(targetUri.getAuthority())) {
4791 continue;
4792 }
4793 List<String> targetSegments = targetUri.getPathSegments();
4794 if (targetSegments == null) {
4795 continue;
4796 }
4797 if (targetSegments.size() < NS) {
4798 continue;
4799 }
4800 for (int j=0; j<NS; j++) {
4801 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4802 continue toploop;
4803 }
4804 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004805 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004806 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 perm.clearModes(modeFlags);
4808 if (perm.modeFlags == 0) {
4809 it.remove();
4810 }
4811 }
4812 if (perms.size() == 0) {
4813 mGrantedUriPermissions.remove(
4814 mGrantedUriPermissions.keyAt(i));
4815 N--;
4816 i--;
4817 }
4818 }
4819 }
4820 }
4821
4822 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4823 int modeFlags) {
4824 synchronized(this) {
4825 final ProcessRecord r = getRecordForAppLocked(caller);
4826 if (r == null) {
4827 throw new SecurityException("Unable to find app for caller "
4828 + caller
4829 + " when revoking permission to uri " + uri);
4830 }
4831 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004832 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004833 return;
4834 }
4835
4836 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4837 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4838 if (modeFlags == 0) {
4839 return;
4840 }
4841
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004842 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843
4844 final String authority = uri.getAuthority();
4845 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004846 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 if (cpr != null) {
4848 pi = cpr.info;
4849 } else {
4850 try {
4851 pi = pm.resolveContentProvider(authority,
4852 PackageManager.GET_URI_PERMISSION_PATTERNS);
4853 } catch (RemoteException ex) {
4854 }
4855 }
4856 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004857 Slog.w(TAG, "No content provider found for permission revoke: "
4858 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004859 return;
4860 }
4861
4862 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4863 }
4864 }
4865
Dianne Hackborn7e269642010-08-25 19:50:20 -07004866 @Override
4867 public IBinder newUriPermissionOwner(String name) {
4868 synchronized(this) {
4869 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4870 return owner.getExternalTokenLocked();
4871 }
4872 }
4873
4874 @Override
4875 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4876 Uri uri, int modeFlags) {
4877 synchronized(this) {
4878 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4879 if (owner == null) {
4880 throw new IllegalArgumentException("Unknown owner: " + token);
4881 }
4882 if (fromUid != Binder.getCallingUid()) {
4883 if (Binder.getCallingUid() != Process.myUid()) {
4884 // Only system code can grant URI permissions on behalf
4885 // of other users.
4886 throw new SecurityException("nice try");
4887 }
4888 }
4889 if (targetPkg == null) {
4890 throw new IllegalArgumentException("null target");
4891 }
4892 if (uri == null) {
4893 throw new IllegalArgumentException("null uri");
4894 }
4895
4896 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4897 }
4898 }
4899
4900 @Override
4901 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4902 synchronized(this) {
4903 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4904 if (owner == null) {
4905 throw new IllegalArgumentException("Unknown owner: " + token);
4906 }
4907
4908 if (uri == null) {
4909 owner.removeUriPermissionsLocked(mode);
4910 } else {
4911 owner.removeUriPermissionLocked(uri, mode);
4912 }
4913 }
4914 }
4915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4917 synchronized (this) {
4918 ProcessRecord app =
4919 who != null ? getRecordForAppLocked(who) : null;
4920 if (app == null) return;
4921
4922 Message msg = Message.obtain();
4923 msg.what = WAIT_FOR_DEBUGGER_MSG;
4924 msg.obj = app;
4925 msg.arg1 = waiting ? 1 : 0;
4926 mHandler.sendMessage(msg);
4927 }
4928 }
4929
4930 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004931 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4932 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004934 outInfo.threshold = homeAppMem;
4935 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4936 outInfo.hiddenAppThreshold = hiddenAppMem;
4937 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07004938 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07004939 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4940 ProcessList.VISIBLE_APP_ADJ);
4941 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4942 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 }
4944
4945 // =========================================================
4946 // TASK MANAGEMENT
4947 // =========================================================
4948
4949 public List getTasks(int maxNum, int flags,
4950 IThumbnailReceiver receiver) {
4951 ArrayList list = new ArrayList();
4952
4953 PendingThumbnailsRecord pending = null;
4954 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004955 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956
4957 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004958 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4960 + ", receiver=" + receiver);
4961
4962 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4963 != PackageManager.PERMISSION_GRANTED) {
4964 if (receiver != null) {
4965 // If the caller wants to wait for pending thumbnails,
4966 // it ain't gonna get them.
4967 try {
4968 receiver.finished();
4969 } catch (RemoteException ex) {
4970 }
4971 }
4972 String msg = "Permission Denial: getTasks() from pid="
4973 + Binder.getCallingPid()
4974 + ", uid=" + Binder.getCallingUid()
4975 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004976 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004977 throw new SecurityException(msg);
4978 }
4979
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004980 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004981 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004982 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004983 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004984 TaskRecord curTask = null;
4985 int numActivities = 0;
4986 int numRunning = 0;
4987 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004988 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004989 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004990 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004991
4992 // Initialize state for next task if needed.
4993 if (top == null ||
4994 (top.state == ActivityState.INITIALIZING
4995 && top.task == r.task)) {
4996 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004997 curTask = r.task;
4998 numActivities = numRunning = 0;
4999 }
5000
5001 // Add 'r' into the current task.
5002 numActivities++;
5003 if (r.app != null && r.app.thread != null) {
5004 numRunning++;
5005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005006
Joe Onorato8a9b2202010-02-26 18:56:32 -08005007 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 TAG, r.intent.getComponent().flattenToShortString()
5009 + ": task=" + r.task);
5010
5011 // If the next one is a different task, generate a new
5012 // TaskInfo entry for what we have.
5013 if (next == null || next.task != curTask) {
5014 ActivityManager.RunningTaskInfo ci
5015 = new ActivityManager.RunningTaskInfo();
5016 ci.id = curTask.taskId;
5017 ci.baseActivity = r.intent.getComponent();
5018 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005019 if (top.thumbHolder != null) {
5020 ci.description = top.thumbHolder.lastDescription;
5021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005022 ci.numActivities = numActivities;
5023 ci.numRunning = numRunning;
5024 //System.out.println(
5025 // "#" + maxNum + ": " + " descr=" + ci.description);
5026 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005027 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005028 TAG, "State=" + top.state + "Idle=" + top.idle
5029 + " app=" + top.app
5030 + " thr=" + (top.app != null ? top.app.thread : null));
5031 if (top.state == ActivityState.RESUMED
5032 || top.state == ActivityState.PAUSING) {
5033 if (top.idle && top.app != null
5034 && top.app.thread != null) {
5035 topRecord = top;
5036 topThumbnail = top.app.thread;
5037 } else {
5038 top.thumbnailNeeded = true;
5039 }
5040 }
5041 if (pending == null) {
5042 pending = new PendingThumbnailsRecord(receiver);
5043 }
5044 pending.pendingRecords.add(top);
5045 }
5046 list.add(ci);
5047 maxNum--;
5048 top = null;
5049 }
5050 }
5051
5052 if (pending != null) {
5053 mPendingThumbnails.add(pending);
5054 }
5055 }
5056
Joe Onorato8a9b2202010-02-26 18:56:32 -08005057 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058
5059 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005060 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005061 try {
5062 topThumbnail.requestThumbnail(topRecord);
5063 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005064 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 sendPendingThumbnail(null, topRecord, null, null, true);
5066 }
5067 }
5068
5069 if (pending == null && receiver != null) {
5070 // In this case all thumbnails were available and the client
5071 // is being asked to be told when the remaining ones come in...
5072 // which is unusually, since the top-most currently running
5073 // activity should never have a canned thumbnail! Oh well.
5074 try {
5075 receiver.finished();
5076 } catch (RemoteException ex) {
5077 }
5078 }
5079
5080 return list;
5081 }
5082
5083 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5084 int flags) {
5085 synchronized (this) {
5086 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5087 "getRecentTasks()");
5088
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005089 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 final int N = mRecentTasks.size();
5092 ArrayList<ActivityManager.RecentTaskInfo> res
5093 = new ArrayList<ActivityManager.RecentTaskInfo>(
5094 maxNum < N ? maxNum : N);
5095 for (int i=0; i<N && maxNum > 0; i++) {
5096 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005097 // Return the entry if desired by the caller. We always return
5098 // the first entry, because callers always expect this to be the
5099 // forground app. We may filter others if the caller has
5100 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5101 // we should exclude the entry.
5102 if (i == 0
5103 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005104 || (tr.intent == null)
5105 || ((tr.intent.getFlags()
5106 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5107 ActivityManager.RecentTaskInfo rti
5108 = new ActivityManager.RecentTaskInfo();
5109 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005110 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005111 rti.baseIntent = new Intent(
5112 tr.intent != null ? tr.intent : tr.affinityIntent);
5113 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005114 rti.description = tr.lastDescription;
5115
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005116 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5117 // Check whether this activity is currently available.
5118 try {
5119 if (rti.origActivity != null) {
5120 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5121 continue;
5122 }
5123 } else if (rti.baseIntent != null) {
5124 if (pm.queryIntentActivities(rti.baseIntent,
5125 null, 0) == null) {
5126 continue;
5127 }
5128 }
5129 } catch (RemoteException e) {
5130 // Will never happen.
5131 }
5132 }
5133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134 res.add(rti);
5135 maxNum--;
5136 }
5137 }
5138 return res;
5139 }
5140 }
5141
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005142 private TaskRecord taskForIdLocked(int id) {
5143 final int N = mRecentTasks.size();
5144 for (int i=0; i<N; i++) {
5145 TaskRecord tr = mRecentTasks.get(i);
5146 if (tr.taskId == id) {
5147 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005148 }
5149 }
5150 return null;
5151 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005152
5153 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5154 synchronized (this) {
5155 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5156 "getTaskThumbnails()");
5157 TaskRecord tr = taskForIdLocked(id);
5158 if (tr != null) {
5159 return mMainStack.getTaskThumbnailsLocked(tr);
5160 }
5161 }
5162 return null;
5163 }
5164
5165 public boolean removeSubTask(int taskId, int subTaskIndex) {
5166 synchronized (this) {
5167 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5168 "removeSubTask()");
5169 long ident = Binder.clearCallingIdentity();
5170 try {
5171 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5172 } finally {
5173 Binder.restoreCallingIdentity(ident);
5174 }
5175 }
5176 }
5177
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005178 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005179 TaskRecord tr = root.task;
5180 Intent baseIntent = new Intent(
5181 tr.intent != null ? tr.intent : tr.affinityIntent);
5182 ComponentName component = baseIntent.getComponent();
5183 if (component == null) {
5184 Slog.w(TAG, "Now component for base intent of task: " + tr);
5185 return;
5186 }
5187
5188 // Find any running services associated with this app.
5189 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5190 for (ServiceRecord sr : mServices.values()) {
5191 if (sr.packageName.equals(component.getPackageName())) {
5192 services.add(sr);
5193 }
5194 }
5195
5196 // Take care of any running services associated with the app.
5197 for (int i=0; i<services.size(); i++) {
5198 ServiceRecord sr = services.get(i);
5199 if (sr.startRequested) {
5200 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005201 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005202 stopServiceLocked(sr);
5203 } else {
5204 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5205 sr.makeNextStartId(), baseIntent, -1));
5206 if (sr.app != null && sr.app.thread != null) {
5207 sendServiceArgsLocked(sr, false);
5208 }
5209 }
5210 }
5211 }
5212
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005213 if (killProcesses) {
5214 // Find any running processes associated with this app.
5215 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5216 SparseArray<ProcessRecord> appProcs
5217 = mProcessNames.getMap().get(component.getPackageName());
5218 if (appProcs != null) {
5219 for (int i=0; i<appProcs.size(); i++) {
5220 procs.add(appProcs.valueAt(i));
5221 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005222 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005223
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005224 // Kill the running processes.
5225 for (int i=0; i<procs.size(); i++) {
5226 ProcessRecord pr = procs.get(i);
5227 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5228 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5229 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5230 pr.processName, pr.setAdj, "remove task");
5231 Process.killProcessQuiet(pr.pid);
5232 } else {
5233 pr.waitingToKill = "remove task";
5234 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005235 }
5236 }
5237 }
5238
5239 public boolean removeTask(int taskId, int flags) {
5240 synchronized (this) {
5241 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5242 "removeTask()");
5243 long ident = Binder.clearCallingIdentity();
5244 try {
5245 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5246 if (r != null) {
5247 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005248 cleanUpRemovedTaskLocked(r,
5249 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005250 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005251 } else {
5252 TaskRecord tr = null;
5253 int i=0;
5254 while (i < mRecentTasks.size()) {
5255 TaskRecord t = mRecentTasks.get(i);
5256 if (t.taskId == taskId) {
5257 tr = t;
5258 break;
5259 }
5260 i++;
5261 }
5262 if (tr != null) {
5263 if (tr.numActivities <= 0) {
5264 // Caller is just removing a recent task that is
5265 // not actively running. That is easy!
5266 mRecentTasks.remove(i);
5267 } else {
5268 Slog.w(TAG, "removeTask: task " + taskId
5269 + " does not have activities to remove, "
5270 + " but numActivities=" + tr.numActivities
5271 + ": " + tr);
5272 }
5273 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005274 }
5275 } finally {
5276 Binder.restoreCallingIdentity(ident);
5277 }
5278 }
5279 return false;
5280 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5283 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005284 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 TaskRecord jt = startTask;
5286
5287 // First look backwards
5288 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005289 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 if (r.task != jt) {
5291 jt = r.task;
5292 if (affinity.equals(jt.affinity)) {
5293 return j;
5294 }
5295 }
5296 }
5297
5298 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005299 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005300 jt = startTask;
5301 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005302 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005303 if (r.task != jt) {
5304 if (affinity.equals(jt.affinity)) {
5305 return j;
5306 }
5307 jt = r.task;
5308 }
5309 }
5310
5311 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005312 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005313 return N-1;
5314 }
5315
5316 return -1;
5317 }
5318
5319 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005320 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005322 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5324 "moveTaskToFront()");
5325
5326 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005327 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5328 Binder.getCallingUid(), "Task to front")) {
5329 return;
5330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 final long origId = Binder.clearCallingIdentity();
5332 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005333 TaskRecord tr = taskForIdLocked(task);
5334 if (tr != null) {
5335 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5336 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005338 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5339 // Caller wants the home activity moved with it. To accomplish this,
5340 // we'll just move the home task to the top first.
5341 mMainStack.moveHomeToFrontLocked();
5342 }
5343 mMainStack.moveTaskToFrontLocked(tr, null);
5344 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005346 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5347 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005349 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5350 mMainStack.mUserLeaving = true;
5351 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005352 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5353 // Caller wants the home activity moved with it. To accomplish this,
5354 // we'll just move the home task to the top first.
5355 mMainStack.moveHomeToFrontLocked();
5356 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005357 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005358 return;
5359 }
5360 }
5361 } finally {
5362 Binder.restoreCallingIdentity(origId);
5363 }
5364 }
5365 }
5366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005367 public void moveTaskToBack(int task) {
5368 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5369 "moveTaskToBack()");
5370
5371 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005372 if (mMainStack.mResumedActivity != null
5373 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005374 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5375 Binder.getCallingUid(), "Task to back")) {
5376 return;
5377 }
5378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005379 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005380 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 Binder.restoreCallingIdentity(origId);
5382 }
5383 }
5384
5385 /**
5386 * Moves an activity, and all of the other activities within the same task, to the bottom
5387 * of the history stack. The activity's order within the task is unchanged.
5388 *
5389 * @param token A reference to the activity we wish to move
5390 * @param nonRoot If false then this only works if the activity is the root
5391 * of a task; if true it will work for any activity in a task.
5392 * @return Returns true if the move completed, false if not.
5393 */
5394 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5395 synchronized(this) {
5396 final long origId = Binder.clearCallingIdentity();
5397 int taskId = getTaskForActivityLocked(token, !nonRoot);
5398 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005399 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 }
5401 Binder.restoreCallingIdentity(origId);
5402 }
5403 return false;
5404 }
5405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005406 public void moveTaskBackwards(int task) {
5407 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5408 "moveTaskBackwards()");
5409
5410 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005411 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5412 Binder.getCallingUid(), "Task backwards")) {
5413 return;
5414 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 final long origId = Binder.clearCallingIdentity();
5416 moveTaskBackwardsLocked(task);
5417 Binder.restoreCallingIdentity(origId);
5418 }
5419 }
5420
5421 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005422 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 }
5424
5425 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5426 synchronized(this) {
5427 return getTaskForActivityLocked(token, onlyRoot);
5428 }
5429 }
5430
5431 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005432 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 TaskRecord lastTask = null;
5434 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005435 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 if (r == token) {
5437 if (!onlyRoot || lastTask != r.task) {
5438 return r.task.taskId;
5439 }
5440 return -1;
5441 }
5442 lastTask = r.task;
5443 }
5444
5445 return -1;
5446 }
5447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 public void finishOtherInstances(IBinder token, ComponentName className) {
5449 synchronized(this) {
5450 final long origId = Binder.clearCallingIdentity();
5451
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005452 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005453 TaskRecord lastTask = null;
5454 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005455 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 if (r.realActivity.equals(className)
5457 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005458 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005459 null, "others")) {
5460 i--;
5461 N--;
5462 }
5463 }
5464 lastTask = r.task;
5465 }
5466
5467 Binder.restoreCallingIdentity(origId);
5468 }
5469 }
5470
5471 // =========================================================
5472 // THUMBNAILS
5473 // =========================================================
5474
5475 public void reportThumbnail(IBinder token,
5476 Bitmap thumbnail, CharSequence description) {
5477 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5478 final long origId = Binder.clearCallingIdentity();
5479 sendPendingThumbnail(null, token, thumbnail, description, true);
5480 Binder.restoreCallingIdentity(origId);
5481 }
5482
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005483 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005484 Bitmap thumbnail, CharSequence description, boolean always) {
5485 TaskRecord task = null;
5486 ArrayList receivers = null;
5487
5488 //System.out.println("Send pending thumbnail: " + r);
5489
5490 synchronized(this) {
5491 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005492 r = mMainStack.isInStackLocked(token);
5493 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005494 return;
5495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005497 if (thumbnail == null && r.thumbHolder != null) {
5498 thumbnail = r.thumbHolder.lastThumbnail;
5499 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005500 }
5501 if (thumbnail == null && !always) {
5502 // If there is no thumbnail, and this entry is not actually
5503 // going away, then abort for now and pick up the next
5504 // thumbnail we get.
5505 return;
5506 }
5507 task = r.task;
5508
5509 int N = mPendingThumbnails.size();
5510 int i=0;
5511 while (i<N) {
5512 PendingThumbnailsRecord pr =
5513 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5514 //System.out.println("Looking in " + pr.pendingRecords);
5515 if (pr.pendingRecords.remove(r)) {
5516 if (receivers == null) {
5517 receivers = new ArrayList();
5518 }
5519 receivers.add(pr);
5520 if (pr.pendingRecords.size() == 0) {
5521 pr.finished = true;
5522 mPendingThumbnails.remove(i);
5523 N--;
5524 continue;
5525 }
5526 }
5527 i++;
5528 }
5529 }
5530
5531 if (receivers != null) {
5532 final int N = receivers.size();
5533 for (int i=0; i<N; i++) {
5534 try {
5535 PendingThumbnailsRecord pr =
5536 (PendingThumbnailsRecord)receivers.get(i);
5537 pr.receiver.newThumbnail(
5538 task != null ? task.taskId : -1, thumbnail, description);
5539 if (pr.finished) {
5540 pr.receiver.finished();
5541 }
5542 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005543 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005544 }
5545 }
5546 }
5547 }
5548
5549 // =========================================================
5550 // CONTENT PROVIDERS
5551 // =========================================================
5552
Jeff Brown10e89712011-07-08 18:52:57 -07005553 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5554 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005556 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005557 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005558 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005559 } catch (RemoteException ex) {
5560 }
5561 if (providers != null) {
5562 final int N = providers.size();
5563 for (int i=0; i<N; i++) {
5564 ProviderInfo cpi =
5565 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005566 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5567 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005569 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005570 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 }
5572 app.pubProviders.put(cpi.name, cpr);
5573 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005574 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 }
5576 }
5577 return providers;
5578 }
5579
5580 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005581 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5583 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5584 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005585 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005586 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005587 return null;
5588 }
5589 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005590 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 == PackageManager.PERMISSION_GRANTED) {
5592 return null;
5593 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005594
5595 PathPermission[] pps = cpi.pathPermissions;
5596 if (pps != null) {
5597 int i = pps.length;
5598 while (i > 0) {
5599 i--;
5600 PathPermission pp = pps[i];
5601 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005602 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005603 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005604 return null;
5605 }
5606 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005607 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005608 == PackageManager.PERMISSION_GRANTED) {
5609 return null;
5610 }
5611 }
5612 }
5613
Dianne Hackbornb424b632010-08-18 15:59:05 -07005614 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5615 if (perms != null) {
5616 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5617 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5618 return null;
5619 }
5620 }
5621 }
5622
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005623 String msg;
5624 if (!cpi.exported) {
5625 msg = "Permission Denial: opening provider " + cpi.name
5626 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5627 + ", uid=" + callingUid + ") that is not exported from uid "
5628 + cpi.applicationInfo.uid;
5629 } else {
5630 msg = "Permission Denial: opening provider " + cpi.name
5631 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5632 + ", uid=" + callingUid + ") requires "
5633 + cpi.readPermission + " or " + cpi.writePermission;
5634 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005635 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005636 return msg;
5637 }
5638
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005639 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5640 if (r != null) {
5641 Integer cnt = r.conProviders.get(cpr);
5642 if (DEBUG_PROVIDER) Slog.v(TAG,
5643 "Adding provider requested by "
5644 + r.processName + " from process "
5645 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5646 + " cnt=" + (cnt == null ? 1 : cnt));
5647 if (cnt == null) {
5648 cpr.clients.add(r);
5649 r.conProviders.put(cpr, new Integer(1));
5650 return true;
5651 } else {
5652 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5653 }
5654 } else {
5655 cpr.externals++;
5656 }
5657 return false;
5658 }
5659
5660 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5661 if (r != null) {
5662 Integer cnt = r.conProviders.get(cpr);
5663 if (DEBUG_PROVIDER) Slog.v(TAG,
5664 "Removing provider requested by "
5665 + r.processName + " from process "
5666 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5667 + " cnt=" + cnt);
5668 if (cnt == null || cnt.intValue() <= 1) {
5669 cpr.clients.remove(r);
5670 r.conProviders.remove(cpr);
5671 return true;
5672 } else {
5673 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5674 }
5675 } else {
5676 cpr.externals++;
5677 }
5678 return false;
5679 }
5680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 private final ContentProviderHolder getContentProviderImpl(
5682 IApplicationThread caller, String name) {
5683 ContentProviderRecord cpr;
5684 ProviderInfo cpi = null;
5685
5686 synchronized(this) {
5687 ProcessRecord r = null;
5688 if (caller != null) {
5689 r = getRecordForAppLocked(caller);
5690 if (r == null) {
5691 throw new SecurityException(
5692 "Unable to find app for caller " + caller
5693 + " (pid=" + Binder.getCallingPid()
5694 + ") when getting content provider " + name);
5695 }
5696 }
5697
5698 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005699 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005700 boolean providerRunning = cpr != null;
5701 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005703 String msg;
5704 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5705 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 }
5707
5708 if (r != null && cpr.canRunHere(r)) {
5709 // This provider has been published or is in the process
5710 // of being published... but it is also allowed to run
5711 // in the caller's process, so don't make a connection
5712 // and just let the caller instantiate its own instance.
5713 if (cpr.provider != null) {
5714 // don't give caller the provider object, it needs
5715 // to make its own.
5716 cpr = new ContentProviderRecord(cpr);
5717 }
5718 return cpr;
5719 }
5720
5721 final long origId = Binder.clearCallingIdentity();
5722
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005723 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005725 final boolean countChanged = incProviderCount(r, cpr);
5726 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005727 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005728 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005729 // make sure to count it as being accessed and thus
5730 // back up on the LRU list. This is good because
5731 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005732 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005733 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005734 }
5735
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005736 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005737 if (false) {
5738 if (cpr.name.flattenToShortString().equals(
5739 "com.android.providers.calendar/.CalendarProvider2")) {
5740 Slog.v(TAG, "****************** KILLING "
5741 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005742 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005743 }
5744 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005745 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005746 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5747 // NOTE: there is still a race here where a signal could be
5748 // pending on the process even though we managed to update its
5749 // adj level. Not sure what to do about this, but at least
5750 // the race is now smaller.
5751 if (!success) {
5752 // Uh oh... it looks like the provider's process
5753 // has been killed on us. We need to wait for a new
5754 // process to be started, and make sure its death
5755 // doesn't kill our process.
5756 Slog.i(TAG,
5757 "Existing provider " + cpr.name.flattenToShortString()
5758 + " is crashing; detaching " + r);
5759 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005760 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005761 if (!lastRef) {
5762 // This wasn't the last ref our process had on
5763 // the provider... we have now been killed, bail.
5764 return null;
5765 }
5766 providerRunning = false;
5767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005768 }
5769
5770 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005773 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005775 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005776 resolveContentProvider(name,
5777 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005778 } catch (RemoteException ex) {
5779 }
5780 if (cpi == null) {
5781 return null;
5782 }
5783
Dianne Hackbornb424b632010-08-18 15:59:05 -07005784 String msg;
5785 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5786 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005787 }
5788
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005789 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005790 && !cpi.processName.equals("system")) {
5791 // If this content provider does not run in the system
5792 // process, and the system is not yet ready to run other
5793 // processes, then fail fast instead of hanging.
5794 throw new IllegalArgumentException(
5795 "Attempt to launch content provider before system ready");
5796 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005797
5798 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5799 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 final boolean firstClass = cpr == null;
5801 if (firstClass) {
5802 try {
5803 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005804 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005805 getApplicationInfo(
5806 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005807 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005808 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005809 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 + cpi.name);
5811 return null;
5812 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005813 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 } catch (RemoteException ex) {
5815 // pm is in same process, this will never happen.
5816 }
5817 }
5818
5819 if (r != null && cpr.canRunHere(r)) {
5820 // If this is a multiprocess provider, then just return its
5821 // info and allow the caller to instantiate it. Only do
5822 // this if the provider is the same user as the caller's
5823 // process, or can run as root (so can be in any process).
5824 return cpr;
5825 }
5826
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005827 if (DEBUG_PROVIDER) {
5828 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005829 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005830 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 }
5832
5833 // This is single process, and our app is now connecting to it.
5834 // See if we are already in the process of launching this
5835 // provider.
5836 final int N = mLaunchingProviders.size();
5837 int i;
5838 for (i=0; i<N; i++) {
5839 if (mLaunchingProviders.get(i) == cpr) {
5840 break;
5841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005842 }
5843
5844 // If the provider is not already being launched, then get it
5845 // started.
5846 if (i >= N) {
5847 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005848
5849 try {
5850 // Content provider is now in use, its package can't be stopped.
5851 try {
5852 AppGlobals.getPackageManager().setPackageStoppedState(
5853 cpr.appInfo.packageName, false);
5854 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005855 } catch (IllegalArgumentException e) {
5856 Slog.w(TAG, "Failed trying to unstop package "
5857 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005858 }
5859
5860 ProcessRecord proc = startProcessLocked(cpi.processName,
5861 cpr.appInfo, false, 0, "content provider",
5862 new ComponentName(cpi.applicationInfo.packageName,
5863 cpi.name), false);
5864 if (proc == null) {
5865 Slog.w(TAG, "Unable to launch app "
5866 + cpi.applicationInfo.packageName + "/"
5867 + cpi.applicationInfo.uid + " for provider "
5868 + name + ": process is bad");
5869 return null;
5870 }
5871 cpr.launchingApp = proc;
5872 mLaunchingProviders.add(cpr);
5873 } finally {
5874 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005876 }
5877
5878 // Make sure the provider is published (the same provider class
5879 // may be published under multiple names).
5880 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005881 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 }
5883 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005884 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 }
5886 }
5887
5888 // Wait for the provider to be published...
5889 synchronized (cpr) {
5890 while (cpr.provider == null) {
5891 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005892 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005893 + cpi.applicationInfo.packageName + "/"
5894 + cpi.applicationInfo.uid + " for provider "
5895 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005896 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 cpi.applicationInfo.packageName,
5898 cpi.applicationInfo.uid, name);
5899 return null;
5900 }
5901 try {
5902 cpr.wait();
5903 } catch (InterruptedException ex) {
5904 }
5905 }
5906 }
5907 return cpr;
5908 }
5909
5910 public final ContentProviderHolder getContentProvider(
5911 IApplicationThread caller, String name) {
5912 if (caller == null) {
5913 String msg = "null IApplicationThread when getting content provider "
5914 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005915 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 throw new SecurityException(msg);
5917 }
5918
5919 return getContentProviderImpl(caller, name);
5920 }
5921
5922 private ContentProviderHolder getContentProviderExternal(String name) {
5923 return getContentProviderImpl(null, name);
5924 }
5925
5926 /**
5927 * Drop a content provider from a ProcessRecord's bookkeeping
5928 * @param cpr
5929 */
5930 public void removeContentProvider(IApplicationThread caller, String name) {
5931 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005932 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005934 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005935 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005936 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 return;
5938 }
5939 final ProcessRecord r = getRecordForAppLocked(caller);
5940 if (r == null) {
5941 throw new SecurityException(
5942 "Unable to find app for caller " + caller +
5943 " when removing content provider " + name);
5944 }
5945 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005946 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5947 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005948 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005949 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005950 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005951 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 return;
5953 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005954 if (decProviderCount(r, localCpr)) {
5955 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 }
5959 }
5960
5961 private void removeContentProviderExternal(String name) {
5962 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005963 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 if(cpr == null) {
5965 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005966 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005967 return;
5968 }
5969
5970 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005971 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5972 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 localCpr.externals--;
5974 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005975 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005976 }
5977 updateOomAdjLocked();
5978 }
5979 }
5980
5981 public final void publishContentProviders(IApplicationThread caller,
5982 List<ContentProviderHolder> providers) {
5983 if (providers == null) {
5984 return;
5985 }
5986
5987 synchronized(this) {
5988 final ProcessRecord r = getRecordForAppLocked(caller);
5989 if (r == null) {
5990 throw new SecurityException(
5991 "Unable to find app for caller " + caller
5992 + " (pid=" + Binder.getCallingPid()
5993 + ") when publishing content providers");
5994 }
5995
5996 final long origId = Binder.clearCallingIdentity();
5997
5998 final int N = providers.size();
5999 for (int i=0; i<N; i++) {
6000 ContentProviderHolder src = providers.get(i);
6001 if (src == null || src.info == null || src.provider == null) {
6002 continue;
6003 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006004 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006005 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006006 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6007 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006008 String names[] = dst.info.authority.split(";");
6009 for (int j = 0; j < names.length; j++) {
6010 mProvidersByName.put(names[j], dst);
6011 }
6012
6013 int NL = mLaunchingProviders.size();
6014 int j;
6015 for (j=0; j<NL; j++) {
6016 if (mLaunchingProviders.get(j) == dst) {
6017 mLaunchingProviders.remove(j);
6018 j--;
6019 NL--;
6020 }
6021 }
6022 synchronized (dst) {
6023 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006024 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 dst.notifyAll();
6026 }
6027 updateOomAdjLocked(r);
6028 }
6029 }
6030
6031 Binder.restoreCallingIdentity(origId);
6032 }
6033 }
6034
6035 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006036 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006037 synchronized (mSelf) {
6038 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6039 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006040 if (providers != null) {
6041 for (int i=providers.size()-1; i>=0; i--) {
6042 ProviderInfo pi = (ProviderInfo)providers.get(i);
6043 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6044 Slog.w(TAG, "Not installing system proc provider " + pi.name
6045 + ": not system .apk");
6046 providers.remove(i);
6047 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006048 }
6049 }
6050 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006051 if (providers != null) {
6052 mSystemThread.installSystemProviders(providers);
6053 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006054
6055 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006056
6057 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 }
6059
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006060 /**
6061 * Allows app to retrieve the MIME type of a URI without having permission
6062 * to access its content provider.
6063 *
6064 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6065 *
6066 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6067 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6068 */
6069 public String getProviderMimeType(Uri uri) {
6070 final String name = uri.getAuthority();
6071 final long ident = Binder.clearCallingIdentity();
6072 ContentProviderHolder holder = null;
6073
6074 try {
6075 holder = getContentProviderExternal(name);
6076 if (holder != null) {
6077 return holder.provider.getType(uri);
6078 }
6079 } catch (RemoteException e) {
6080 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6081 return null;
6082 } finally {
6083 if (holder != null) {
6084 removeContentProviderExternal(name);
6085 }
6086 Binder.restoreCallingIdentity(ident);
6087 }
6088
6089 return null;
6090 }
6091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 // =========================================================
6093 // GLOBAL MANAGEMENT
6094 // =========================================================
6095
6096 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6097 ApplicationInfo info, String customProcess) {
6098 String proc = customProcess != null ? customProcess : info.processName;
6099 BatteryStatsImpl.Uid.Proc ps = null;
6100 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6101 synchronized (stats) {
6102 ps = stats.getProcessStatsLocked(info.uid, proc);
6103 }
6104 return new ProcessRecord(ps, thread, info, proc);
6105 }
6106
6107 final ProcessRecord addAppLocked(ApplicationInfo info) {
6108 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6109
6110 if (app == null) {
6111 app = newProcessRecordLocked(null, info, null);
6112 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006113 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006114 }
6115
Dianne Hackborne7f97212011-02-24 14:40:20 -08006116 // This package really, really can not be stopped.
6117 try {
6118 AppGlobals.getPackageManager().setPackageStoppedState(
6119 info.packageName, false);
6120 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006121 } catch (IllegalArgumentException e) {
6122 Slog.w(TAG, "Failed trying to unstop package "
6123 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006124 }
6125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006126 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6127 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6128 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006129 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006130 }
6131 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6132 mPersistentStartingProcesses.add(app);
6133 startProcessLocked(app, "added application", app.processName);
6134 }
6135
6136 return app;
6137 }
6138
6139 public void unhandledBack() {
6140 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6141 "unhandledBack()");
6142
6143 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006144 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006145 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006146 TAG, "Performing unhandledBack(): stack size = " + count);
6147 if (count > 1) {
6148 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006149 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6151 Binder.restoreCallingIdentity(origId);
6152 }
6153 }
6154 }
6155
6156 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6157 String name = uri.getAuthority();
6158 ContentProviderHolder cph = getContentProviderExternal(name);
6159 ParcelFileDescriptor pfd = null;
6160 if (cph != null) {
6161 // We record the binder invoker's uid in thread-local storage before
6162 // going to the content provider to open the file. Later, in the code
6163 // that handles all permissions checks, we look for this uid and use
6164 // that rather than the Activity Manager's own uid. The effect is that
6165 // we do the check against the caller's permissions even though it looks
6166 // to the content provider like the Activity Manager itself is making
6167 // the request.
6168 sCallerIdentity.set(new Identity(
6169 Binder.getCallingPid(), Binder.getCallingUid()));
6170 try {
6171 pfd = cph.provider.openFile(uri, "r");
6172 } catch (FileNotFoundException e) {
6173 // do nothing; pfd will be returned null
6174 } finally {
6175 // Ensure that whatever happens, we clean up the identity state
6176 sCallerIdentity.remove();
6177 }
6178
6179 // We've got the fd now, so we're done with the provider.
6180 removeContentProviderExternal(name);
6181 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006182 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 }
6184 return pfd;
6185 }
6186
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006187 // Actually is sleeping or shutting down or whatever else in the future
6188 // is an inactive state.
6189 public boolean isSleeping() {
6190 return mSleeping || mShuttingDown;
6191 }
6192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006193 public void goingToSleep() {
6194 synchronized(this) {
6195 mSleeping = true;
6196 mWindowManager.setEventDispatching(false);
6197
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006198 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006199
6200 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006201 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006202 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6203 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006204 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006205 }
6206 }
6207
Dianne Hackborn55280a92009-05-07 15:53:46 -07006208 public boolean shutdown(int timeout) {
6209 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6210 != PackageManager.PERMISSION_GRANTED) {
6211 throw new SecurityException("Requires permission "
6212 + android.Manifest.permission.SHUTDOWN);
6213 }
6214
6215 boolean timedout = false;
6216
6217 synchronized(this) {
6218 mShuttingDown = true;
6219 mWindowManager.setEventDispatching(false);
6220
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006221 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006222 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006223 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006224 while (mMainStack.mResumedActivity != null
6225 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006226 long delay = endTime - System.currentTimeMillis();
6227 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006228 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006229 timedout = true;
6230 break;
6231 }
6232 try {
6233 this.wait();
6234 } catch (InterruptedException e) {
6235 }
6236 }
6237 }
6238 }
6239
6240 mUsageStatsService.shutdown();
6241 mBatteryStatsService.shutdown();
6242
6243 return timedout;
6244 }
6245
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006246 public final void activitySlept(IBinder token) {
6247 if (localLOGV) Slog.v(
6248 TAG, "Activity slept: token=" + token);
6249
6250 ActivityRecord r = null;
6251
6252 final long origId = Binder.clearCallingIdentity();
6253
6254 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006255 r = mMainStack.isInStackLocked(token);
6256 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006257 mMainStack.activitySleptLocked(r);
6258 }
6259 }
6260
6261 Binder.restoreCallingIdentity(origId);
6262 }
6263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006264 public void wakingUp() {
6265 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006266 mWindowManager.setEventDispatching(true);
6267 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006268 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006269 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006270 }
6271 }
6272
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006273 public void stopAppSwitches() {
6274 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6275 != PackageManager.PERMISSION_GRANTED) {
6276 throw new SecurityException("Requires permission "
6277 + android.Manifest.permission.STOP_APP_SWITCHES);
6278 }
6279
6280 synchronized(this) {
6281 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6282 + APP_SWITCH_DELAY_TIME;
6283 mDidAppSwitch = false;
6284 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6285 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6286 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6287 }
6288 }
6289
6290 public void resumeAppSwitches() {
6291 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6292 != PackageManager.PERMISSION_GRANTED) {
6293 throw new SecurityException("Requires permission "
6294 + android.Manifest.permission.STOP_APP_SWITCHES);
6295 }
6296
6297 synchronized(this) {
6298 // Note that we don't execute any pending app switches... we will
6299 // let those wait until either the timeout, or the next start
6300 // activity request.
6301 mAppSwitchesAllowedTime = 0;
6302 }
6303 }
6304
6305 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6306 String name) {
6307 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6308 return true;
6309 }
6310
6311 final int perm = checkComponentPermission(
6312 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006313 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006314 if (perm == PackageManager.PERMISSION_GRANTED) {
6315 return true;
6316 }
6317
Joe Onorato8a9b2202010-02-26 18:56:32 -08006318 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006319 return false;
6320 }
6321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 public void setDebugApp(String packageName, boolean waitForDebugger,
6323 boolean persistent) {
6324 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6325 "setDebugApp()");
6326
6327 // Note that this is not really thread safe if there are multiple
6328 // callers into it at the same time, but that's not a situation we
6329 // care about.
6330 if (persistent) {
6331 final ContentResolver resolver = mContext.getContentResolver();
6332 Settings.System.putString(
6333 resolver, Settings.System.DEBUG_APP,
6334 packageName);
6335 Settings.System.putInt(
6336 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6337 waitForDebugger ? 1 : 0);
6338 }
6339
6340 synchronized (this) {
6341 if (!persistent) {
6342 mOrigDebugApp = mDebugApp;
6343 mOrigWaitForDebugger = mWaitForDebugger;
6344 }
6345 mDebugApp = packageName;
6346 mWaitForDebugger = waitForDebugger;
6347 mDebugTransient = !persistent;
6348 if (packageName != null) {
6349 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006350 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006351 Binder.restoreCallingIdentity(origId);
6352 }
6353 }
6354 }
6355
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006356 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6357 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6358 synchronized (this) {
6359 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6360 if (!isDebuggable) {
6361 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6362 throw new SecurityException("Process not debuggable: " + app.packageName);
6363 }
6364 }
6365 mProfileApp = processName;
6366 mProfileFile = profileFile;
6367 if (mProfileFd != null) {
6368 try {
6369 mProfileFd.close();
6370 } catch (IOException e) {
6371 }
6372 mProfileFd = null;
6373 }
6374 mProfileFd = profileFd;
6375 mProfileType = 0;
6376 mAutoStopProfiler = autoStopProfiler;
6377 }
6378 }
6379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006380 public void setAlwaysFinish(boolean enabled) {
6381 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6382 "setAlwaysFinish()");
6383
6384 Settings.System.putInt(
6385 mContext.getContentResolver(),
6386 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6387
6388 synchronized (this) {
6389 mAlwaysFinishActivities = enabled;
6390 }
6391 }
6392
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006393 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006394 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006395 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006397 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006398 }
6399 }
6400
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006401 public boolean isUserAMonkey() {
6402 // For now the fact that there is a controller implies
6403 // we have a monkey.
6404 synchronized (this) {
6405 return mController != null;
6406 }
6407 }
6408
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006409 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006410 synchronized (this) {
6411 mWatchers.register(watcher);
6412 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006413 }
6414
6415 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006416 synchronized (this) {
6417 mWatchers.unregister(watcher);
6418 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006419 }
6420
Jeff Sharkeya4620792011-05-20 15:29:23 -07006421 public void registerProcessObserver(IProcessObserver observer) {
6422 mProcessObservers.register(observer);
6423 }
6424
6425 public void unregisterProcessObserver(IProcessObserver observer) {
6426 mProcessObservers.unregister(observer);
6427 }
6428
Daniel Sandler69a48172010-06-23 16:29:36 -04006429 public void setImmersive(IBinder token, boolean immersive) {
6430 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006431 ActivityRecord r = mMainStack.isInStackLocked(token);
6432 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006433 throw new IllegalArgumentException();
6434 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006435 r.immersive = immersive;
6436 }
6437 }
6438
6439 public boolean isImmersive(IBinder token) {
6440 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006441 ActivityRecord r = mMainStack.isInStackLocked(token);
6442 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006443 throw new IllegalArgumentException();
6444 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006445 return r.immersive;
6446 }
6447 }
6448
6449 public boolean isTopActivityImmersive() {
6450 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006451 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006452 return (r != null) ? r.immersive : false;
6453 }
6454 }
6455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006456 public final void enterSafeMode() {
6457 synchronized(this) {
6458 // It only makes sense to do this before the system is ready
6459 // and started launching other packages.
6460 if (!mSystemReady) {
6461 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006462 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006463 } catch (RemoteException e) {
6464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006465 }
6466 }
6467 }
6468
Jeff Brownb09abc12011-01-13 21:08:27 -08006469 public final void showSafeModeOverlay() {
6470 View v = LayoutInflater.from(mContext).inflate(
6471 com.android.internal.R.layout.safe_mode, null);
6472 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6473 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6474 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6475 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6476 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6477 lp.format = v.getBackground().getOpacity();
6478 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6479 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6480 ((WindowManager)mContext.getSystemService(
6481 Context.WINDOW_SERVICE)).addView(v, lp);
6482 }
6483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 public void noteWakeupAlarm(IIntentSender sender) {
6485 if (!(sender instanceof PendingIntentRecord)) {
6486 return;
6487 }
6488 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6489 synchronized (stats) {
6490 if (mBatteryStatsService.isOnBattery()) {
6491 mBatteryStatsService.enforceCallingPermission();
6492 PendingIntentRecord rec = (PendingIntentRecord)sender;
6493 int MY_UID = Binder.getCallingUid();
6494 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6495 BatteryStatsImpl.Uid.Pkg pkg =
6496 stats.getPackageStatsLocked(uid, rec.key.packageName);
6497 pkg.incWakeupsLocked();
6498 }
6499 }
6500 }
6501
Dianne Hackborn64825172011-03-02 21:32:58 -08006502 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006503 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006504 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006505 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006506 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507 // XXX Note: don't acquire main activity lock here, because the window
6508 // manager calls in with its locks held.
6509
6510 boolean killed = false;
6511 synchronized (mPidsSelfLocked) {
6512 int[] types = new int[pids.length];
6513 int worstType = 0;
6514 for (int i=0; i<pids.length; i++) {
6515 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6516 if (proc != null) {
6517 int type = proc.setAdj;
6518 types[i] = type;
6519 if (type > worstType) {
6520 worstType = type;
6521 }
6522 }
6523 }
6524
Dianne Hackborn64825172011-03-02 21:32:58 -08006525 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006526 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006527 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6528 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006529 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006530 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006531
6532 // If this is not a secure call, don't let it kill processes that
6533 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006534 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6535 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006536 }
6537
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006538 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006539 for (int i=0; i<pids.length; i++) {
6540 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6541 if (proc == null) {
6542 continue;
6543 }
6544 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006545 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006546 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006547 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6548 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006549 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006550 proc.killedBackground = true;
6551 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006552 }
6553 }
6554 }
6555 return killed;
6556 }
6557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 public final void startRunning(String pkg, String cls, String action,
6559 String data) {
6560 synchronized(this) {
6561 if (mStartRunning) {
6562 return;
6563 }
6564 mStartRunning = true;
6565 mTopComponent = pkg != null && cls != null
6566 ? new ComponentName(pkg, cls) : null;
6567 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6568 mTopData = data;
6569 if (!mSystemReady) {
6570 return;
6571 }
6572 }
6573
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006574 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006575 }
6576
6577 private void retrieveSettings() {
6578 final ContentResolver resolver = mContext.getContentResolver();
6579 String debugApp = Settings.System.getString(
6580 resolver, Settings.System.DEBUG_APP);
6581 boolean waitForDebugger = Settings.System.getInt(
6582 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6583 boolean alwaysFinishActivities = Settings.System.getInt(
6584 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6585
6586 Configuration configuration = new Configuration();
6587 Settings.System.getConfiguration(resolver, configuration);
6588
6589 synchronized (this) {
6590 mDebugApp = mOrigDebugApp = debugApp;
6591 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6592 mAlwaysFinishActivities = alwaysFinishActivities;
6593 // This happens before any activities are started, so we can
6594 // change mConfiguration in-place.
6595 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006596 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006597 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 }
6599 }
6600
6601 public boolean testIsSystemReady() {
6602 // no need to synchronize(this) just to read & return the value
6603 return mSystemReady;
6604 }
6605
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006606 private static File getCalledPreBootReceiversFile() {
6607 File dataDir = Environment.getDataDirectory();
6608 File systemDir = new File(dataDir, "system");
6609 File fname = new File(systemDir, "called_pre_boots.dat");
6610 return fname;
6611 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006612
6613 static final int LAST_DONE_VERSION = 10000;
6614
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006615 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6616 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6617 File file = getCalledPreBootReceiversFile();
6618 FileInputStream fis = null;
6619 try {
6620 fis = new FileInputStream(file);
6621 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006622 int fvers = dis.readInt();
6623 if (fvers == LAST_DONE_VERSION) {
6624 String vers = dis.readUTF();
6625 String codename = dis.readUTF();
6626 String build = dis.readUTF();
6627 if (android.os.Build.VERSION.RELEASE.equals(vers)
6628 && android.os.Build.VERSION.CODENAME.equals(codename)
6629 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6630 int num = dis.readInt();
6631 while (num > 0) {
6632 num--;
6633 String pkg = dis.readUTF();
6634 String cls = dis.readUTF();
6635 lastDoneReceivers.add(new ComponentName(pkg, cls));
6636 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006637 }
6638 }
6639 } catch (FileNotFoundException e) {
6640 } catch (IOException e) {
6641 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6642 } finally {
6643 if (fis != null) {
6644 try {
6645 fis.close();
6646 } catch (IOException e) {
6647 }
6648 }
6649 }
6650 return lastDoneReceivers;
6651 }
6652
6653 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6654 File file = getCalledPreBootReceiversFile();
6655 FileOutputStream fos = null;
6656 DataOutputStream dos = null;
6657 try {
6658 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6659 fos = new FileOutputStream(file);
6660 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006661 dos.writeInt(LAST_DONE_VERSION);
6662 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006663 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006664 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006665 dos.writeInt(list.size());
6666 for (int i=0; i<list.size(); i++) {
6667 dos.writeUTF(list.get(i).getPackageName());
6668 dos.writeUTF(list.get(i).getClassName());
6669 }
6670 } catch (IOException e) {
6671 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6672 file.delete();
6673 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006674 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006675 if (dos != null) {
6676 try {
6677 dos.close();
6678 } catch (IOException e) {
6679 // TODO Auto-generated catch block
6680 e.printStackTrace();
6681 }
6682 }
6683 }
6684 }
6685
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006686 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006687 synchronized(this) {
6688 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006689 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 return;
6691 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006692
6693 // Check to see if there are any update receivers to run.
6694 if (!mDidUpdate) {
6695 if (mWaitingUpdate) {
6696 return;
6697 }
6698 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6699 List<ResolveInfo> ris = null;
6700 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006701 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006702 intent, null, 0);
6703 } catch (RemoteException e) {
6704 }
6705 if (ris != null) {
6706 for (int i=ris.size()-1; i>=0; i--) {
6707 if ((ris.get(i).activityInfo.applicationInfo.flags
6708 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6709 ris.remove(i);
6710 }
6711 }
6712 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006713
6714 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6715
6716 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006717 for (int i=0; i<ris.size(); i++) {
6718 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006719 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6720 if (lastDoneReceivers.contains(comp)) {
6721 ris.remove(i);
6722 i--;
6723 }
6724 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006725
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006726 for (int i=0; i<ris.size(); i++) {
6727 ActivityInfo ai = ris.get(i).activityInfo;
6728 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6729 doneReceivers.add(comp);
6730 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006731 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006732 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006733 finisher = new IIntentReceiver.Stub() {
6734 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006735 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006736 boolean sticky) {
6737 // The raw IIntentReceiver interface is called
6738 // with the AM lock held, so redispatch to
6739 // execute our code without the lock.
6740 mHandler.post(new Runnable() {
6741 public void run() {
6742 synchronized (ActivityManagerService.this) {
6743 mDidUpdate = true;
6744 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006745 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006746 showBootMessage(mContext.getText(
6747 R.string.android_upgrading_complete),
6748 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006749 systemReady(goingCallback);
6750 }
6751 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006752 }
6753 };
6754 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006755 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006756 broadcastIntentLocked(null, null, intent, null, finisher,
6757 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006758 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006759 mWaitingUpdate = true;
6760 }
6761 }
6762 }
6763 if (mWaitingUpdate) {
6764 return;
6765 }
6766 mDidUpdate = true;
6767 }
6768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 mSystemReady = true;
6770 if (!mStartRunning) {
6771 return;
6772 }
6773 }
6774
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006775 ArrayList<ProcessRecord> procsToKill = null;
6776 synchronized(mPidsSelfLocked) {
6777 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6778 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6779 if (!isAllowedWhileBooting(proc.info)){
6780 if (procsToKill == null) {
6781 procsToKill = new ArrayList<ProcessRecord>();
6782 }
6783 procsToKill.add(proc);
6784 }
6785 }
6786 }
6787
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006788 synchronized(this) {
6789 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006790 for (int i=procsToKill.size()-1; i>=0; i--) {
6791 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006792 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006793 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006794 }
6795 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006796
6797 // Now that we have cleaned up any update processes, we
6798 // are ready to start launching real processes and know that
6799 // we won't trample on them any more.
6800 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006801 }
6802
Joe Onorato8a9b2202010-02-26 18:56:32 -08006803 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006804 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 SystemClock.uptimeMillis());
6806
6807 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006808 // Make sure we have no pre-ready processes sitting around.
6809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6811 ResolveInfo ri = mContext.getPackageManager()
6812 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006813 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 CharSequence errorMsg = null;
6815 if (ri != null) {
6816 ActivityInfo ai = ri.activityInfo;
6817 ApplicationInfo app = ai.applicationInfo;
6818 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6819 mTopAction = Intent.ACTION_FACTORY_TEST;
6820 mTopData = null;
6821 mTopComponent = new ComponentName(app.packageName,
6822 ai.name);
6823 } else {
6824 errorMsg = mContext.getResources().getText(
6825 com.android.internal.R.string.factorytest_not_system);
6826 }
6827 } else {
6828 errorMsg = mContext.getResources().getText(
6829 com.android.internal.R.string.factorytest_no_action);
6830 }
6831 if (errorMsg != null) {
6832 mTopAction = null;
6833 mTopData = null;
6834 mTopComponent = null;
6835 Message msg = Message.obtain();
6836 msg.what = SHOW_FACTORY_ERROR_MSG;
6837 msg.getData().putCharSequence("msg", errorMsg);
6838 mHandler.sendMessage(msg);
6839 }
6840 }
6841 }
6842
6843 retrieveSettings();
6844
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006845 if (goingCallback != null) goingCallback.run();
6846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 synchronized (this) {
6848 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6849 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006850 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006851 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006852 if (apps != null) {
6853 int N = apps.size();
6854 int i;
6855 for (i=0; i<N; i++) {
6856 ApplicationInfo info
6857 = (ApplicationInfo)apps.get(i);
6858 if (info != null &&
6859 !info.packageName.equals("android")) {
6860 addAppLocked(info);
6861 }
6862 }
6863 }
6864 } catch (RemoteException ex) {
6865 // pm is in same process, this will never happen.
6866 }
6867 }
6868
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006869 // Start up initial activity.
6870 mBooting = true;
6871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006873 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006874 Message msg = Message.obtain();
6875 msg.what = SHOW_UID_ERROR_MSG;
6876 mHandler.sendMessage(msg);
6877 }
6878 } catch (RemoteException e) {
6879 }
6880
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006881 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 }
6883 }
6884
Dan Egnorb7f03672009-12-09 16:22:32 -08006885 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006886 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006888 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006889 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 startAppProblemLocked(app);
6891 app.stopFreezingAllLocked();
6892 return handleAppCrashLocked(app);
6893 }
6894
Dan Egnorb7f03672009-12-09 16:22:32 -08006895 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006896 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006898 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006899 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6900 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 startAppProblemLocked(app);
6902 app.stopFreezingAllLocked();
6903 }
6904
6905 /**
6906 * Generate a process error record, suitable for attachment to a ProcessRecord.
6907 *
6908 * @param app The ProcessRecord in which the error occurred.
6909 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6910 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006911 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 * @param shortMsg Short message describing the crash.
6913 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006914 * @param stackTrace Full crash stack trace, may be null.
6915 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 * @return Returns a fully-formed AppErrorStateInfo record.
6917 */
6918 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006919 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006920 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 report.condition = condition;
6923 report.processName = app.processName;
6924 report.pid = app.pid;
6925 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006926 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006927 report.shortMsg = shortMsg;
6928 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006929 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006930
6931 return report;
6932 }
6933
Dan Egnor42471dd2010-01-07 17:25:22 -08006934 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006935 synchronized (this) {
6936 app.crashing = false;
6937 app.crashingReport = null;
6938 app.notResponding = false;
6939 app.notRespondingReport = null;
6940 if (app.anrDialog == fromDialog) {
6941 app.anrDialog = null;
6942 }
6943 if (app.waitDialog == fromDialog) {
6944 app.waitDialog = null;
6945 }
6946 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006947 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006948 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006949 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6950 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006951 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006953 }
6954 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006955
Dan Egnorb7f03672009-12-09 16:22:32 -08006956 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 long now = SystemClock.uptimeMillis();
6958
6959 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6960 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006961 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006963 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006965 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006967 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6968 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006969 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006970 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006971 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006972 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 }
6974 }
6975 if (!app.persistent) {
6976 // We don't want to start this process again until the user
6977 // explicitly does so... but for persistent process, we really
6978 // need to keep it running. If a persistent process is actually
6979 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006980 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006981 app.info.processName);
6982 mBadProcesses.put(app.info.processName, app.info.uid, now);
6983 app.bad = true;
6984 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6985 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006986 // Don't let services in this process be restarted and potentially
6987 // annoy the user repeatedly. Unless it is persistent, since those
6988 // processes run critical code.
6989 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006990 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 return false;
6992 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006993 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006994 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006995 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006996 if (r.app == app) {
6997 // If the top running activity is from this crashing
6998 // process, then terminate it to avoid getting in a loop.
6999 Slog.w(TAG, " Force finishing activity "
7000 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007001 int index = mMainStack.indexOfTokenLocked(r);
7002 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007003 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007004 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007005 // stopped, to avoid a situation where one will get
7006 // re-start our crashing activity once it gets resumed again.
7007 index--;
7008 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007009 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007010 if (r.state == ActivityState.RESUMED
7011 || r.state == ActivityState.PAUSING
7012 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007013 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007014 Slog.w(TAG, " Force finishing activity "
7015 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007016 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007017 Activity.RESULT_CANCELED, null, "crashed");
7018 }
7019 }
7020 }
7021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007022 }
7023
7024 // Bump up the crash count of any services currently running in the proc.
7025 if (app.services.size() != 0) {
7026 // Any services running in the application need to be placed
7027 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007028 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007030 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 sr.crashCount++;
7032 }
7033 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007034
7035 // If the crashing process is what we consider to be the "home process" and it has been
7036 // replaced by a third-party app, clear the package preferred activities from packages
7037 // with a home activity running in the process to prevent a repeatedly crashing app
7038 // from blocking the user to manually clear the list.
7039 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7040 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7041 Iterator it = mHomeProcess.activities.iterator();
7042 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007043 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007044 if (r.isHomeActivity) {
7045 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7046 try {
7047 ActivityThread.getPackageManager()
7048 .clearPackagePreferredActivities(r.packageName);
7049 } catch (RemoteException c) {
7050 // pm is in same process, this will never happen.
7051 }
7052 }
7053 }
7054 }
7055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7057 return true;
7058 }
7059
7060 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007061 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7062 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007063 skipCurrentReceiverLocked(app);
7064 }
7065
7066 void skipCurrentReceiverLocked(ProcessRecord app) {
7067 boolean reschedule = false;
7068 BroadcastRecord r = app.curReceiver;
7069 if (r != null) {
7070 // The current broadcast is waiting for this app's receiver
7071 // to be finished. Looks like that's not going to happen, so
7072 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007073 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007074 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7075 r.resultExtras, r.resultAbort, true);
7076 reschedule = true;
7077 }
7078 r = mPendingBroadcast;
7079 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007080 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007082 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007083 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7084 r.resultExtras, r.resultAbort, true);
7085 reschedule = true;
7086 }
7087 if (reschedule) {
7088 scheduleBroadcastsLocked();
7089 }
7090 }
7091
Dan Egnor60d87622009-12-16 16:32:58 -08007092 /**
7093 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7094 * The application process will exit immediately after this call returns.
7095 * @param app object of the crashing app, null for the system server
7096 * @param crashInfo describing the exception
7097 */
7098 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007099 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007100 final String processName = app == null ? "system_server"
7101 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007102
7103 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007104 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007105 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007106 crashInfo.exceptionClassName,
7107 crashInfo.exceptionMessage,
7108 crashInfo.throwFileName,
7109 crashInfo.throwLineNumber);
7110
Jeff Sharkeya353d262011-10-28 11:12:06 -07007111 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007112
7113 crashApplication(r, crashInfo);
7114 }
7115
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007116 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007117 IBinder app,
7118 int violationMask,
7119 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007120 ProcessRecord r = findAppProcess(app, "StrictMode");
7121 if (r == null) {
7122 return;
7123 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007124
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007125 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007126 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007127 boolean logIt = true;
7128 synchronized (mAlreadyLoggedViolatedStacks) {
7129 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7130 logIt = false;
7131 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007132 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007133 // the relative pain numbers, without logging all
7134 // the stack traces repeatedly. We'd want to do
7135 // likewise in the client code, which also does
7136 // dup suppression, before the Binder call.
7137 } else {
7138 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7139 mAlreadyLoggedViolatedStacks.clear();
7140 }
7141 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7142 }
7143 }
7144 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007145 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007146 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007147 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007148
7149 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7150 AppErrorResult result = new AppErrorResult();
7151 synchronized (this) {
7152 final long origId = Binder.clearCallingIdentity();
7153
7154 Message msg = Message.obtain();
7155 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7156 HashMap<String, Object> data = new HashMap<String, Object>();
7157 data.put("result", result);
7158 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007159 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007160 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007161 msg.obj = data;
7162 mHandler.sendMessage(msg);
7163
7164 Binder.restoreCallingIdentity(origId);
7165 }
7166 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007167 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007168 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007169 }
7170
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007171 // Depending on the policy in effect, there could be a bunch of
7172 // these in quick succession so we try to batch these together to
7173 // minimize disk writes, number of dropbox entries, and maximize
7174 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007175 private void logStrictModeViolationToDropBox(
7176 ProcessRecord process,
7177 StrictMode.ViolationInfo info) {
7178 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007179 return;
7180 }
7181 final boolean isSystemApp = process == null ||
7182 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7183 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007184 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007185 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7186 final DropBoxManager dbox = (DropBoxManager)
7187 mContext.getSystemService(Context.DROPBOX_SERVICE);
7188
7189 // Exit early if the dropbox isn't configured to accept this report type.
7190 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7191
7192 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007193 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007194 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7195 synchronized (sb) {
7196 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007197 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007198 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7199 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007200 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7201 if (info.violationNumThisLoop != 0) {
7202 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7203 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007204 if (info.numAnimationsRunning != 0) {
7205 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7206 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007207 if (info.broadcastIntentAction != null) {
7208 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7209 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007210 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007211 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007212 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007213 if (info.numInstances != -1) {
7214 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7215 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007216 if (info.tags != null) {
7217 for (String tag : info.tags) {
7218 sb.append("Span-Tag: ").append(tag).append("\n");
7219 }
7220 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007221 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007222 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7223 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007224 }
7225 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007226
7227 // Only buffer up to ~64k. Various logging bits truncate
7228 // things at 128k.
7229 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007230 }
7231
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007232 // Flush immediately if the buffer's grown too large, or this
7233 // is a non-system app. Non-system apps are isolated with a
7234 // different tag & policy and not batched.
7235 //
7236 // Batching is useful during internal testing with
7237 // StrictMode settings turned up high. Without batching,
7238 // thousands of separate files could be created on boot.
7239 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007240 new Thread("Error dump: " + dropboxTag) {
7241 @Override
7242 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007243 String report;
7244 synchronized (sb) {
7245 report = sb.toString();
7246 sb.delete(0, sb.length());
7247 sb.trimToSize();
7248 }
7249 if (report.length() != 0) {
7250 dbox.addText(dropboxTag, report);
7251 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007252 }
7253 }.start();
7254 return;
7255 }
7256
7257 // System app batching:
7258 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007259 // An existing dropbox-writing thread is outstanding, so
7260 // we don't need to start it up. The existing thread will
7261 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007262 return;
7263 }
7264
7265 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7266 // (After this point, we shouldn't access AMS internal data structures.)
7267 new Thread("Error dump: " + dropboxTag) {
7268 @Override
7269 public void run() {
7270 // 5 second sleep to let stacks arrive and be batched together
7271 try {
7272 Thread.sleep(5000); // 5 seconds
7273 } catch (InterruptedException e) {}
7274
7275 String errorReport;
7276 synchronized (mStrictModeBuffer) {
7277 errorReport = mStrictModeBuffer.toString();
7278 if (errorReport.length() == 0) {
7279 return;
7280 }
7281 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7282 mStrictModeBuffer.trimToSize();
7283 }
7284 dbox.addText(dropboxTag, errorReport);
7285 }
7286 }.start();
7287 }
7288
Dan Egnor60d87622009-12-16 16:32:58 -08007289 /**
7290 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7291 * @param app object of the crashing app, null for the system server
7292 * @param tag reported by the caller
7293 * @param crashInfo describing the context of the error
7294 * @return true if the process should exit immediately (WTF is fatal)
7295 */
7296 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007297 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007298 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007299 final String processName = app == null ? "system_server"
7300 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007301
7302 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007303 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007304 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007305 tag, crashInfo.exceptionMessage);
7306
Jeff Sharkeya353d262011-10-28 11:12:06 -07007307 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007308
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007309 if (r != null && r.pid != Process.myPid() &&
7310 Settings.Secure.getInt(mContext.getContentResolver(),
7311 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007312 crashApplication(r, crashInfo);
7313 return true;
7314 } else {
7315 return false;
7316 }
7317 }
7318
7319 /**
7320 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7321 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7322 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007323 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007324 if (app == null) {
7325 return null;
7326 }
7327
7328 synchronized (this) {
7329 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7330 final int NA = apps.size();
7331 for (int ia=0; ia<NA; ia++) {
7332 ProcessRecord p = apps.valueAt(ia);
7333 if (p.thread != null && p.thread.asBinder() == app) {
7334 return p;
7335 }
7336 }
7337 }
7338
Dianne Hackborncb44d962011-03-10 17:02:27 -08007339 Slog.w(TAG, "Can't find mystery application for " + reason
7340 + " from pid=" + Binder.getCallingPid()
7341 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007342 return null;
7343 }
7344 }
7345
7346 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007347 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7348 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007349 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007350 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7351 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007352 // Watchdog thread ends up invoking this function (with
7353 // a null ProcessRecord) to add the stack file to dropbox.
7354 // Do not acquire a lock on this (am) in such cases, as it
7355 // could cause a potential deadlock, if and when watchdog
7356 // is invoked due to unavailability of lock on am and it
7357 // would prevent watchdog from killing system_server.
7358 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007359 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007360 return;
7361 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007362 // Note: ProcessRecord 'process' is guarded by the service
7363 // instance. (notably process.pkgList, which could otherwise change
7364 // concurrently during execution of this method)
7365 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007366 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007367 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007368 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007369 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7370 for (String pkg : process.pkgList) {
7371 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007372 try {
Dan Egnora455d192010-03-12 08:52:28 -08007373 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7374 if (pi != null) {
7375 sb.append(" v").append(pi.versionCode);
7376 if (pi.versionName != null) {
7377 sb.append(" (").append(pi.versionName).append(")");
7378 }
7379 }
7380 } catch (RemoteException e) {
7381 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007382 }
Dan Egnora455d192010-03-12 08:52:28 -08007383 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007384 }
Dan Egnora455d192010-03-12 08:52:28 -08007385 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007386 }
7387
7388 private static String processClass(ProcessRecord process) {
7389 if (process == null || process.pid == MY_PID) {
7390 return "system_server";
7391 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7392 return "system_app";
7393 } else {
7394 return "data_app";
7395 }
7396 }
7397
7398 /**
7399 * Write a description of an error (crash, WTF, ANR) to the drop box.
7400 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7401 * @param process which caused the error, null means the system server
7402 * @param activity which triggered the error, null if unknown
7403 * @param parent activity related to the error, null if unknown
7404 * @param subject line related to the error, null if absent
7405 * @param report in long form describing the error, null if absent
7406 * @param logFile to include in the report, null if none
7407 * @param crashInfo giving an application stack trace, null if absent
7408 */
7409 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007410 ProcessRecord process, String processName, ActivityRecord activity,
7411 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007412 final String report, final File logFile,
7413 final ApplicationErrorReport.CrashInfo crashInfo) {
7414 // NOTE -- this must never acquire the ActivityManagerService lock,
7415 // otherwise the watchdog may be prevented from resetting the system.
7416
7417 final String dropboxTag = processClass(process) + "_" + eventType;
7418 final DropBoxManager dbox = (DropBoxManager)
7419 mContext.getSystemService(Context.DROPBOX_SERVICE);
7420
7421 // Exit early if the dropbox isn't configured to accept this report type.
7422 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7423
7424 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007425 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007426 if (activity != null) {
7427 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7428 }
7429 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7430 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7431 }
7432 if (parent != null && parent != activity) {
7433 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7434 }
7435 if (subject != null) {
7436 sb.append("Subject: ").append(subject).append("\n");
7437 }
7438 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007439 if (Debug.isDebuggerConnected()) {
7440 sb.append("Debugger: Connected\n");
7441 }
Dan Egnora455d192010-03-12 08:52:28 -08007442 sb.append("\n");
7443
7444 // Do the rest in a worker thread to avoid blocking the caller on I/O
7445 // (After this point, we shouldn't access AMS internal data structures.)
7446 Thread worker = new Thread("Error dump: " + dropboxTag) {
7447 @Override
7448 public void run() {
7449 if (report != null) {
7450 sb.append(report);
7451 }
7452 if (logFile != null) {
7453 try {
7454 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7455 } catch (IOException e) {
7456 Slog.e(TAG, "Error reading " + logFile, e);
7457 }
7458 }
7459 if (crashInfo != null && crashInfo.stackTrace != null) {
7460 sb.append(crashInfo.stackTrace);
7461 }
7462
7463 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7464 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7465 if (lines > 0) {
7466 sb.append("\n");
7467
7468 // Merge several logcat streams, and take the last N lines
7469 InputStreamReader input = null;
7470 try {
7471 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7472 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7473 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7474
7475 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7476 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7477 input = new InputStreamReader(logcat.getInputStream());
7478
7479 int num;
7480 char[] buf = new char[8192];
7481 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7482 } catch (IOException e) {
7483 Slog.e(TAG, "Error running logcat", e);
7484 } finally {
7485 if (input != null) try { input.close(); } catch (IOException e) {}
7486 }
7487 }
7488
7489 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007490 }
Dan Egnora455d192010-03-12 08:52:28 -08007491 };
7492
7493 if (process == null || process.pid == MY_PID) {
7494 worker.run(); // We may be about to die -- need to run this synchronously
7495 } else {
7496 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007497 }
7498 }
7499
7500 /**
7501 * Bring up the "unexpected error" dialog box for a crashing app.
7502 * Deal with edge cases (intercepts from instrumented applications,
7503 * ActivityController, error intent receivers, that sort of thing).
7504 * @param r the application crashing
7505 * @param crashInfo describing the failure
7506 */
7507 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007508 long timeMillis = System.currentTimeMillis();
7509 String shortMsg = crashInfo.exceptionClassName;
7510 String longMsg = crashInfo.exceptionMessage;
7511 String stackTrace = crashInfo.stackTrace;
7512 if (shortMsg != null && longMsg != null) {
7513 longMsg = shortMsg + ": " + longMsg;
7514 } else if (shortMsg != null) {
7515 longMsg = shortMsg;
7516 }
7517
Dan Egnor60d87622009-12-16 16:32:58 -08007518 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007520 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007521 try {
7522 String name = r != null ? r.processName : null;
7523 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007524 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007525 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007526 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 + " at watcher's request");
7528 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007529 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007530 }
7531 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007532 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 }
7534 }
7535
7536 final long origId = Binder.clearCallingIdentity();
7537
7538 // If this process is running instrumentation, finish it.
7539 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007540 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007542 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7543 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007544 Bundle info = new Bundle();
7545 info.putString("shortMsg", shortMsg);
7546 info.putString("longMsg", longMsg);
7547 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7548 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007549 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007550 }
7551
Dan Egnor60d87622009-12-16 16:32:58 -08007552 // If we can't identify the process or it's already exceeded its crash quota,
7553 // quit right away without showing a crash dialog.
7554 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007556 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007557 }
7558
7559 Message msg = Message.obtain();
7560 msg.what = SHOW_ERROR_MSG;
7561 HashMap data = new HashMap();
7562 data.put("result", result);
7563 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007564 msg.obj = data;
7565 mHandler.sendMessage(msg);
7566
7567 Binder.restoreCallingIdentity(origId);
7568 }
7569
7570 int res = result.get();
7571
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007572 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 synchronized (this) {
7574 if (r != null) {
7575 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7576 SystemClock.uptimeMillis());
7577 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007578 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007579 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007580 }
7581 }
7582
7583 if (appErrorIntent != null) {
7584 try {
7585 mContext.startActivity(appErrorIntent);
7586 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007587 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007590 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007591
7592 Intent createAppErrorIntentLocked(ProcessRecord r,
7593 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7594 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007595 if (report == null) {
7596 return null;
7597 }
7598 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7599 result.setComponent(r.errorReportReceiver);
7600 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7601 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7602 return result;
7603 }
7604
Dan Egnorb7f03672009-12-09 16:22:32 -08007605 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7606 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007607 if (r.errorReportReceiver == null) {
7608 return null;
7609 }
7610
7611 if (!r.crashing && !r.notResponding) {
7612 return null;
7613 }
7614
Dan Egnorb7f03672009-12-09 16:22:32 -08007615 ApplicationErrorReport report = new ApplicationErrorReport();
7616 report.packageName = r.info.packageName;
7617 report.installerPackageName = r.errorReportReceiver.getPackageName();
7618 report.processName = r.processName;
7619 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007620 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007621
Dan Egnorb7f03672009-12-09 16:22:32 -08007622 if (r.crashing) {
7623 report.type = ApplicationErrorReport.TYPE_CRASH;
7624 report.crashInfo = crashInfo;
7625 } else if (r.notResponding) {
7626 report.type = ApplicationErrorReport.TYPE_ANR;
7627 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007628
Dan Egnorb7f03672009-12-09 16:22:32 -08007629 report.anrInfo.activity = r.notRespondingReport.tag;
7630 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7631 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007632 }
7633
Dan Egnorb7f03672009-12-09 16:22:32 -08007634 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007635 }
7636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7638 // assume our apps are happy - lazy create the list
7639 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7640
7641 synchronized (this) {
7642
7643 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007644 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7645 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007646 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7647 // This one's in trouble, so we'll generate a report for it
7648 // crashes are higher priority (in case there's a crash *and* an anr)
7649 ActivityManager.ProcessErrorStateInfo report = null;
7650 if (app.crashing) {
7651 report = app.crashingReport;
7652 } else if (app.notResponding) {
7653 report = app.notRespondingReport;
7654 }
7655
7656 if (report != null) {
7657 if (errList == null) {
7658 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7659 }
7660 errList.add(report);
7661 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007662 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007663 " crashing = " + app.crashing +
7664 " notResponding = " + app.notResponding);
7665 }
7666 }
7667 }
7668 }
7669
7670 return errList;
7671 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007672
7673 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007674 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007675 if (currApp != null) {
7676 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7677 }
7678 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007679 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7680 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007681 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7682 if (currApp != null) {
7683 currApp.lru = 0;
7684 }
7685 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007686 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007687 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7688 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7689 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7690 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7691 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7692 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7693 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7694 } else {
7695 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7696 }
7697 }
7698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7700 // Lazy instantiation of list
7701 List<ActivityManager.RunningAppProcessInfo> runList = null;
7702 synchronized (this) {
7703 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007704 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7705 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007706 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7707 // Generate process state info for running application
7708 ActivityManager.RunningAppProcessInfo currApp =
7709 new ActivityManager.RunningAppProcessInfo(app.processName,
7710 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007711 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007712 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007713 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007714 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007715 if (app.persistent) {
7716 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007719 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007720 currApp.importanceReasonCode = app.adjTypeCode;
7721 if (app.adjSource instanceof ProcessRecord) {
7722 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007723 currApp.importanceReasonImportance = oomAdjToImportance(
7724 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007725 } else if (app.adjSource instanceof ActivityRecord) {
7726 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007727 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7728 }
7729 if (app.adjTarget instanceof ComponentName) {
7730 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7731 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007732 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007733 // + " lru=" + currApp.lru);
7734 if (runList == null) {
7735 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7736 }
7737 runList.add(currApp);
7738 }
7739 }
7740 }
7741 return runList;
7742 }
7743
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007744 public List<ApplicationInfo> getRunningExternalApplications() {
7745 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7746 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7747 if (runningApps != null && runningApps.size() > 0) {
7748 Set<String> extList = new HashSet<String>();
7749 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7750 if (app.pkgList != null) {
7751 for (String pkg : app.pkgList) {
7752 extList.add(pkg);
7753 }
7754 }
7755 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007756 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007757 for (String pkg : extList) {
7758 try {
7759 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7760 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7761 retList.add(info);
7762 }
7763 } catch (RemoteException e) {
7764 }
7765 }
7766 }
7767 return retList;
7768 }
7769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 @Override
7771 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007772 if (checkCallingPermission(android.Manifest.permission.DUMP)
7773 != PackageManager.PERMISSION_GRANTED) {
7774 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7775 + Binder.getCallingPid()
7776 + ", uid=" + Binder.getCallingUid()
7777 + " without permission "
7778 + android.Manifest.permission.DUMP);
7779 return;
7780 }
7781
7782 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007783 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007784
7785 int opti = 0;
7786 while (opti < args.length) {
7787 String opt = args[opti];
7788 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7789 break;
7790 }
7791 opti++;
7792 if ("-a".equals(opt)) {
7793 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007794 } else if ("-c".equals(opt)) {
7795 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 } else if ("-h".equals(opt)) {
7797 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007798 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007800 pw.println(" a[ctivities]: activity stack state");
7801 pw.println(" b[roadcasts]: broadcast state");
7802 pw.println(" i[ntents]: pending intent state");
7803 pw.println(" p[rocesses]: process state");
7804 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007805 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7806 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007807 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007808 pw.println(" all: dump all activities");
7809 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007810 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007811 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7812 pw.println(" a partial substring in a component name, a");
7813 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007814 pw.println(" -a: include all available server state.");
7815 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007816 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007817 } else {
7818 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007819 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007820 }
7821
7822 // Is the caller requesting to dump a particular piece of data?
7823 if (opti < args.length) {
7824 String cmd = args[opti];
7825 opti++;
7826 if ("activities".equals(cmd) || "a".equals(cmd)) {
7827 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007828 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007829 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007830 return;
7831 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7832 synchronized (this) {
7833 dumpBroadcastsLocked(fd, pw, args, opti, true);
7834 }
7835 return;
7836 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7837 synchronized (this) {
7838 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7839 }
7840 return;
7841 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7842 synchronized (this) {
7843 dumpProcessesLocked(fd, pw, args, opti, true);
7844 }
7845 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007846 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7847 synchronized (this) {
7848 dumpOomLocked(fd, pw, args, opti, true);
7849 }
7850 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007851 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7852 synchronized (this) {
7853 dumpProvidersLocked(fd, pw, args, opti, true);
7854 }
7855 return;
7856 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007857 String[] newArgs;
7858 String name;
7859 if (opti >= args.length) {
7860 name = null;
7861 newArgs = EMPTY_STRING_ARRAY;
7862 } else {
7863 name = args[opti];
7864 opti++;
7865 newArgs = new String[args.length - opti];
7866 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7867 }
7868 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7869 pw.println("No services match: " + name);
7870 pw.println("Use -h for help.");
7871 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007872 return;
7873 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7874 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007875 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007876 }
7877 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007878 } else {
7879 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007880 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7881 pw.println("Bad activity command, or no activities match: " + cmd);
7882 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007883 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007884 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007886 }
7887
7888 // No piece of data specified, dump everything.
7889 synchronized (this) {
7890 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007891 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007892 if (needSep) {
7893 pw.println(" ");
7894 }
7895 if (dumpAll) {
7896 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007897 }
7898 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7899 if (needSep) {
7900 pw.println(" ");
7901 }
7902 if (dumpAll) {
7903 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007904 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007905 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007906 if (needSep) {
7907 pw.println(" ");
7908 }
7909 if (dumpAll) {
7910 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007912 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007913 if (needSep) {
7914 pw.println(" ");
7915 }
7916 if (dumpAll) {
7917 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007918 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007919 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007920 if (needSep) {
7921 pw.println(" ");
7922 }
7923 if (dumpAll) {
7924 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007925 }
7926 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7927 }
7928 }
7929
7930 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007931 int opti, boolean dumpAll, boolean dumpClient) {
7932 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7933 pw.println(" Main stack:");
7934 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007935 pw.println(" ");
7936 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007937 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007938 if (mMainStack.mWaitingVisibleActivities.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 for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007941 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7942 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007943 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007944 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007946 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007947 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7948 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007949 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007950 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7951 pw.println(" ");
7952 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007953 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7954 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007955 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007956 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007957 pw.println(" ");
7958 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007959 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7960 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007962
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007963 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007964 if (mMainStack.mPausingActivity != null) {
7965 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7966 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007967 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007968 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007969 if (dumpAll) {
7970 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7971 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007972 pw.println(" mDismissKeyguardOnNextActivity: "
7973 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007976 if (mRecentTasks.size() > 0) {
7977 pw.println();
7978 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007979
7980 final int N = mRecentTasks.size();
7981 for (int i=0; i<N; i++) {
7982 TaskRecord tr = mRecentTasks.get(i);
7983 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7984 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007985 if (dumpAll) {
7986 mRecentTasks.get(i).dump(pw, " ");
7987 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007988 }
7989 }
7990
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007991 if (dumpAll) {
7992 pw.println(" ");
7993 pw.println(" mCurTask: " + mCurTask);
7994 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007995
7996 return true;
7997 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007998
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007999 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8000 int opti, boolean dumpAll) {
8001 boolean needSep = false;
8002 int numPers = 0;
8003
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008004 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8005
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008006 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008007 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8008 final int NA = procs.size();
8009 for (int ia=0; ia<NA; ia++) {
8010 if (!needSep) {
8011 pw.println(" All known processes:");
8012 needSep = true;
8013 }
8014 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008015 pw.print(r.persistent ? " *PERS*" : " *APP*");
8016 pw.print(" UID "); pw.print(procs.keyAt(ia));
8017 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008018 r.dump(pw, " ");
8019 if (r.persistent) {
8020 numPers++;
8021 }
8022 }
8023 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008024 }
8025
8026 if (mLruProcesses.size() > 0) {
8027 if (needSep) pw.println(" ");
8028 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008029 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008030 dumpProcessOomList(pw, this, mLruProcesses, " ",
8031 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008032 needSep = true;
8033 }
8034
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008035 if (dumpAll) {
8036 synchronized (mPidsSelfLocked) {
8037 if (mPidsSelfLocked.size() > 0) {
8038 if (needSep) pw.println(" ");
8039 needSep = true;
8040 pw.println(" PID mappings:");
8041 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8042 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8043 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008045 }
8046 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008047 }
8048
8049 if (mForegroundProcesses.size() > 0) {
8050 if (needSep) pw.println(" ");
8051 needSep = true;
8052 pw.println(" Foreground Processes:");
8053 for (int i=0; i<mForegroundProcesses.size(); i++) {
8054 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8055 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008056 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008057 }
8058
8059 if (mPersistentStartingProcesses.size() > 0) {
8060 if (needSep) pw.println(" ");
8061 needSep = true;
8062 pw.println(" Persisent processes that are starting:");
8063 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008064 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008065 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008066
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008067 if (mRemovedProcesses.size() > 0) {
8068 if (needSep) pw.println(" ");
8069 needSep = true;
8070 pw.println(" Processes that are being removed:");
8071 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008072 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008073 }
8074
8075 if (mProcessesOnHold.size() > 0) {
8076 if (needSep) pw.println(" ");
8077 needSep = true;
8078 pw.println(" Processes that are on old until the system is ready:");
8079 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008080 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008082
Dianne Hackborn287952c2010-09-22 22:34:31 -07008083 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008084
8085 if (mProcessCrashTimes.getMap().size() > 0) {
8086 if (needSep) pw.println(" ");
8087 needSep = true;
8088 pw.println(" Time since processes crashed:");
8089 long now = SystemClock.uptimeMillis();
8090 for (Map.Entry<String, SparseArray<Long>> procs
8091 : mProcessCrashTimes.getMap().entrySet()) {
8092 SparseArray<Long> uids = procs.getValue();
8093 final int N = uids.size();
8094 for (int i=0; i<N; i++) {
8095 pw.print(" Process "); pw.print(procs.getKey());
8096 pw.print(" uid "); pw.print(uids.keyAt(i));
8097 pw.print(": last crashed ");
8098 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008099 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008100 }
8101 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008104 if (mBadProcesses.getMap().size() > 0) {
8105 if (needSep) pw.println(" ");
8106 needSep = true;
8107 pw.println(" Bad processes:");
8108 for (Map.Entry<String, SparseArray<Long>> procs
8109 : mBadProcesses.getMap().entrySet()) {
8110 SparseArray<Long> uids = procs.getValue();
8111 final int N = uids.size();
8112 for (int i=0; i<N; i++) {
8113 pw.print(" Bad process "); pw.print(procs.getKey());
8114 pw.print(" uid "); pw.print(uids.keyAt(i));
8115 pw.print(": crashed at time ");
8116 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 }
8118 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008121 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008122 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008123 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008124 if (mHeavyWeightProcess != null) {
8125 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8126 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008127 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008128 if (dumpAll) {
8129 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008130 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008131 pw.println(" mScreenCompatPackages:");
8132 for (Map.Entry<String, Integer> entry
8133 : mCompatModePackages.getPackages().entrySet()) {
8134 String pkg = entry.getKey();
8135 int mode = entry.getValue();
8136 pw.print(" "); pw.print(pkg); pw.print(": ");
8137 pw.print(mode); pw.println();
8138 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008139 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008140 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008141 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8142 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8143 || mOrigWaitForDebugger) {
8144 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8145 + " mDebugTransient=" + mDebugTransient
8146 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8147 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008148 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8149 || mProfileFd != null) {
8150 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8151 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8152 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8153 + mAutoStopProfiler);
8154 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008155 if (mAlwaysFinishActivities || mController != null) {
8156 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8157 + " mController=" + mController);
8158 }
8159 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008161 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008162 + " mProcessesReady=" + mProcessesReady
8163 + " mSystemReady=" + mSystemReady);
8164 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008165 + " mBooted=" + mBooted
8166 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008167 pw.print(" mLastPowerCheckRealtime=");
8168 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8169 pw.println("");
8170 pw.print(" mLastPowerCheckUptime=");
8171 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8172 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008173 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8174 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008175 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008176 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8177 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008178 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008179
8180 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008181 }
8182
Dianne Hackborn287952c2010-09-22 22:34:31 -07008183 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8184 int opti, boolean needSep, boolean dumpAll) {
8185 if (mProcessesToGc.size() > 0) {
8186 if (needSep) pw.println(" ");
8187 needSep = true;
8188 pw.println(" Processes that are waiting to GC:");
8189 long now = SystemClock.uptimeMillis();
8190 for (int i=0; i<mProcessesToGc.size(); i++) {
8191 ProcessRecord proc = mProcessesToGc.get(i);
8192 pw.print(" Process "); pw.println(proc);
8193 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8194 pw.print(", last gced=");
8195 pw.print(now-proc.lastRequestedGc);
8196 pw.print(" ms ago, last lowMem=");
8197 pw.print(now-proc.lastLowMemory);
8198 pw.println(" ms ago");
8199
8200 }
8201 }
8202 return needSep;
8203 }
8204
8205 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8206 int opti, boolean dumpAll) {
8207 boolean needSep = false;
8208
8209 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008210 if (needSep) pw.println(" ");
8211 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008212 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008213 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008214 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008215 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8216 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8217 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8218 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8219 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008220 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008221 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008222 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008223 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008224 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008225 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008226
8227 if (needSep) pw.println(" ");
8228 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008229 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008230 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008231 "Proc", "PERS", true);
8232 needSep = true;
8233 }
8234
8235 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8236
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008237 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008238 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008239 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008240 if (mHeavyWeightProcess != null) {
8241 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8242 }
8243
8244 return true;
8245 }
8246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008247 /**
8248 * There are three ways to call this:
8249 * - no service specified: dump all the services
8250 * - a flattened component name that matched an existing service was specified as the
8251 * first arg: dump that one service
8252 * - the first arg isn't the flattened component name of an existing service:
8253 * dump all services whose component contains the first arg as a substring
8254 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008255 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8256 int opti, boolean dumpAll) {
8257 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008258
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008259 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008260 synchronized (this) {
8261 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008262 services.add(r1);
8263 }
8264 }
8265 } else {
8266 ComponentName componentName = name != null
8267 ? ComponentName.unflattenFromString(name) : null;
8268 int objectId = 0;
8269 if (componentName == null) {
8270 // Not a '/' separated full component name; maybe an object ID?
8271 try {
8272 objectId = Integer.parseInt(name, 16);
8273 name = null;
8274 componentName = null;
8275 } catch (RuntimeException e) {
8276 }
8277 }
8278
8279 synchronized (this) {
8280 for (ServiceRecord r1 : mServices.values()) {
8281 if (componentName != null) {
8282 if (r1.name.equals(componentName)) {
8283 services.add(r1);
8284 }
8285 } else if (name != null) {
8286 if (r1.name.flattenToString().contains(name)) {
8287 services.add(r1);
8288 }
8289 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008290 services.add(r1);
8291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008292 }
8293 }
8294 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008295
8296 if (services.size() <= 0) {
8297 return false;
8298 }
8299
8300 boolean needSep = false;
8301 for (int i=0; i<services.size(); i++) {
8302 if (needSep) {
8303 pw.println();
8304 }
8305 needSep = true;
8306 dumpService("", fd, pw, services.get(i), args, dumpAll);
8307 }
8308 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008309 }
8310
8311 /**
8312 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8313 * there is a thread associated with the service.
8314 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008315 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8316 final ServiceRecord r, String[] args, boolean dumpAll) {
8317 String innerPrefix = prefix + " ";
8318 synchronized (this) {
8319 pw.print(prefix); pw.print("SERVICE ");
8320 pw.print(r.shortName); pw.print(" ");
8321 pw.print(Integer.toHexString(System.identityHashCode(r)));
8322 pw.print(" pid=");
8323 if (r.app != null) pw.println(r.app.pid);
8324 else pw.println("(not running)");
8325 if (dumpAll) {
8326 r.dump(pw, innerPrefix);
8327 }
8328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008329 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008330 pw.print(prefix); pw.println(" Client:");
8331 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008332 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008333 TransferPipe tp = new TransferPipe();
8334 try {
8335 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8336 tp.setBufferPrefix(prefix + " ");
8337 tp.go(fd);
8338 } finally {
8339 tp.kill();
8340 }
8341 } catch (IOException e) {
8342 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008343 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008344 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008345 }
8346 }
8347 }
8348
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008349 static class ItemMatcher {
8350 ArrayList<ComponentName> components;
8351 ArrayList<String> strings;
8352 ArrayList<Integer> objects;
8353 boolean all;
8354
8355 ItemMatcher() {
8356 all = true;
8357 }
8358
8359 void build(String name) {
8360 ComponentName componentName = ComponentName.unflattenFromString(name);
8361 if (componentName != null) {
8362 if (components == null) {
8363 components = new ArrayList<ComponentName>();
8364 }
8365 components.add(componentName);
8366 all = false;
8367 } else {
8368 int objectId = 0;
8369 // Not a '/' separated full component name; maybe an object ID?
8370 try {
8371 objectId = Integer.parseInt(name, 16);
8372 if (objects == null) {
8373 objects = new ArrayList<Integer>();
8374 }
8375 objects.add(objectId);
8376 all = false;
8377 } catch (RuntimeException e) {
8378 // Not an integer; just do string match.
8379 if (strings == null) {
8380 strings = new ArrayList<String>();
8381 }
8382 strings.add(name);
8383 all = false;
8384 }
8385 }
8386 }
8387
8388 int build(String[] args, int opti) {
8389 for (; opti<args.length; opti++) {
8390 String name = args[opti];
8391 if ("--".equals(name)) {
8392 return opti+1;
8393 }
8394 build(name);
8395 }
8396 return opti;
8397 }
8398
8399 boolean match(Object object, ComponentName comp) {
8400 if (all) {
8401 return true;
8402 }
8403 if (components != null) {
8404 for (int i=0; i<components.size(); i++) {
8405 if (components.get(i).equals(comp)) {
8406 return true;
8407 }
8408 }
8409 }
8410 if (objects != null) {
8411 for (int i=0; i<objects.size(); i++) {
8412 if (System.identityHashCode(object) == objects.get(i)) {
8413 return true;
8414 }
8415 }
8416 }
8417 if (strings != null) {
8418 String flat = comp.flattenToString();
8419 for (int i=0; i<strings.size(); i++) {
8420 if (flat.contains(strings.get(i))) {
8421 return true;
8422 }
8423 }
8424 }
8425 return false;
8426 }
8427 }
8428
Dianne Hackborn625ac272010-09-17 18:29:22 -07008429 /**
8430 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008431 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008432 * - the cmd arg isn't the flattened component name of an existing activity:
8433 * dump all activity whose component contains the cmd as a substring
8434 * - A hex number of the ActivityRecord object instance.
8435 */
8436 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8437 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008438 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008439
8440 if ("all".equals(name)) {
8441 synchronized (this) {
8442 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008443 activities.add(r1);
8444 }
8445 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008446 } else if ("top".equals(name)) {
8447 synchronized (this) {
8448 final int N = mMainStack.mHistory.size();
8449 if (N > 0) {
8450 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8451 }
8452 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008453 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008454 ItemMatcher matcher = new ItemMatcher();
8455 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008456
8457 synchronized (this) {
8458 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008459 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008460 activities.add(r1);
8461 }
8462 }
8463 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008464 }
8465
8466 if (activities.size() <= 0) {
8467 return false;
8468 }
8469
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008470 String[] newArgs = new String[args.length - opti];
8471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8472
Dianne Hackborn30d71892010-12-11 10:37:55 -08008473 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008474 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008475 for (int i=activities.size()-1; i>=0; i--) {
8476 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008477 if (needSep) {
8478 pw.println();
8479 }
8480 needSep = true;
8481 synchronized (this) {
8482 if (lastTask != r.task) {
8483 lastTask = r.task;
8484 pw.print("TASK "); pw.print(lastTask.affinity);
8485 pw.print(" id="); pw.println(lastTask.taskId);
8486 if (dumpAll) {
8487 lastTask.dump(pw, " ");
8488 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008489 }
8490 }
8491 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008492 }
8493 return true;
8494 }
8495
8496 /**
8497 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8498 * there is a thread associated with the activity.
8499 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008500 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008501 final ActivityRecord r, String[] args, boolean dumpAll) {
8502 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008503 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008504 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8505 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8506 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008507 if (r.app != null) pw.println(r.app.pid);
8508 else pw.println("(not running)");
8509 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008510 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008511 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008512 }
8513 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008514 // flush anything that is already in the PrintWriter since the thread is going
8515 // to write to the file descriptor directly
8516 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008517 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008518 TransferPipe tp = new TransferPipe();
8519 try {
8520 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8521 innerPrefix, args);
8522 tp.go(fd);
8523 } finally {
8524 tp.kill();
8525 }
8526 } catch (IOException e) {
8527 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008528 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008529 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008530 }
8531 }
8532 }
8533
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008534 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8535 int opti, boolean dumpAll) {
8536 boolean needSep = false;
8537
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008538 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008539 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008540 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 pw.println(" Registered Receivers:");
8542 Iterator it = mRegisteredReceivers.values().iterator();
8543 while (it.hasNext()) {
8544 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008545 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008546 r.dump(pw, " ");
8547 }
8548 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008549
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008550 pw.println();
8551 pw.println(" Receiver Resolver Table:");
8552 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008553 needSep = true;
8554 }
8555
8556 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8557 || mPendingBroadcast != null) {
8558 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008559 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008560 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008561 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008562 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8563 pw.println(" Broadcast #" + i + ":");
8564 mParallelBroadcasts.get(i).dump(pw, " ");
8565 }
8566 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008567 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008568 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008569 }
8570 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8571 pw.println(" Serialized Broadcast #" + i + ":");
8572 mOrderedBroadcasts.get(i).dump(pw, " ");
8573 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008574 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008575 pw.println(" Pending broadcast:");
8576 if (mPendingBroadcast != null) {
8577 mPendingBroadcast.dump(pw, " ");
8578 } else {
8579 pw.println(" (null)");
8580 }
8581 needSep = true;
8582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008583
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008584 if (needSep) {
8585 pw.println();
8586 }
8587 pw.println(" Historical broadcasts:");
8588 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8589 BroadcastRecord r = mBroadcastHistory[i];
8590 if (r == null) {
8591 break;
8592 }
8593 if (dumpAll) {
8594 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8595 r.dump(pw, " ");
8596 } else {
8597 if (i >= 50) {
8598 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008599 break;
8600 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008601 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008602 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008603 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008604 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008605
8606 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008607 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008608 pw.println(" Sticky broadcasts:");
8609 StringBuilder sb = new StringBuilder(128);
8610 for (Map.Entry<String, ArrayList<Intent>> ent
8611 : mStickyBroadcasts.entrySet()) {
8612 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008613 if (dumpAll) {
8614 pw.println(":");
8615 ArrayList<Intent> intents = ent.getValue();
8616 final int N = intents.size();
8617 for (int i=0; i<N; i++) {
8618 sb.setLength(0);
8619 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008620 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008621 pw.println(sb.toString());
8622 Bundle bundle = intents.get(i).getExtras();
8623 if (bundle != null) {
8624 pw.print(" ");
8625 pw.println(bundle.toString());
8626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008627 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008628 } else {
8629 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008630 }
8631 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008632 needSep = true;
8633 }
8634
8635 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008636 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008637 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 pw.println(" mHandler:");
8639 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008640 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008642
8643 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 }
8645
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008646 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008647 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008648 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008649
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008650 ItemMatcher matcher = new ItemMatcher();
8651 matcher.build(args, opti);
8652
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008653 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8654 if (mServices.size() > 0) {
8655 pw.println(" Active services:");
8656 long nowReal = SystemClock.elapsedRealtime();
8657 Iterator<ServiceRecord> it = mServices.values().iterator();
8658 needSep = false;
8659 while (it.hasNext()) {
8660 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008661 if (!matcher.match(r, r.name)) {
8662 continue;
8663 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008664 if (needSep) {
8665 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008666 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008667 pw.print(" * "); pw.println(r);
8668 if (dumpAll) {
8669 r.dump(pw, " ");
8670 needSep = true;
8671 } else {
8672 pw.print(" app="); pw.println(r.app);
8673 pw.print(" created=");
8674 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8675 pw.print(" started="); pw.print(r.startRequested);
8676 pw.print(" connections="); pw.println(r.connections.size());
8677 }
8678 if (dumpClient && r.app != null && r.app.thread != null) {
8679 pw.println(" Client:");
8680 pw.flush();
8681 try {
8682 TransferPipe tp = new TransferPipe();
8683 try {
8684 r.app.thread.dumpService(
8685 tp.getWriteFd().getFileDescriptor(), r, args);
8686 tp.setBufferPrefix(" ");
8687 // Short timeout, since blocking here can
8688 // deadlock with the application.
8689 tp.go(fd, 2000);
8690 } finally {
8691 tp.kill();
8692 }
8693 } catch (IOException e) {
8694 pw.println(" Failure while dumping the service: " + e);
8695 } catch (RemoteException e) {
8696 pw.println(" Got a RemoteException while dumping the service");
8697 }
8698 needSep = true;
8699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008700 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008701 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008703
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008704 if (mPendingServices.size() > 0) {
8705 if (needSep) pw.println(" ");
8706 pw.println(" Pending services:");
8707 for (int i=0; i<mPendingServices.size(); i++) {
8708 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008709 if (!matcher.match(r, r.name)) {
8710 continue;
8711 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008712 pw.print(" * Pending "); pw.println(r);
8713 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008714 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008715 needSep = true;
8716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008717
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008718 if (mRestartingServices.size() > 0) {
8719 if (needSep) pw.println(" ");
8720 pw.println(" Restarting services:");
8721 for (int i=0; i<mRestartingServices.size(); i++) {
8722 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008723 if (!matcher.match(r, r.name)) {
8724 continue;
8725 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008726 pw.print(" * Restarting "); pw.println(r);
8727 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008728 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008729 needSep = true;
8730 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008731
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008732 if (mStoppingServices.size() > 0) {
8733 if (needSep) pw.println(" ");
8734 pw.println(" Stopping services:");
8735 for (int i=0; i<mStoppingServices.size(); i++) {
8736 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008737 if (!matcher.match(r, r.name)) {
8738 continue;
8739 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008740 pw.print(" * Stopping "); pw.println(r);
8741 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008743 needSep = true;
8744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008745
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008746 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008747 if (mServiceConnections.size() > 0) {
8748 if (needSep) pw.println(" ");
8749 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008750 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008751 = mServiceConnections.values().iterator();
8752 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008753 ArrayList<ConnectionRecord> r = it.next();
8754 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008755 ConnectionRecord cr = r.get(i);
8756 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8757 continue;
8758 }
8759 pw.print(" * "); pw.println(cr);
8760 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008762 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008763 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008764 }
8765 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008766
8767 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008768 }
8769
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008770 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8771 int opti, boolean dumpAll) {
8772 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008773
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008774 ItemMatcher matcher = new ItemMatcher();
8775 matcher.build(args, opti);
8776
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008777 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8778 if (mProvidersByClass.size() > 0) {
8779 if (needSep) pw.println(" ");
8780 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008781 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008782 = mProvidersByClass.entrySet().iterator();
8783 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008784 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008785 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008786 ComponentName comp = e.getKey();
8787 String cls = comp.getClassName();
8788 int end = cls.lastIndexOf('.');
8789 if (end > 0 && end < (cls.length()-2)) {
8790 cls = cls.substring(end+1);
8791 }
8792 if (!matcher.match(r, comp)) {
8793 continue;
8794 }
8795 pw.print(" * "); pw.print(cls); pw.print(" (");
8796 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008797 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008798 pw.println();
8799 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008800 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008801 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008802 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008803 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008804 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008805 } else {
8806 pw.println();
8807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008809 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008810 needSep = true;
8811 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008812
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008813 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008814 if (mProvidersByName.size() > 0) {
8815 pw.println(" ");
8816 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008817 Iterator<Map.Entry<String, ContentProviderRecord>> it
8818 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008819 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008820 Map.Entry<String, ContentProviderRecord> e = it.next();
8821 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008822 if (!matcher.match(r, r.name)) {
8823 continue;
8824 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008825 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8826 pw.println(r);
8827 }
8828 needSep = true;
8829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008830 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008831
8832 if (mLaunchingProviders.size() > 0) {
8833 if (needSep) pw.println(" ");
8834 pw.println(" Launching content providers:");
8835 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8836 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8837 pw.println(mLaunchingProviders.get(i));
8838 }
8839 needSep = true;
8840 }
8841
8842 if (mGrantedUriPermissions.size() > 0) {
8843 pw.println();
8844 pw.println("Granted Uri Permissions:");
8845 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8846 int uid = mGrantedUriPermissions.keyAt(i);
8847 HashMap<Uri, UriPermission> perms
8848 = mGrantedUriPermissions.valueAt(i);
8849 pw.print(" * UID "); pw.print(uid);
8850 pw.println(" holds:");
8851 for (UriPermission perm : perms.values()) {
8852 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008853 if (dumpAll) {
8854 perm.dump(pw, " ");
8855 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008856 }
8857 }
8858 needSep = true;
8859 }
8860
8861 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008862 }
8863
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008864 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8865 int opti, boolean dumpAll) {
8866 boolean needSep = false;
8867
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008868 if (this.mIntentSenderRecords.size() > 0) {
8869 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8870 Iterator<WeakReference<PendingIntentRecord>> it
8871 = mIntentSenderRecords.values().iterator();
8872 while (it.hasNext()) {
8873 WeakReference<PendingIntentRecord> ref = it.next();
8874 PendingIntentRecord rec = ref != null ? ref.get(): null;
8875 needSep = true;
8876 if (rec != null) {
8877 pw.print(" * "); pw.println(rec);
8878 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008880 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008881 } else {
8882 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 }
8884 }
8885 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008886
8887 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888 }
8889
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008890 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8891 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008892 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008893 boolean needNL = false;
8894 final String innerPrefix = prefix + " ";
8895 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008896 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008897 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008898 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008899 if (needNL) {
8900 pw.println(" ");
8901 needNL = false;
8902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008903 if (lastTask != r.task) {
8904 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008905 pw.print(prefix);
8906 pw.print(full ? "* " : " ");
8907 pw.println(lastTask);
8908 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008909 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008910 } else if (complete) {
8911 // Complete + brief == give a summary. Isn't that obvious?!?
8912 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008913 pw.print(prefix); pw.print(" ");
8914 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008915 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008917 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008918 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8919 pw.print(" #"); pw.print(i); pw.print(": ");
8920 pw.println(r);
8921 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008922 r.dump(pw, innerPrefix);
8923 } else if (complete) {
8924 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008925 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008926 if (r.app != null) {
8927 pw.print(innerPrefix); pw.println(r.app);
8928 }
8929 }
8930 if (client && r.app != null && r.app.thread != null) {
8931 // flush anything that is already in the PrintWriter since the thread is going
8932 // to write to the file descriptor directly
8933 pw.flush();
8934 try {
8935 TransferPipe tp = new TransferPipe();
8936 try {
8937 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8938 innerPrefix, args);
8939 // Short timeout, since blocking here can
8940 // deadlock with the application.
8941 tp.go(fd, 2000);
8942 } finally {
8943 tp.kill();
8944 }
8945 } catch (IOException e) {
8946 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8947 } catch (RemoteException e) {
8948 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8949 }
8950 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008952 }
8953 }
8954
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008955 private static String buildOomTag(String prefix, String space, int val, int base) {
8956 if (val == base) {
8957 if (space == null) return prefix;
8958 return prefix + " ";
8959 }
8960 return prefix + "+" + Integer.toString(val-base);
8961 }
8962
8963 private static final int dumpProcessList(PrintWriter pw,
8964 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008965 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008966 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008967 final int N = list.size()-1;
8968 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008969 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008970 pw.println(String.format("%s%s #%2d: %s",
8971 prefix, (r.persistent ? persistentLabel : normalLabel),
8972 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973 if (r.persistent) {
8974 numPers++;
8975 }
8976 }
8977 return numPers;
8978 }
8979
Dianne Hackborn287952c2010-09-22 22:34:31 -07008980 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008981 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008982 String prefix, String normalLabel, String persistentLabel,
8983 boolean inclDetails) {
8984
Dianne Hackborn905577f2011-09-07 18:31:28 -07008985 ArrayList<Pair<ProcessRecord, Integer>> list
8986 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8987 for (int i=0; i<origList.size(); i++) {
8988 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8989 }
8990
8991 Comparator<Pair<ProcessRecord, Integer>> comparator
8992 = new Comparator<Pair<ProcessRecord, Integer>>() {
8993 @Override
8994 public int compare(Pair<ProcessRecord, Integer> object1,
8995 Pair<ProcessRecord, Integer> object2) {
8996 if (object1.first.setAdj != object2.first.setAdj) {
8997 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8998 }
8999 if (object1.second.intValue() != object2.second.intValue()) {
9000 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9001 }
9002 return 0;
9003 }
9004 };
9005
9006 Collections.sort(list, comparator);
9007
Dianne Hackborn287952c2010-09-22 22:34:31 -07009008 final long curRealtime = SystemClock.elapsedRealtime();
9009 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9010 final long curUptime = SystemClock.uptimeMillis();
9011 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9012
9013 final int N = list.size()-1;
9014 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009015 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009016 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009017 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009018 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009019 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9020 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009021 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9022 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009023 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9024 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009025 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9026 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009027 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9028 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9029 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9030 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9031 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9032 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9033 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9034 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9035 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9036 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009037 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9038 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009039 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9040 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009041 } else {
9042 oomAdj = Integer.toString(r.setAdj);
9043 }
9044 String schedGroup;
9045 switch (r.setSchedGroup) {
9046 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9047 schedGroup = "B";
9048 break;
9049 case Process.THREAD_GROUP_DEFAULT:
9050 schedGroup = "F";
9051 break;
9052 default:
9053 schedGroup = Integer.toString(r.setSchedGroup);
9054 break;
9055 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009056 String foreground;
9057 if (r.foregroundActivities) {
9058 foreground = "A";
9059 } else if (r.foregroundServices) {
9060 foreground = "S";
9061 } else {
9062 foreground = " ";
9063 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009064 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009065 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009066 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009067 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009068 if (r.adjSource != null || r.adjTarget != null) {
9069 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009070 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009071 if (r.adjTarget instanceof ComponentName) {
9072 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9073 } else if (r.adjTarget != null) {
9074 pw.print(r.adjTarget.toString());
9075 } else {
9076 pw.print("{null}");
9077 }
9078 pw.print("<=");
9079 if (r.adjSource instanceof ProcessRecord) {
9080 pw.print("Proc{");
9081 pw.print(((ProcessRecord)r.adjSource).toShortString());
9082 pw.println("}");
9083 } else if (r.adjSource != null) {
9084 pw.println(r.adjSource.toString());
9085 } else {
9086 pw.println("{null}");
9087 }
9088 }
9089 if (inclDetails) {
9090 pw.print(prefix);
9091 pw.print(" ");
9092 pw.print("oom: max="); pw.print(r.maxAdj);
9093 pw.print(" hidden="); pw.print(r.hiddenAdj);
9094 pw.print(" curRaw="); pw.print(r.curRawAdj);
9095 pw.print(" setRaw="); pw.print(r.setRawAdj);
9096 pw.print(" cur="); pw.print(r.curAdj);
9097 pw.print(" set="); pw.println(r.setAdj);
9098 pw.print(prefix);
9099 pw.print(" ");
9100 pw.print("keeping="); pw.print(r.keeping);
9101 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009102 pw.print(" empty="); pw.print(r.empty);
9103 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009104
9105 if (!r.keeping) {
9106 if (r.lastWakeTime != 0) {
9107 long wtime;
9108 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9109 synchronized (stats) {
9110 wtime = stats.getProcessWakeTime(r.info.uid,
9111 r.pid, curRealtime);
9112 }
9113 long timeUsed = wtime - r.lastWakeTime;
9114 pw.print(prefix);
9115 pw.print(" ");
9116 pw.print("keep awake over ");
9117 TimeUtils.formatDuration(realtimeSince, pw);
9118 pw.print(" used ");
9119 TimeUtils.formatDuration(timeUsed, pw);
9120 pw.print(" (");
9121 pw.print((timeUsed*100)/realtimeSince);
9122 pw.println("%)");
9123 }
9124 if (r.lastCpuTime != 0) {
9125 long timeUsed = r.curCpuTime - r.lastCpuTime;
9126 pw.print(prefix);
9127 pw.print(" ");
9128 pw.print("run cpu over ");
9129 TimeUtils.formatDuration(uptimeSince, pw);
9130 pw.print(" used ");
9131 TimeUtils.formatDuration(timeUsed, pw);
9132 pw.print(" (");
9133 pw.print((timeUsed*100)/uptimeSince);
9134 pw.println("%)");
9135 }
9136 }
9137 }
9138 }
9139 }
9140
Dianne Hackbornb437e092011-08-05 17:50:29 -07009141 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009142 ArrayList<ProcessRecord> procs;
9143 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009144 if (args != null && args.length > start
9145 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009146 procs = new ArrayList<ProcessRecord>();
9147 int pid = -1;
9148 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009149 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009150 } catch (NumberFormatException e) {
9151
9152 }
9153 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9154 ProcessRecord proc = mLruProcesses.get(i);
9155 if (proc.pid == pid) {
9156 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009157 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009158 procs.add(proc);
9159 }
9160 }
9161 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009162 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009163 return null;
9164 }
9165 } else {
9166 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9167 }
9168 }
9169 return procs;
9170 }
9171
9172 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9173 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009174 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009175 if (procs == null) {
9176 return;
9177 }
9178
9179 long uptime = SystemClock.uptimeMillis();
9180 long realtime = SystemClock.elapsedRealtime();
9181 pw.println("Applications Graphics Acceleration Info:");
9182 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9183
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009184 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9185 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009186 if (r.thread != null) {
9187 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9188 pw.flush();
9189 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009190 TransferPipe tp = new TransferPipe();
9191 try {
9192 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9193 tp.go(fd);
9194 } finally {
9195 tp.kill();
9196 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009197 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009198 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009199 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009200 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009201 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009202 pw.flush();
9203 }
9204 }
9205 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009206 }
9207
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009208 final static class MemItem {
9209 final String label;
9210 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009211 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009212
9213 public MemItem(String _label, long _pss) {
9214 label = _label;
9215 pss = _pss;
9216 }
9217 }
9218
Dianne Hackbornb437e092011-08-05 17:50:29 -07009219 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9220 boolean sort) {
9221 if (sort) {
9222 Collections.sort(items, new Comparator<MemItem>() {
9223 @Override
9224 public int compare(MemItem lhs, MemItem rhs) {
9225 if (lhs.pss < rhs.pss) {
9226 return 1;
9227 } else if (lhs.pss > rhs.pss) {
9228 return -1;
9229 }
9230 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009231 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009232 });
9233 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009234
9235 for (int i=0; i<items.size(); i++) {
9236 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009237 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9238 if (mi.subitems != null) {
9239 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9240 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009241 }
9242 }
9243
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009244 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9245 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009246 boolean dumpAll = false;
9247
9248 int opti = 0;
9249 while (opti < args.length) {
9250 String opt = args[opti];
9251 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9252 break;
9253 }
9254 opti++;
9255 if ("-a".equals(opt)) {
9256 dumpAll = true;
9257 } else if ("-h".equals(opt)) {
9258 pw.println("meminfo dump options: [-a] [process]");
9259 pw.println(" -a: include all available information for each process.");
9260 pw.println("If [process] is specified it can be the name or ");
9261 pw.println("pid of a specific process to dump.");
9262 return;
9263 } else {
9264 pw.println("Unknown argument: " + opt + "; use -h for help");
9265 }
9266 }
9267
9268 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009269 if (procs == null) {
9270 return;
9271 }
9272
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009273 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009274 long uptime = SystemClock.uptimeMillis();
9275 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009276
9277 if (procs.size() == 1 || isCheckinRequest) {
9278 dumpAll = true;
9279 }
9280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009281 if (isCheckinRequest) {
9282 // short checkin version
9283 pw.println(uptime + "," + realtime);
9284 pw.flush();
9285 } else {
9286 pw.println("Applications Memory Usage (kB):");
9287 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9288 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009289
Dianne Hackbornb437e092011-08-05 17:50:29 -07009290 String[] innerArgs = new String[args.length-opti];
9291 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9292
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009293 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9294 long nativePss=0, dalvikPss=0, otherPss=0;
9295 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9296
Dianne Hackbornb437e092011-08-05 17:50:29 -07009297 final int[] oomAdj = new int[] {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009298 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
Dianne Hackborn7d608422011-08-07 16:24:18 -07009299 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009300 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009301 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009302 };
9303 final String[] oomLabel = new String[] {
9304 "System", "Persistent", "Foreground",
9305 "Visible", "Perceptible", "Heavy Weight",
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009306 "Backup", "A Services", "Home", "Previous",
9307 "B Services", "Background"
Dianne Hackbornb437e092011-08-05 17:50:29 -07009308 };
9309 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009310 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009311
9312 long totalPss = 0;
9313
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009314 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9315 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009316 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009317 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9319 pw.flush();
9320 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009321 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009322 if (dumpAll) {
9323 try {
9324 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9325 } catch (RemoteException e) {
9326 if (!isCheckinRequest) {
9327 pw.println("Got RemoteException!");
9328 pw.flush();
9329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009330 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009331 } else {
9332 mi = new Debug.MemoryInfo();
9333 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009334 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009335
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009336 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009337 long myTotalPss = mi.getTotalPss();
9338 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009339 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9340 myTotalPss);
9341 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009342
9343 nativePss += mi.nativePss;
9344 dalvikPss += mi.dalvikPss;
9345 otherPss += mi.otherPss;
9346 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9347 long mem = mi.getOtherPss(j);
9348 miscPss[j] += mem;
9349 otherPss -= mem;
9350 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009351
9352 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9353 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9354 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009355 if (oomProcs[oomIndex] == null) {
9356 oomProcs[oomIndex] = new ArrayList<MemItem>();
9357 }
9358 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009359 break;
9360 }
9361 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363 }
9364 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009365
9366 if (!isCheckinRequest && procs.size() > 1) {
9367 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9368
9369 catMems.add(new MemItem("Native", nativePss));
9370 catMems.add(new MemItem("Dalvik", dalvikPss));
9371 catMems.add(new MemItem("Unknown", otherPss));
9372 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9373 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9374 }
9375
Dianne Hackbornb437e092011-08-05 17:50:29 -07009376 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9377 for (int j=0; j<oomPss.length; j++) {
9378 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009379 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9380 item.subitems = oomProcs[j];
9381 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009382 }
9383 }
9384
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009385 pw.println();
9386 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009387 dumpMemItems(pw, " ", procMems, true);
9388 pw.println();
9389 pw.println("Total PSS by OOM adjustment:");
9390 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009391 pw.println();
9392 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009393 dumpMemItems(pw, " ", catMems, true);
9394 pw.println();
9395 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009397 }
9398
9399 /**
9400 * Searches array of arguments for the specified string
9401 * @param args array of argument strings
9402 * @param value value to search for
9403 * @return true if the value is contained in the array
9404 */
9405 private static boolean scanArgs(String[] args, String value) {
9406 if (args != null) {
9407 for (String arg : args) {
9408 if (value.equals(arg)) {
9409 return true;
9410 }
9411 }
9412 }
9413 return false;
9414 }
9415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009416 private final void killServicesLocked(ProcessRecord app,
9417 boolean allowRestart) {
9418 // Report disconnected services.
9419 if (false) {
9420 // XXX we are letting the client link to the service for
9421 // death notifications.
9422 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009423 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009425 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009426 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009427 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009428 = r.connections.values().iterator();
9429 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009430 ArrayList<ConnectionRecord> cl = jt.next();
9431 for (int i=0; i<cl.size(); i++) {
9432 ConnectionRecord c = cl.get(i);
9433 if (c.binding.client != app) {
9434 try {
9435 //c.conn.connected(r.className, null);
9436 } catch (Exception e) {
9437 // todo: this should be asynchronous!
9438 Slog.w(TAG, "Exception thrown disconnected servce "
9439 + r.shortName
9440 + " from app " + app.processName, e);
9441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 }
9443 }
9444 }
9445 }
9446 }
9447 }
9448 }
9449
9450 // Clean up any connections this application has to other services.
9451 if (app.connections.size() > 0) {
9452 Iterator<ConnectionRecord> it = app.connections.iterator();
9453 while (it.hasNext()) {
9454 ConnectionRecord r = it.next();
9455 removeConnectionLocked(r, app, null);
9456 }
9457 }
9458 app.connections.clear();
9459
9460 if (app.services.size() != 0) {
9461 // Any services running in the application need to be placed
9462 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009463 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009464 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009465 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009466 synchronized (sr.stats.getBatteryStats()) {
9467 sr.stats.stopLaunchedLocked();
9468 }
9469 sr.app = null;
9470 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009471 if (mStoppingServices.remove(sr)) {
9472 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9473 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009474
9475 boolean hasClients = sr.bindings.size() > 0;
9476 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009477 Iterator<IntentBindRecord> bindings
9478 = sr.bindings.values().iterator();
9479 while (bindings.hasNext()) {
9480 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009481 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009482 + ": shouldUnbind=" + b.hasBound);
9483 b.binder = null;
9484 b.requested = b.received = b.hasBound = false;
9485 }
9486 }
9487
Dianne Hackborn070783f2010-12-29 16:46:28 -08009488 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9489 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009490 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009492 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009493 sr.crashCount, sr.shortName, app.pid);
9494 bringDownServiceLocked(sr, true);
9495 } else if (!allowRestart) {
9496 bringDownServiceLocked(sr, true);
9497 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009498 boolean canceled = scheduleServiceRestartLocked(sr, true);
9499
9500 // Should the service remain running? Note that in the
9501 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009502 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009503 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9504 if (sr.pendingStarts.size() == 0) {
9505 sr.startRequested = false;
9506 if (!hasClients) {
9507 // Whoops, no reason to restart!
9508 bringDownServiceLocked(sr, true);
9509 }
9510 }
9511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 }
9513 }
9514
9515 if (!allowRestart) {
9516 app.services.clear();
9517 }
9518 }
9519
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009520 // Make sure we have no more records on the stopping list.
9521 int i = mStoppingServices.size();
9522 while (i > 0) {
9523 i--;
9524 ServiceRecord sr = mStoppingServices.get(i);
9525 if (sr.app == app) {
9526 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009527 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009528 }
9529 }
9530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 app.executingServices.clear();
9532 }
9533
9534 private final void removeDyingProviderLocked(ProcessRecord proc,
9535 ContentProviderRecord cpr) {
9536 synchronized (cpr) {
9537 cpr.launchingApp = null;
9538 cpr.notifyAll();
9539 }
9540
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009541 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009542 String names[] = cpr.info.authority.split(";");
9543 for (int j = 0; j < names.length; j++) {
9544 mProvidersByName.remove(names[j]);
9545 }
9546
9547 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9548 while (cit.hasNext()) {
9549 ProcessRecord capp = cit.next();
9550 if (!capp.persistent && capp.thread != null
9551 && capp.pid != 0
9552 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009553 Slog.i(TAG, "Kill " + capp.processName
9554 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009555 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009556 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009557 capp.processName, capp.setAdj, "dying provider "
9558 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009559 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009560 }
9561 }
9562
9563 mLaunchingProviders.remove(cpr);
9564 }
9565
9566 /**
9567 * Main code for cleaning up a process when it has gone away. This is
9568 * called both as a result of the process dying, or directly when stopping
9569 * a process when running in single process mode.
9570 */
9571 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009572 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009573 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009574 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009575 }
9576
Dianne Hackborn36124872009-10-08 16:22:03 -07009577 mProcessesToGc.remove(app);
9578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009579 // Dismiss any open dialogs.
9580 if (app.crashDialog != null) {
9581 app.crashDialog.dismiss();
9582 app.crashDialog = null;
9583 }
9584 if (app.anrDialog != null) {
9585 app.anrDialog.dismiss();
9586 app.anrDialog = null;
9587 }
9588 if (app.waitDialog != null) {
9589 app.waitDialog.dismiss();
9590 app.waitDialog = null;
9591 }
9592
9593 app.crashing = false;
9594 app.notResponding = false;
9595
9596 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009597 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009598 app.thread = null;
9599 app.forcingToForeground = null;
9600 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009601 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009602 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009603 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009605 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606
9607 boolean restart = false;
9608
9609 int NL = mLaunchingProviders.size();
9610
9611 // Remove published content providers.
9612 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009613 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009614 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009615 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009617 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618
9619 // See if someone is waiting for this provider... in which
9620 // case we don't remove it, but just let it restart.
9621 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009622 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009623 for (; i<NL; i++) {
9624 if (mLaunchingProviders.get(i) == cpr) {
9625 restart = true;
9626 break;
9627 }
9628 }
9629 } else {
9630 i = NL;
9631 }
9632
9633 if (i >= NL) {
9634 removeDyingProviderLocked(app, cpr);
9635 NL = mLaunchingProviders.size();
9636 }
9637 }
9638 app.pubProviders.clear();
9639 }
9640
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009641 // Take care of any launching providers waiting for this process.
9642 if (checkAppInLaunchingProvidersLocked(app, false)) {
9643 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009644 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009646 // Unregister from connected content providers.
9647 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009648 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009649 while (it.hasNext()) {
9650 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9651 cpr.clients.remove(app);
9652 }
9653 app.conProviders.clear();
9654 }
9655
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009656 // At this point there may be remaining entries in mLaunchingProviders
9657 // where we were the only one waiting, so they are no longer of use.
9658 // Look for these and clean up if found.
9659 // XXX Commented out for now. Trying to figure out a way to reproduce
9660 // the actual situation to identify what is actually going on.
9661 if (false) {
9662 for (int i=0; i<NL; i++) {
9663 ContentProviderRecord cpr = (ContentProviderRecord)
9664 mLaunchingProviders.get(i);
9665 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9666 synchronized (cpr) {
9667 cpr.launchingApp = null;
9668 cpr.notifyAll();
9669 }
9670 }
9671 }
9672 }
9673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 skipCurrentReceiverLocked(app);
9675
9676 // Unregister any receivers.
9677 if (app.receivers.size() > 0) {
9678 Iterator<ReceiverList> it = app.receivers.iterator();
9679 while (it.hasNext()) {
9680 removeReceiverLocked(it.next());
9681 }
9682 app.receivers.clear();
9683 }
9684
Christopher Tate181fafa2009-05-14 11:12:14 -07009685 // If the app is undergoing backup, tell the backup manager about it
9686 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009687 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009688 try {
9689 IBackupManager bm = IBackupManager.Stub.asInterface(
9690 ServiceManager.getService(Context.BACKUP_SERVICE));
9691 bm.agentDisconnected(app.info.packageName);
9692 } catch (RemoteException e) {
9693 // can't happen; backup manager is local
9694 }
9695 }
9696
Jeff Sharkey287bd832011-05-28 19:36:26 -07009697 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009699 // If the caller is restarting this app, then leave it in its
9700 // current lists and let the caller take care of it.
9701 if (restarting) {
9702 return;
9703 }
9704
9705 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009706 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009707 "Removing non-persistent process during cleanup: " + app);
9708 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009709 if (mHeavyWeightProcess == app) {
9710 mHeavyWeightProcess = null;
9711 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9712 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 } else if (!app.removed) {
9714 // This app is persistent, so we need to keep its record around.
9715 // If it is not already on the pending app list, add it there
9716 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009717 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9718 mPersistentStartingProcesses.add(app);
9719 restart = true;
9720 }
9721 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009722 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9723 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009724 mProcessesOnHold.remove(app);
9725
The Android Open Source Project4df24232009-03-05 14:34:35 -08009726 if (app == mHomeProcess) {
9727 mHomeProcess = null;
9728 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009729 if (app == mPreviousProcess) {
9730 mPreviousProcess = null;
9731 }
9732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009733 if (restart) {
9734 // We have components that still need to be running in the
9735 // process, so re-launch it.
9736 mProcessNames.put(app.processName, app.info.uid, app);
9737 startProcessLocked(app, "restart", app.processName);
9738 } else if (app.pid > 0 && app.pid != MY_PID) {
9739 // Goodbye!
9740 synchronized (mPidsSelfLocked) {
9741 mPidsSelfLocked.remove(app.pid);
9742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9743 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009744 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 }
9746 }
9747
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009748 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9749 // Look through the content providers we are waiting to have launched,
9750 // and if any run in this process then either schedule a restart of
9751 // the process or kill the client waiting for it if this process has
9752 // gone bad.
9753 int NL = mLaunchingProviders.size();
9754 boolean restart = false;
9755 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009756 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009757 if (cpr.launchingApp == app) {
9758 if (!alwaysBad && !app.bad) {
9759 restart = true;
9760 } else {
9761 removeDyingProviderLocked(app, cpr);
9762 NL = mLaunchingProviders.size();
9763 }
9764 }
9765 }
9766 return restart;
9767 }
9768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 // =========================================================
9770 // SERVICES
9771 // =========================================================
9772
9773 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9774 ActivityManager.RunningServiceInfo info =
9775 new ActivityManager.RunningServiceInfo();
9776 info.service = r.name;
9777 if (r.app != null) {
9778 info.pid = r.app.pid;
9779 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009780 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009781 info.process = r.processName;
9782 info.foreground = r.isForeground;
9783 info.activeSince = r.createTime;
9784 info.started = r.startRequested;
9785 info.clientCount = r.connections.size();
9786 info.crashCount = r.crashCount;
9787 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009788 if (r.isForeground) {
9789 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9790 }
9791 if (r.startRequested) {
9792 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9793 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009794 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009795 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9796 }
9797 if (r.app != null && r.app.persistent) {
9798 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9799 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009800
9801 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9802 for (int i=0; i<connl.size(); i++) {
9803 ConnectionRecord conn = connl.get(i);
9804 if (conn.clientLabel != 0) {
9805 info.clientPackage = conn.binding.client.info.packageName;
9806 info.clientLabel = conn.clientLabel;
9807 return info;
9808 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009809 }
9810 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009811 return info;
9812 }
9813
9814 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9815 int flags) {
9816 synchronized (this) {
9817 ArrayList<ActivityManager.RunningServiceInfo> res
9818 = new ArrayList<ActivityManager.RunningServiceInfo>();
9819
9820 if (mServices.size() > 0) {
9821 Iterator<ServiceRecord> it = mServices.values().iterator();
9822 while (it.hasNext() && res.size() < maxNum) {
9823 res.add(makeRunningServiceInfoLocked(it.next()));
9824 }
9825 }
9826
9827 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9828 ServiceRecord r = mRestartingServices.get(i);
9829 ActivityManager.RunningServiceInfo info =
9830 makeRunningServiceInfoLocked(r);
9831 info.restarting = r.nextRestartTime;
9832 res.add(info);
9833 }
9834
9835 return res;
9836 }
9837 }
9838
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009839 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9840 synchronized (this) {
9841 ServiceRecord r = mServices.get(name);
9842 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009843 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9844 for (int i=0; i<conn.size(); i++) {
9845 if (conn.get(i).clientIntent != null) {
9846 return conn.get(i).clientIntent;
9847 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009848 }
9849 }
9850 }
9851 }
9852 return null;
9853 }
9854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009855 private final ServiceRecord findServiceLocked(ComponentName name,
9856 IBinder token) {
9857 ServiceRecord r = mServices.get(name);
9858 return r == token ? r : null;
9859 }
9860
9861 private final class ServiceLookupResult {
9862 final ServiceRecord record;
9863 final String permission;
9864
9865 ServiceLookupResult(ServiceRecord _record, String _permission) {
9866 record = _record;
9867 permission = _permission;
9868 }
9869 };
9870
9871 private ServiceLookupResult findServiceLocked(Intent service,
9872 String resolvedType) {
9873 ServiceRecord r = null;
9874 if (service.getComponent() != null) {
9875 r = mServices.get(service.getComponent());
9876 }
9877 if (r == null) {
9878 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9879 r = mServicesByIntent.get(filter);
9880 }
9881
9882 if (r == null) {
9883 try {
9884 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009885 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009886 service, resolvedType, 0);
9887 ServiceInfo sInfo =
9888 rInfo != null ? rInfo.serviceInfo : null;
9889 if (sInfo == null) {
9890 return null;
9891 }
9892
9893 ComponentName name = new ComponentName(
9894 sInfo.applicationInfo.packageName, sInfo.name);
9895 r = mServices.get(name);
9896 } catch (RemoteException ex) {
9897 // pm is in same process, this will never happen.
9898 }
9899 }
9900 if (r != null) {
9901 int callingPid = Binder.getCallingPid();
9902 int callingUid = Binder.getCallingUid();
9903 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009904 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009906 if (!r.exported) {
9907 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9908 + " from pid=" + callingPid
9909 + ", uid=" + callingUid
9910 + " that is not exported from uid " + r.appInfo.uid);
9911 return new ServiceLookupResult(null, "not exported from uid "
9912 + r.appInfo.uid);
9913 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009914 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 + " from pid=" + callingPid
9916 + ", uid=" + callingUid
9917 + " requires " + r.permission);
9918 return new ServiceLookupResult(null, r.permission);
9919 }
9920 return new ServiceLookupResult(r, null);
9921 }
9922 return null;
9923 }
9924
9925 private class ServiceRestarter implements Runnable {
9926 private ServiceRecord mService;
9927
9928 void setService(ServiceRecord service) {
9929 mService = service;
9930 }
9931
9932 public void run() {
9933 synchronized(ActivityManagerService.this) {
9934 performServiceRestartLocked(mService);
9935 }
9936 }
9937 }
9938
9939 private ServiceLookupResult retrieveServiceLocked(Intent service,
9940 String resolvedType, int callingPid, int callingUid) {
9941 ServiceRecord r = null;
9942 if (service.getComponent() != null) {
9943 r = mServices.get(service.getComponent());
9944 }
9945 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9946 r = mServicesByIntent.get(filter);
9947 if (r == null) {
9948 try {
9949 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009950 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009951 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 ServiceInfo sInfo =
9953 rInfo != null ? rInfo.serviceInfo : null;
9954 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009955 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 ": not found");
9957 return null;
9958 }
9959
9960 ComponentName name = new ComponentName(
9961 sInfo.applicationInfo.packageName, sInfo.name);
9962 r = mServices.get(name);
9963 if (r == null) {
9964 filter = new Intent.FilterComparison(service.cloneFilter());
9965 ServiceRestarter res = new ServiceRestarter();
9966 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9967 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9968 synchronized (stats) {
9969 ss = stats.getServiceStatsLocked(
9970 sInfo.applicationInfo.uid, sInfo.packageName,
9971 sInfo.name);
9972 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009973 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009974 res.setService(r);
9975 mServices.put(name, r);
9976 mServicesByIntent.put(filter, r);
9977
9978 // Make sure this component isn't in the pending list.
9979 int N = mPendingServices.size();
9980 for (int i=0; i<N; i++) {
9981 ServiceRecord pr = mPendingServices.get(i);
9982 if (pr.name.equals(name)) {
9983 mPendingServices.remove(i);
9984 i--;
9985 N--;
9986 }
9987 }
9988 }
9989 } catch (RemoteException ex) {
9990 // pm is in same process, this will never happen.
9991 }
9992 }
9993 if (r != null) {
9994 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009995 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009997 if (!r.exported) {
9998 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9999 + " from pid=" + callingPid
10000 + ", uid=" + callingUid
10001 + " that is not exported from uid " + r.appInfo.uid);
10002 return new ServiceLookupResult(null, "not exported from uid "
10003 + r.appInfo.uid);
10004 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010005 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010006 + " from pid=" + callingPid
10007 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010008 + " requires " + r.permission);
10009 return new ServiceLookupResult(null, r.permission);
10010 }
10011 return new ServiceLookupResult(r, null);
10012 }
10013 return null;
10014 }
10015
Dianne Hackborn287952c2010-09-22 22:34:31 -070010016 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10017 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10018 + why + " of " + r + " in app " + r.app);
10019 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10020 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010021 long now = SystemClock.uptimeMillis();
10022 if (r.executeNesting == 0 && r.app != null) {
10023 if (r.app.executingServices.size() == 0) {
10024 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10025 msg.obj = r.app;
10026 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10027 }
10028 r.app.executingServices.add(r);
10029 }
10030 r.executeNesting++;
10031 r.executingStart = now;
10032 }
10033
10034 private final void sendServiceArgsLocked(ServiceRecord r,
10035 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010036 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010037 if (N == 0) {
10038 return;
10039 }
10040
Dianne Hackborn39792d22010-08-19 18:01:52 -070010041 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010042 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010043 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010044 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10045 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010046 if (si.intent == null && N > 1) {
10047 // If somehow we got a dummy null intent in the middle,
10048 // then skip it. DO NOT skip a null intent when it is
10049 // the only one in the list -- this is to support the
10050 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010051 continue;
10052 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010053 si.deliveredTime = SystemClock.uptimeMillis();
10054 r.deliveredStarts.add(si);
10055 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010056 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010057 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010058 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010059 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010060 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 if (!oomAdjusted) {
10062 oomAdjusted = true;
10063 updateOomAdjLocked(r.app);
10064 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010065 int flags = 0;
10066 if (si.deliveryCount > 0) {
10067 flags |= Service.START_FLAG_RETRY;
10068 }
10069 if (si.doneExecutingCount > 0) {
10070 flags |= Service.START_FLAG_REDELIVERY;
10071 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010072 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010073 } catch (RemoteException e) {
10074 // Remote process gone... we'll let the normal cleanup take
10075 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010076 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010077 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010078 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010079 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010080 break;
10081 }
10082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 }
10084
10085 private final boolean requestServiceBindingLocked(ServiceRecord r,
10086 IntentBindRecord i, boolean rebind) {
10087 if (r.app == null || r.app.thread == null) {
10088 // If service is not currently running, can't yet bind.
10089 return false;
10090 }
10091 if ((!i.requested || rebind) && i.apps.size() > 0) {
10092 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010093 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010094 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10095 if (!rebind) {
10096 i.requested = true;
10097 }
10098 i.hasBound = true;
10099 i.doRebind = false;
10100 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010101 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010102 return false;
10103 }
10104 }
10105 return true;
10106 }
10107
10108 private final void requestServiceBindingsLocked(ServiceRecord r) {
10109 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10110 while (bindings.hasNext()) {
10111 IntentBindRecord i = bindings.next();
10112 if (!requestServiceBindingLocked(r, i, false)) {
10113 break;
10114 }
10115 }
10116 }
10117
10118 private final void realStartServiceLocked(ServiceRecord r,
10119 ProcessRecord app) throws RemoteException {
10120 if (app.thread == null) {
10121 throw new RemoteException();
10122 }
10123
10124 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010125 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126
10127 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010128 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010129 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010130
10131 boolean created = false;
10132 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010133 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010134 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010135 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010136 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010137 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010138 synchronized (r.stats.getBatteryStats()) {
10139 r.stats.startLaunchedLocked();
10140 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010141 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010142 app.thread.scheduleCreateService(r, r.serviceInfo,
10143 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010144 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010145 created = true;
10146 } finally {
10147 if (!created) {
10148 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010149 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010150 }
10151 }
10152
10153 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010154
10155 // If the service is in the started state, and there are no
10156 // pending arguments, then fake up one so its onStartCommand() will
10157 // be called.
10158 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010159 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10160 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010161 }
10162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010163 sendServiceArgsLocked(r, true);
10164 }
10165
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010166 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10167 boolean allowCancel) {
10168 boolean canceled = false;
10169
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010170 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010171 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010172 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010173
Dianne Hackborn070783f2010-12-29 16:46:28 -080010174 if ((r.serviceInfo.applicationInfo.flags
10175 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10176 minDuration /= 4;
10177 }
10178
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010179 // Any delivered but not yet finished starts should be put back
10180 // on the pending list.
10181 final int N = r.deliveredStarts.size();
10182 if (N > 0) {
10183 for (int i=N-1; i>=0; i--) {
10184 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010185 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010186 if (si.intent == null) {
10187 // We'll generate this again if needed.
10188 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10189 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10190 r.pendingStarts.add(0, si);
10191 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10192 dur *= 2;
10193 if (minDuration < dur) minDuration = dur;
10194 if (resetTime < dur) resetTime = dur;
10195 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010196 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010197 + r.name);
10198 canceled = true;
10199 }
10200 }
10201 r.deliveredStarts.clear();
10202 }
10203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010204 r.totalRestartCount++;
10205 if (r.restartDelay == 0) {
10206 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010207 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 } else {
10209 // If it has been a "reasonably long time" since the service
10210 // was started, then reset our restart duration back to
10211 // the beginning, so we don't infinitely increase the duration
10212 // on a service that just occasionally gets killed (which is
10213 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010214 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010215 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010216 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010217 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010218 if ((r.serviceInfo.applicationInfo.flags
10219 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10220 // Services in peristent processes will restart much more
10221 // quickly, since they are pretty important. (Think SystemUI).
10222 r.restartDelay += minDuration/2;
10223 } else {
10224 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10225 if (r.restartDelay < minDuration) {
10226 r.restartDelay = minDuration;
10227 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010229 }
10230 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010231
10232 r.nextRestartTime = now + r.restartDelay;
10233
10234 // Make sure that we don't end up restarting a bunch of services
10235 // all at the same time.
10236 boolean repeat;
10237 do {
10238 repeat = false;
10239 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10240 ServiceRecord r2 = mRestartingServices.get(i);
10241 if (r2 != r && r.nextRestartTime
10242 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10243 && r.nextRestartTime
10244 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10245 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10246 r.restartDelay = r.nextRestartTime - now;
10247 repeat = true;
10248 break;
10249 }
10250 }
10251 } while (repeat);
10252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 if (!mRestartingServices.contains(r)) {
10254 mRestartingServices.add(r);
10255 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010256
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010257 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010259 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010260 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010262 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010263 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010264 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010265 r.shortName, r.restartDelay);
10266
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010267 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010268 }
10269
10270 final void performServiceRestartLocked(ServiceRecord r) {
10271 if (!mRestartingServices.contains(r)) {
10272 return;
10273 }
10274 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10275 }
10276
10277 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10278 if (r.restartDelay == 0) {
10279 return false;
10280 }
10281 r.resetRestartCounter();
10282 mRestartingServices.remove(r);
10283 mHandler.removeCallbacks(r.restarter);
10284 return true;
10285 }
10286
10287 private final boolean bringUpServiceLocked(ServiceRecord r,
10288 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010289 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010290 //r.dump(" ");
10291
Dianne Hackborn36124872009-10-08 16:22:03 -070010292 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 sendServiceArgsLocked(r, false);
10294 return true;
10295 }
10296
10297 if (!whileRestarting && r.restartDelay > 0) {
10298 // If waiting for a restart, then do nothing.
10299 return true;
10300 }
10301
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010302 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010303
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010304 // We are now bringing the service up, so no longer in the
10305 // restarting state.
10306 mRestartingServices.remove(r);
10307
Dianne Hackborne7f97212011-02-24 14:40:20 -080010308 // Service is now being launched, its package can't be stopped.
10309 try {
10310 AppGlobals.getPackageManager().setPackageStoppedState(
10311 r.packageName, false);
10312 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010313 } catch (IllegalArgumentException e) {
10314 Slog.w(TAG, "Failed trying to unstop package "
10315 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010316 }
10317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 final String appName = r.processName;
10319 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10320 if (app != null && app.thread != null) {
10321 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010322 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 realStartServiceLocked(r, app);
10324 return true;
10325 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010326 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010327 }
10328
10329 // If a dead object exception was thrown -- fall through to
10330 // restart the application.
10331 }
10332
Dianne Hackborn36124872009-10-08 16:22:03 -070010333 // Not running -- get it started, and enqueue this service record
10334 // to be executed when the app comes up.
10335 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10336 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010337 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010338 + r.appInfo.packageName + "/"
10339 + r.appInfo.uid + " for service "
10340 + r.intent.getIntent() + ": process is bad");
10341 bringDownServiceLocked(r, true);
10342 return false;
10343 }
10344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010345 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 mPendingServices.add(r);
10347 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010349 return true;
10350 }
10351
10352 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010353 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010354 //r.dump(" ");
10355
10356 // Does it still need to run?
10357 if (!force && r.startRequested) {
10358 return;
10359 }
10360 if (r.connections.size() > 0) {
10361 if (!force) {
10362 // XXX should probably keep a count of the number of auto-create
10363 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010364 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010365 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010366 ArrayList<ConnectionRecord> cr = it.next();
10367 for (int i=0; i<cr.size(); i++) {
10368 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10369 return;
10370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010371 }
10372 }
10373 }
10374
10375 // Report to all of the connections that the service is no longer
10376 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010377 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010379 ArrayList<ConnectionRecord> c = it.next();
10380 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010381 ConnectionRecord cr = c.get(i);
10382 // There is still a connection to the service that is
10383 // being brought down. Mark it as dead.
10384 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010385 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010386 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010387 } catch (Exception e) {
10388 Slog.w(TAG, "Failure disconnecting service " + r.name +
10389 " to connection " + c.get(i).conn.asBinder() +
10390 " (in " + c.get(i).binding.client.processName + ")", e);
10391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010392 }
10393 }
10394 }
10395
10396 // Tell the service that it has been unbound.
10397 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10398 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10399 while (it.hasNext()) {
10400 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010401 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010402 + ": hasBound=" + ibr.hasBound);
10403 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10404 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010405 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 updateOomAdjLocked(r.app);
10407 ibr.hasBound = false;
10408 r.app.thread.scheduleUnbindService(r,
10409 ibr.intent.getIntent());
10410 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010411 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010412 + r.shortName, e);
10413 serviceDoneExecutingLocked(r, true);
10414 }
10415 }
10416 }
10417 }
10418
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010419 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010420 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421 System.identityHashCode(r), r.shortName,
10422 (r.app != null) ? r.app.pid : -1);
10423
10424 mServices.remove(r.name);
10425 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010426 r.totalRestartCount = 0;
10427 unscheduleServiceRestartLocked(r);
10428
10429 // Also make sure it is not on the pending list.
10430 int N = mPendingServices.size();
10431 for (int i=0; i<N; i++) {
10432 if (mPendingServices.get(i) == r) {
10433 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010434 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010435 i--;
10436 N--;
10437 }
10438 }
10439
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010440 r.cancelNotification();
10441 r.isForeground = false;
10442 r.foregroundId = 0;
10443 r.foregroundNoti = null;
10444
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010445 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010446 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010447 r.pendingStarts.clear();
10448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449 if (r.app != null) {
10450 synchronized (r.stats.getBatteryStats()) {
10451 r.stats.stopLaunchedLocked();
10452 }
10453 r.app.services.remove(r);
10454 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010455 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010456 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 mStoppingServices.add(r);
10458 updateOomAdjLocked(r.app);
10459 r.app.thread.scheduleStopService(r);
10460 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010461 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010462 + r.shortName, e);
10463 serviceDoneExecutingLocked(r, true);
10464 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010465 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010466 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010467 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010468 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 }
10470 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010471 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010472 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010474
10475 if (r.bindings.size() > 0) {
10476 r.bindings.clear();
10477 }
10478
10479 if (r.restarter instanceof ServiceRestarter) {
10480 ((ServiceRestarter)r.restarter).setService(null);
10481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010482 }
10483
10484 ComponentName startServiceLocked(IApplicationThread caller,
10485 Intent service, String resolvedType,
10486 int callingPid, int callingUid) {
10487 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010488 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 + " type=" + resolvedType + " args=" + service.getExtras());
10490
10491 if (caller != null) {
10492 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10493 if (callerApp == null) {
10494 throw new SecurityException(
10495 "Unable to find app for caller " + caller
10496 + " (pid=" + Binder.getCallingPid()
10497 + ") when starting service " + service);
10498 }
10499 }
10500
10501 ServiceLookupResult res =
10502 retrieveServiceLocked(service, resolvedType,
10503 callingPid, callingUid);
10504 if (res == null) {
10505 return null;
10506 }
10507 if (res.record == null) {
10508 return new ComponentName("!", res.permission != null
10509 ? res.permission : "private to package");
10510 }
10511 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010512 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10513 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010514 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010515 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010516 }
10517 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010518 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010519 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010520 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010521 r.lastActivity = SystemClock.uptimeMillis();
10522 synchronized (r.stats.getBatteryStats()) {
10523 r.stats.startRunningLocked();
10524 }
10525 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10526 return new ComponentName("!", "Service process is bad");
10527 }
10528 return r.name;
10529 }
10530 }
10531
10532 public ComponentName startService(IApplicationThread caller, Intent service,
10533 String resolvedType) {
10534 // Refuse possible leaked file descriptors
10535 if (service != null && service.hasFileDescriptors() == true) {
10536 throw new IllegalArgumentException("File descriptors passed in Intent");
10537 }
10538
10539 synchronized(this) {
10540 final int callingPid = Binder.getCallingPid();
10541 final int callingUid = Binder.getCallingUid();
10542 final long origId = Binder.clearCallingIdentity();
10543 ComponentName res = startServiceLocked(caller, service,
10544 resolvedType, callingPid, callingUid);
10545 Binder.restoreCallingIdentity(origId);
10546 return res;
10547 }
10548 }
10549
10550 ComponentName startServiceInPackage(int uid,
10551 Intent service, String resolvedType) {
10552 synchronized(this) {
10553 final long origId = Binder.clearCallingIdentity();
10554 ComponentName res = startServiceLocked(null, service,
10555 resolvedType, -1, uid);
10556 Binder.restoreCallingIdentity(origId);
10557 return res;
10558 }
10559 }
10560
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010561 private void stopServiceLocked(ServiceRecord service) {
10562 synchronized (service.stats.getBatteryStats()) {
10563 service.stats.stopRunningLocked();
10564 }
10565 service.startRequested = false;
10566 service.callStart = false;
10567 bringDownServiceLocked(service, false);
10568 }
10569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010570 public int stopService(IApplicationThread caller, Intent service,
10571 String resolvedType) {
10572 // Refuse possible leaked file descriptors
10573 if (service != null && service.hasFileDescriptors() == true) {
10574 throw new IllegalArgumentException("File descriptors passed in Intent");
10575 }
10576
10577 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010578 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010579 + " type=" + resolvedType);
10580
10581 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10582 if (caller != null && callerApp == null) {
10583 throw new SecurityException(
10584 "Unable to find app for caller " + caller
10585 + " (pid=" + Binder.getCallingPid()
10586 + ") when stopping service " + service);
10587 }
10588
10589 // If this service is active, make sure it is stopped.
10590 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10591 if (r != null) {
10592 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010593 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010594 try {
10595 stopServiceLocked(r.record);
10596 } finally {
10597 Binder.restoreCallingIdentity(origId);
10598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010599 return 1;
10600 }
10601 return -1;
10602 }
10603 }
10604
10605 return 0;
10606 }
10607
10608 public IBinder peekService(Intent service, String resolvedType) {
10609 // Refuse possible leaked file descriptors
10610 if (service != null && service.hasFileDescriptors() == true) {
10611 throw new IllegalArgumentException("File descriptors passed in Intent");
10612 }
10613
10614 IBinder ret = null;
10615
10616 synchronized(this) {
10617 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10618
10619 if (r != null) {
10620 // r.record is null if findServiceLocked() failed the caller permission check
10621 if (r.record == null) {
10622 throw new SecurityException(
10623 "Permission Denial: Accessing service " + r.record.name
10624 + " from pid=" + Binder.getCallingPid()
10625 + ", uid=" + Binder.getCallingUid()
10626 + " requires " + r.permission);
10627 }
10628 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10629 if (ib != null) {
10630 ret = ib.binder;
10631 }
10632 }
10633 }
10634
10635 return ret;
10636 }
10637
10638 public boolean stopServiceToken(ComponentName className, IBinder token,
10639 int startId) {
10640 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010641 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010642 + " " + token + " startId=" + startId);
10643 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010644 if (r != null) {
10645 if (startId >= 0) {
10646 // Asked to only stop if done with all work. Note that
10647 // to avoid leaks, we will take this as dropping all
10648 // start items up to and including this one.
10649 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10650 if (si != null) {
10651 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010652 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10653 cur.removeUriPermissionsLocked();
10654 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010655 break;
10656 }
10657 }
10658 }
10659
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010660 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010661 return false;
10662 }
10663
10664 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010665 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010666 + " is last, but have " + r.deliveredStarts.size()
10667 + " remaining args");
10668 }
10669 }
10670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010671 synchronized (r.stats.getBatteryStats()) {
10672 r.stats.stopRunningLocked();
10673 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010674 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 }
10676 final long origId = Binder.clearCallingIdentity();
10677 bringDownServiceLocked(r, false);
10678 Binder.restoreCallingIdentity(origId);
10679 return true;
10680 }
10681 }
10682 return false;
10683 }
10684
10685 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010686 int id, Notification notification, boolean removeNotification) {
10687 final long origId = Binder.clearCallingIdentity();
10688 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 synchronized(this) {
10690 ServiceRecord r = findServiceLocked(className, token);
10691 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010692 if (id != 0) {
10693 if (notification == null) {
10694 throw new IllegalArgumentException("null notification");
10695 }
10696 if (r.foregroundId != id) {
10697 r.cancelNotification();
10698 r.foregroundId = id;
10699 }
10700 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10701 r.foregroundNoti = notification;
10702 r.isForeground = true;
10703 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010704 if (r.app != null) {
10705 updateServiceForegroundLocked(r.app, true);
10706 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010707 } else {
10708 if (r.isForeground) {
10709 r.isForeground = false;
10710 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010711 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010712 updateServiceForegroundLocked(r.app, true);
10713 }
10714 }
10715 if (removeNotification) {
10716 r.cancelNotification();
10717 r.foregroundId = 0;
10718 r.foregroundNoti = null;
10719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010720 }
10721 }
10722 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010723 } finally {
10724 Binder.restoreCallingIdentity(origId);
10725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 }
10727
10728 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10729 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010730 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010731 if (sr.isForeground) {
10732 anyForeground = true;
10733 break;
10734 }
10735 }
10736 if (anyForeground != proc.foregroundServices) {
10737 proc.foregroundServices = anyForeground;
10738 if (oomAdj) {
10739 updateOomAdjLocked();
10740 }
10741 }
10742 }
10743
10744 public int bindService(IApplicationThread caller, IBinder token,
10745 Intent service, String resolvedType,
10746 IServiceConnection connection, int flags) {
10747 // Refuse possible leaked file descriptors
10748 if (service != null && service.hasFileDescriptors() == true) {
10749 throw new IllegalArgumentException("File descriptors passed in Intent");
10750 }
10751
10752 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010753 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010754 + " type=" + resolvedType + " conn=" + connection.asBinder()
10755 + " flags=0x" + Integer.toHexString(flags));
10756 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10757 if (callerApp == null) {
10758 throw new SecurityException(
10759 "Unable to find app for caller " + caller
10760 + " (pid=" + Binder.getCallingPid()
10761 + ") when binding service " + service);
10762 }
10763
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010764 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010765 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010766 activity = mMainStack.isInStackLocked(token);
10767 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010768 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 return 0;
10770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010771 }
10772
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010773 int clientLabel = 0;
10774 PendingIntent clientIntent = null;
10775
10776 if (callerApp.info.uid == Process.SYSTEM_UID) {
10777 // Hacky kind of thing -- allow system stuff to tell us
10778 // what they are, so we can report this elsewhere for
10779 // others to know why certain services are running.
10780 try {
10781 clientIntent = (PendingIntent)service.getParcelableExtra(
10782 Intent.EXTRA_CLIENT_INTENT);
10783 } catch (RuntimeException e) {
10784 }
10785 if (clientIntent != null) {
10786 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10787 if (clientLabel != 0) {
10788 // There are no useful extras in the intent, trash them.
10789 // System code calling with this stuff just needs to know
10790 // this will happen.
10791 service = service.cloneFilter();
10792 }
10793 }
10794 }
10795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 ServiceLookupResult res =
10797 retrieveServiceLocked(service, resolvedType,
10798 Binder.getCallingPid(), Binder.getCallingUid());
10799 if (res == null) {
10800 return 0;
10801 }
10802 if (res.record == null) {
10803 return -1;
10804 }
10805 ServiceRecord s = res.record;
10806
10807 final long origId = Binder.clearCallingIdentity();
10808
10809 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010810 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010811 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010812 }
10813
10814 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10815 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010816 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817
10818 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010819 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10820 if (clist == null) {
10821 clist = new ArrayList<ConnectionRecord>();
10822 s.connections.put(binder, clist);
10823 }
10824 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010825 b.connections.add(c);
10826 if (activity != null) {
10827 if (activity.connections == null) {
10828 activity.connections = new HashSet<ConnectionRecord>();
10829 }
10830 activity.connections.add(c);
10831 }
10832 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010833 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10834 b.client.hasAboveClient = true;
10835 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010836 clist = mServiceConnections.get(binder);
10837 if (clist == null) {
10838 clist = new ArrayList<ConnectionRecord>();
10839 mServiceConnections.put(binder, clist);
10840 }
10841 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842
10843 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10844 s.lastActivity = SystemClock.uptimeMillis();
10845 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10846 return 0;
10847 }
10848 }
10849
10850 if (s.app != null) {
10851 // This could have made the service more important.
10852 updateOomAdjLocked(s.app);
10853 }
10854
Joe Onorato8a9b2202010-02-26 18:56:32 -080010855 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010856 + ": received=" + b.intent.received
10857 + " apps=" + b.intent.apps.size()
10858 + " doRebind=" + b.intent.doRebind);
10859
10860 if (s.app != null && b.intent.received) {
10861 // Service is already running, so we can immediately
10862 // publish the connection.
10863 try {
10864 c.conn.connected(s.name, b.intent.binder);
10865 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010866 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010867 + " to connection " + c.conn.asBinder()
10868 + " (in " + c.binding.client.processName + ")", e);
10869 }
10870
10871 // If this is the first app connected back to this binding,
10872 // and the service had previously asked to be told when
10873 // rebound, then do so.
10874 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10875 requestServiceBindingLocked(s, b.intent, true);
10876 }
10877 } else if (!b.intent.requested) {
10878 requestServiceBindingLocked(s, b.intent, false);
10879 }
10880
10881 Binder.restoreCallingIdentity(origId);
10882 }
10883
10884 return 1;
10885 }
10886
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010887 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010888 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010889 IBinder binder = c.conn.asBinder();
10890 AppBindRecord b = c.binding;
10891 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010892 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10893 if (clist != null) {
10894 clist.remove(c);
10895 if (clist.size() == 0) {
10896 s.connections.remove(binder);
10897 }
10898 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 b.connections.remove(c);
10900 if (c.activity != null && c.activity != skipAct) {
10901 if (c.activity.connections != null) {
10902 c.activity.connections.remove(c);
10903 }
10904 }
10905 if (b.client != skipApp) {
10906 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010907 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10908 b.client.updateHasAboveClientLocked();
10909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010911 clist = mServiceConnections.get(binder);
10912 if (clist != null) {
10913 clist.remove(c);
10914 if (clist.size() == 0) {
10915 mServiceConnections.remove(binder);
10916 }
10917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918
10919 if (b.connections.size() == 0) {
10920 b.intent.apps.remove(b.client);
10921 }
10922
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010923 if (!c.serviceDead) {
10924 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10925 + ": shouldUnbind=" + b.intent.hasBound);
10926 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10927 && b.intent.hasBound) {
10928 try {
10929 bumpServiceExecutingLocked(s, "unbind");
10930 updateOomAdjLocked(s.app);
10931 b.intent.hasBound = false;
10932 // Assume the client doesn't want to know about a rebind;
10933 // we will deal with that later if it asks for one.
10934 b.intent.doRebind = false;
10935 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10936 } catch (Exception e) {
10937 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10938 serviceDoneExecutingLocked(s, true);
10939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010940 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010941
10942 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10943 bringDownServiceLocked(s, false);
10944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010945 }
10946 }
10947
10948 public boolean unbindService(IServiceConnection connection) {
10949 synchronized (this) {
10950 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010951 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010952 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10953 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010954 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 + connection.asBinder());
10956 return false;
10957 }
10958
10959 final long origId = Binder.clearCallingIdentity();
10960
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010961 while (clist.size() > 0) {
10962 ConnectionRecord r = clist.get(0);
10963 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010965 if (r.binding.service.app != null) {
10966 // This could have made the service less important.
10967 updateOomAdjLocked(r.binding.service.app);
10968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010969 }
10970
10971 Binder.restoreCallingIdentity(origId);
10972 }
10973
10974 return true;
10975 }
10976
10977 public void publishService(IBinder token, Intent intent, IBinder service) {
10978 // Refuse possible leaked file descriptors
10979 if (intent != null && intent.hasFileDescriptors() == true) {
10980 throw new IllegalArgumentException("File descriptors passed in Intent");
10981 }
10982
10983 synchronized(this) {
10984 if (!(token instanceof ServiceRecord)) {
10985 throw new IllegalArgumentException("Invalid service token");
10986 }
10987 ServiceRecord r = (ServiceRecord)token;
10988
10989 final long origId = Binder.clearCallingIdentity();
10990
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010991 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 + " " + intent + ": " + service);
10993 if (r != null) {
10994 Intent.FilterComparison filter
10995 = new Intent.FilterComparison(intent);
10996 IntentBindRecord b = r.bindings.get(filter);
10997 if (b != null && !b.received) {
10998 b.binder = service;
10999 b.requested = true;
11000 b.received = true;
11001 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011002 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011003 = r.connections.values().iterator();
11004 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011005 ArrayList<ConnectionRecord> clist = it.next();
11006 for (int i=0; i<clist.size(); i++) {
11007 ConnectionRecord c = clist.get(i);
11008 if (!filter.equals(c.binding.intent.intent)) {
11009 if (DEBUG_SERVICE) Slog.v(
11010 TAG, "Not publishing to: " + c);
11011 if (DEBUG_SERVICE) Slog.v(
11012 TAG, "Bound intent: " + c.binding.intent.intent);
11013 if (DEBUG_SERVICE) Slog.v(
11014 TAG, "Published intent: " + intent);
11015 continue;
11016 }
11017 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11018 try {
11019 c.conn.connected(r.name, service);
11020 } catch (Exception e) {
11021 Slog.w(TAG, "Failure sending service " + r.name +
11022 " to connection " + c.conn.asBinder() +
11023 " (in " + c.binding.client.processName + ")", e);
11024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011025 }
11026 }
11027 }
11028 }
11029
11030 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11031
11032 Binder.restoreCallingIdentity(origId);
11033 }
11034 }
11035 }
11036
11037 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11038 // Refuse possible leaked file descriptors
11039 if (intent != null && intent.hasFileDescriptors() == true) {
11040 throw new IllegalArgumentException("File descriptors passed in Intent");
11041 }
11042
11043 synchronized(this) {
11044 if (!(token instanceof ServiceRecord)) {
11045 throw new IllegalArgumentException("Invalid service token");
11046 }
11047 ServiceRecord r = (ServiceRecord)token;
11048
11049 final long origId = Binder.clearCallingIdentity();
11050
11051 if (r != null) {
11052 Intent.FilterComparison filter
11053 = new Intent.FilterComparison(intent);
11054 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011055 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011056 + " at " + b + ": apps="
11057 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011058
11059 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011060 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011061 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 // Applications have already bound since the last
11063 // unbind, so just rebind right here.
11064 requestServiceBindingLocked(r, b, true);
11065 } else {
11066 // Note to tell the service the next time there is
11067 // a new client.
11068 b.doRebind = true;
11069 }
11070 }
11071
Per Edelberg78f9fff2010-08-30 20:01:35 +020011072 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011073
11074 Binder.restoreCallingIdentity(origId);
11075 }
11076 }
11077 }
11078
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011079 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 synchronized(this) {
11081 if (!(token instanceof ServiceRecord)) {
11082 throw new IllegalArgumentException("Invalid service token");
11083 }
11084 ServiceRecord r = (ServiceRecord)token;
11085 boolean inStopping = mStoppingServices.contains(token);
11086 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011087 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011088 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089 + " with incorrect token: given " + token
11090 + ", expected " + r);
11091 return;
11092 }
11093
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011094 if (type == 1) {
11095 // This is a call from a service start... take care of
11096 // book-keeping.
11097 r.callStart = true;
11098 switch (res) {
11099 case Service.START_STICKY_COMPATIBILITY:
11100 case Service.START_STICKY: {
11101 // We are done with the associated start arguments.
11102 r.findDeliveredStart(startId, true);
11103 // Don't stop if killed.
11104 r.stopIfKilled = false;
11105 break;
11106 }
11107 case Service.START_NOT_STICKY: {
11108 // We are done with the associated start arguments.
11109 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011110 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011111 // There is no more work, and this service
11112 // doesn't want to hang around if killed.
11113 r.stopIfKilled = true;
11114 }
11115 break;
11116 }
11117 case Service.START_REDELIVER_INTENT: {
11118 // We'll keep this item until they explicitly
11119 // call stop for it, but keep track of the fact
11120 // that it was delivered.
11121 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11122 if (si != null) {
11123 si.deliveryCount = 0;
11124 si.doneExecutingCount++;
11125 // Don't stop if killed.
11126 r.stopIfKilled = true;
11127 }
11128 break;
11129 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011130 case Service.START_TASK_REMOVED_COMPLETE: {
11131 // Special processing for onTaskRemoved(). Don't
11132 // impact normal onStartCommand() processing.
11133 r.findDeliveredStart(startId, true);
11134 break;
11135 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011136 default:
11137 throw new IllegalArgumentException(
11138 "Unknown service start result: " + res);
11139 }
11140 if (res == Service.START_STICKY_COMPATIBILITY) {
11141 r.callStart = false;
11142 }
11143 }
11144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 final long origId = Binder.clearCallingIdentity();
11146 serviceDoneExecutingLocked(r, inStopping);
11147 Binder.restoreCallingIdentity(origId);
11148 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011149 Slog.w(TAG, "Done executing unknown service from pid "
11150 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011151 }
11152 }
11153 }
11154
11155 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011156 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11157 + ": nesting=" + r.executeNesting
11158 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011159 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011160 r.executeNesting--;
11161 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011162 if (DEBUG_SERVICE) Slog.v(TAG,
11163 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011164 r.app.executingServices.remove(r);
11165 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011166 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11167 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11169 }
11170 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011171 if (DEBUG_SERVICE) Slog.v(TAG,
11172 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011173 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011174 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 }
11176 updateOomAdjLocked(r.app);
11177 }
11178 }
11179
11180 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011181 String anrMessage = null;
11182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011183 synchronized(this) {
11184 if (proc.executingServices.size() == 0 || proc.thread == null) {
11185 return;
11186 }
11187 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11188 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11189 ServiceRecord timeout = null;
11190 long nextTime = 0;
11191 while (it.hasNext()) {
11192 ServiceRecord sr = it.next();
11193 if (sr.executingStart < maxTime) {
11194 timeout = sr;
11195 break;
11196 }
11197 if (sr.executingStart > nextTime) {
11198 nextTime = sr.executingStart;
11199 }
11200 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011201 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011202 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011203 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011204 } else {
11205 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11206 msg.obj = proc;
11207 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11208 }
11209 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011210
11211 if (anrMessage != null) {
11212 appNotResponding(proc, null, null, anrMessage);
11213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 }
11215
11216 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011217 // BACKUP AND RESTORE
11218 // =========================================================
11219
11220 // Cause the target app to be launched if necessary and its backup agent
11221 // instantiated. The backup agent will invoke backupAgentCreated() on the
11222 // activity manager to announce its creation.
11223 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011224 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011225 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11226
11227 synchronized(this) {
11228 // !!! TODO: currently no check here that we're already bound
11229 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11230 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11231 synchronized (stats) {
11232 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11233 }
11234
Dianne Hackborne7f97212011-02-24 14:40:20 -080011235 // Backup agent is now in use, its package can't be stopped.
11236 try {
11237 AppGlobals.getPackageManager().setPackageStoppedState(
11238 app.packageName, false);
11239 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011240 } catch (IllegalArgumentException e) {
11241 Slog.w(TAG, "Failed trying to unstop package "
11242 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011243 }
11244
Christopher Tate181fafa2009-05-14 11:12:14 -070011245 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011246 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11247 ? new ComponentName(app.packageName, app.backupAgentName)
11248 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011249 // startProcessLocked() returns existing proc's record if it's already running
11250 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011251 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011252 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011253 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011254 return false;
11255 }
11256
11257 r.app = proc;
11258 mBackupTarget = r;
11259 mBackupAppName = app.packageName;
11260
Christopher Tate6fa95972009-06-05 18:43:55 -070011261 // Try not to kill the process during backup
11262 updateOomAdjLocked(proc);
11263
Christopher Tate181fafa2009-05-14 11:12:14 -070011264 // If the process is already attached, schedule the creation of the backup agent now.
11265 // If it is not yet live, this will be done when it attaches to the framework.
11266 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011267 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011268 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011269 proc.thread.scheduleCreateBackupAgent(app,
11270 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011271 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011272 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011273 }
11274 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011275 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011276 }
11277 // Invariants: at this point, the target app process exists and the application
11278 // is either already running or in the process of coming up. mBackupTarget and
11279 // mBackupAppName describe the app, so that when it binds back to the AM we
11280 // know that it's scheduled for a backup-agent operation.
11281 }
11282
11283 return true;
11284 }
11285
11286 // A backup agent has just come up
11287 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011288 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011289 + " = " + agent);
11290
11291 synchronized(this) {
11292 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011293 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011294 return;
11295 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011296 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011297
Dianne Hackborn06740692010-09-22 22:46:21 -070011298 long oldIdent = Binder.clearCallingIdentity();
11299 try {
11300 IBackupManager bm = IBackupManager.Stub.asInterface(
11301 ServiceManager.getService(Context.BACKUP_SERVICE));
11302 bm.agentConnected(agentPackageName, agent);
11303 } catch (RemoteException e) {
11304 // can't happen; the backup manager service is local
11305 } catch (Exception e) {
11306 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11307 e.printStackTrace();
11308 } finally {
11309 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011310 }
11311 }
11312
11313 // done with this agent
11314 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011315 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011316 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011317 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011318 return;
11319 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011320
11321 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011322 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011323 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011324 return;
11325 }
11326
Christopher Tate181fafa2009-05-14 11:12:14 -070011327 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011328 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011329 return;
11330 }
11331
Christopher Tate6fa95972009-06-05 18:43:55 -070011332 ProcessRecord proc = mBackupTarget.app;
11333 mBackupTarget = null;
11334 mBackupAppName = null;
11335
11336 // Not backing this app up any more; reset its OOM adjustment
11337 updateOomAdjLocked(proc);
11338
Christopher Tatec7b31e32009-06-10 15:49:30 -070011339 // If the app crashed during backup, 'thread' will be null here
11340 if (proc.thread != null) {
11341 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011342 proc.thread.scheduleDestroyBackupAgent(appInfo,
11343 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011344 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011345 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011346 e.printStackTrace();
11347 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011348 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011349 }
11350 }
11351 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352 // BROADCASTS
11353 // =========================================================
11354
Josh Bartel7f208742010-02-25 11:01:44 -060011355 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 List cur) {
11357 final ContentResolver resolver = mContext.getContentResolver();
11358 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11359 if (list == null) {
11360 return cur;
11361 }
11362 int N = list.size();
11363 for (int i=0; i<N; i++) {
11364 Intent intent = list.get(i);
11365 if (filter.match(resolver, intent, true, TAG) >= 0) {
11366 if (cur == null) {
11367 cur = new ArrayList<Intent>();
11368 }
11369 cur.add(intent);
11370 }
11371 }
11372 return cur;
11373 }
11374
11375 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011376 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011377 + mBroadcastsScheduled);
11378
11379 if (mBroadcastsScheduled) {
11380 return;
11381 }
11382 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11383 mBroadcastsScheduled = true;
11384 }
11385
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011386 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011387 IIntentReceiver receiver, IntentFilter filter, String permission) {
11388 synchronized(this) {
11389 ProcessRecord callerApp = null;
11390 if (caller != null) {
11391 callerApp = getRecordForAppLocked(caller);
11392 if (callerApp == null) {
11393 throw new SecurityException(
11394 "Unable to find app for caller " + caller
11395 + " (pid=" + Binder.getCallingPid()
11396 + ") when registering receiver " + receiver);
11397 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011398 if (callerApp.info.uid != Process.SYSTEM_UID &&
11399 !callerApp.pkgList.contains(callerPackage)) {
11400 throw new SecurityException("Given caller package " + callerPackage
11401 + " is not running in process " + callerApp);
11402 }
11403 } else {
11404 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011405 }
11406
11407 List allSticky = null;
11408
11409 // Look for any matching sticky broadcasts...
11410 Iterator actions = filter.actionsIterator();
11411 if (actions != null) {
11412 while (actions.hasNext()) {
11413 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011414 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011415 }
11416 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011417 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011418 }
11419
11420 // The first sticky in the list is returned directly back to
11421 // the client.
11422 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11423
Joe Onorato8a9b2202010-02-26 18:56:32 -080011424 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425 + ": " + sticky);
11426
11427 if (receiver == null) {
11428 return sticky;
11429 }
11430
11431 ReceiverList rl
11432 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11433 if (rl == null) {
11434 rl = new ReceiverList(this, callerApp,
11435 Binder.getCallingPid(),
11436 Binder.getCallingUid(), receiver);
11437 if (rl.app != null) {
11438 rl.app.receivers.add(rl);
11439 } else {
11440 try {
11441 receiver.asBinder().linkToDeath(rl, 0);
11442 } catch (RemoteException e) {
11443 return sticky;
11444 }
11445 rl.linkedToDeath = true;
11446 }
11447 mRegisteredReceivers.put(receiver.asBinder(), rl);
11448 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011449 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 rl.add(bf);
11451 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011452 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 }
11454 mReceiverResolver.addFilter(bf);
11455
11456 // Enqueue broadcasts for all existing stickies that match
11457 // this filter.
11458 if (allSticky != null) {
11459 ArrayList receivers = new ArrayList();
11460 receivers.add(bf);
11461
11462 int N = allSticky.size();
11463 for (int i=0; i<N; i++) {
11464 Intent intent = (Intent)allSticky.get(i);
11465 BroadcastRecord r = new BroadcastRecord(intent, null,
11466 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011467 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011468 if (mParallelBroadcasts.size() == 0) {
11469 scheduleBroadcastsLocked();
11470 }
11471 mParallelBroadcasts.add(r);
11472 }
11473 }
11474
11475 return sticky;
11476 }
11477 }
11478
11479 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011480 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011481
11482 boolean doNext = false;
11483
11484 synchronized(this) {
11485 ReceiverList rl
11486 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11487 if (rl != null) {
11488 if (rl.curBroadcast != null) {
11489 BroadcastRecord r = rl.curBroadcast;
11490 doNext = finishReceiverLocked(
11491 receiver.asBinder(), r.resultCode, r.resultData,
11492 r.resultExtras, r.resultAbort, true);
11493 }
11494
11495 if (rl.app != null) {
11496 rl.app.receivers.remove(rl);
11497 }
11498 removeReceiverLocked(rl);
11499 if (rl.linkedToDeath) {
11500 rl.linkedToDeath = false;
11501 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11502 }
11503 }
11504 }
11505
11506 if (!doNext) {
11507 return;
11508 }
11509
11510 final long origId = Binder.clearCallingIdentity();
11511 processNextBroadcast(false);
11512 trimApplications();
11513 Binder.restoreCallingIdentity(origId);
11514 }
11515
11516 void removeReceiverLocked(ReceiverList rl) {
11517 mRegisteredReceivers.remove(rl.receiver.asBinder());
11518 int N = rl.size();
11519 for (int i=0; i<N; i++) {
11520 mReceiverResolver.removeFilter(rl.get(i));
11521 }
11522 }
11523
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011524 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11525 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11526 ProcessRecord r = mLruProcesses.get(i);
11527 if (r.thread != null) {
11528 try {
11529 r.thread.dispatchPackageBroadcast(cmd, packages);
11530 } catch (RemoteException ex) {
11531 }
11532 }
11533 }
11534 }
11535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011536 private final int broadcastIntentLocked(ProcessRecord callerApp,
11537 String callerPackage, Intent intent, String resolvedType,
11538 IIntentReceiver resultTo, int resultCode, String resultData,
11539 Bundle map, String requiredPermission,
11540 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11541 intent = new Intent(intent);
11542
Dianne Hackborne7f97212011-02-24 14:40:20 -080011543 // By default broadcasts do not go to stopped apps.
11544 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11545
Joe Onorato8a9b2202010-02-26 18:56:32 -080011546 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011547 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11548 + " ordered=" + ordered);
11549 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011550 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011551 }
11552
11553 // Handle special intents: if this broadcast is from the package
11554 // manager about a package being removed, we need to remove all of
11555 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011556 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011557 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011558 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11559 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011560 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011561 || uidRemoved) {
11562 if (checkComponentPermission(
11563 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011564 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011565 == PackageManager.PERMISSION_GRANTED) {
11566 if (uidRemoved) {
11567 final Bundle intentExtras = intent.getExtras();
11568 final int uid = intentExtras != null
11569 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11570 if (uid >= 0) {
11571 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11572 synchronized (bs) {
11573 bs.removeUidStatsLocked(uid);
11574 }
11575 }
11576 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011577 // If resources are unvailble just force stop all
11578 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011579 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011580 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11581 if (list != null && (list.length > 0)) {
11582 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011583 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011584 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011585 sendPackageBroadcastLocked(
11586 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011587 }
11588 } else {
11589 Uri data = intent.getData();
11590 String ssp;
11591 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11592 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11593 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011594 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011595 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011596 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011597 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11598 new String[] {ssp});
11599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011600 }
11601 }
11602 }
11603 } else {
11604 String msg = "Permission Denial: " + intent.getAction()
11605 + " broadcast from " + callerPackage + " (pid=" + callingPid
11606 + ", uid=" + callingUid + ")"
11607 + " requires "
11608 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011609 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011610 throw new SecurityException(msg);
11611 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011612
11613 // Special case for adding a package: by default turn on compatibility
11614 // mode.
11615 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011616 Uri data = intent.getData();
11617 String ssp;
11618 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11619 mCompatModePackages.handlePackageAddedLocked(ssp,
11620 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011622 }
11623
11624 /*
11625 * If this is the time zone changed action, queue up a message that will reset the timezone
11626 * of all currently running processes. This message will get queued up before the broadcast
11627 * happens.
11628 */
11629 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11630 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11631 }
11632
Robert Greenwalt03595d02010-11-02 14:08:23 -070011633 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11634 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11635 }
11636
Robert Greenwalt434203a2010-10-11 16:00:27 -070011637 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11638 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11639 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11640 }
11641
Dianne Hackborn854060af2009-07-09 18:14:31 -070011642 /*
11643 * Prevent non-system code (defined here to be non-persistent
11644 * processes) from sending protected broadcasts.
11645 */
11646 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11647 || callingUid == Process.SHELL_UID || callingUid == 0) {
11648 // Always okay.
11649 } else if (callerApp == null || !callerApp.persistent) {
11650 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011651 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011652 intent.getAction())) {
11653 String msg = "Permission Denial: not allowed to send broadcast "
11654 + intent.getAction() + " from pid="
11655 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011656 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011657 throw new SecurityException(msg);
11658 }
11659 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011660 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011661 return BROADCAST_SUCCESS;
11662 }
11663 }
11664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011665 // Add to the sticky list if requested.
11666 if (sticky) {
11667 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11668 callingPid, callingUid)
11669 != PackageManager.PERMISSION_GRANTED) {
11670 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11671 + callingPid + ", uid=" + callingUid
11672 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011673 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 throw new SecurityException(msg);
11675 }
11676 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011677 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011678 + " and enforce permission " + requiredPermission);
11679 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11680 }
11681 if (intent.getComponent() != null) {
11682 throw new SecurityException(
11683 "Sticky broadcasts can't target a specific component");
11684 }
11685 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11686 if (list == null) {
11687 list = new ArrayList<Intent>();
11688 mStickyBroadcasts.put(intent.getAction(), list);
11689 }
11690 int N = list.size();
11691 int i;
11692 for (i=0; i<N; i++) {
11693 if (intent.filterEquals(list.get(i))) {
11694 // This sticky already exists, replace it.
11695 list.set(i, new Intent(intent));
11696 break;
11697 }
11698 }
11699 if (i >= N) {
11700 list.add(new Intent(intent));
11701 }
11702 }
11703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011704 // Figure out who all will receive this broadcast.
11705 List receivers = null;
11706 List<BroadcastFilter> registeredReceivers = null;
11707 try {
11708 if (intent.getComponent() != null) {
11709 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011710 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011711 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011712 if (ai != null) {
11713 receivers = new ArrayList();
11714 ResolveInfo ri = new ResolveInfo();
11715 ri.activityInfo = ai;
11716 receivers.add(ri);
11717 }
11718 } else {
11719 // Need to resolve the intent to interested receivers...
11720 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11721 == 0) {
11722 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011723 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011724 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011725 }
Mihai Preda074edef2009-05-18 17:13:31 +020011726 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011727 }
11728 } catch (RemoteException ex) {
11729 // pm is in same process, this will never happen.
11730 }
11731
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011732 final boolean replacePending =
11733 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11734
Joe Onorato8a9b2202010-02-26 18:56:32 -080011735 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011736 + " replacePending=" + replacePending);
11737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011738 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11739 if (!ordered && NR > 0) {
11740 // If we are not serializing this broadcast, then send the
11741 // registered receivers separately so they don't wait for the
11742 // components to be launched.
11743 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11744 callerPackage, callingPid, callingUid, requiredPermission,
11745 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011746 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011747 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011748 TAG, "Enqueueing parallel broadcast " + r
11749 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011750 boolean replaced = false;
11751 if (replacePending) {
11752 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11753 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011754 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011755 "***** DROPPING PARALLEL: " + intent);
11756 mParallelBroadcasts.set(i, r);
11757 replaced = true;
11758 break;
11759 }
11760 }
11761 }
11762 if (!replaced) {
11763 mParallelBroadcasts.add(r);
11764 scheduleBroadcastsLocked();
11765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011766 registeredReceivers = null;
11767 NR = 0;
11768 }
11769
11770 // Merge into one list.
11771 int ir = 0;
11772 if (receivers != null) {
11773 // A special case for PACKAGE_ADDED: do not allow the package
11774 // being added to see this broadcast. This prevents them from
11775 // using this as a back door to get run as soon as they are
11776 // installed. Maybe in the future we want to have a special install
11777 // broadcast or such for apps, but we'd like to deliberately make
11778 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011779 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011780 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11781 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11782 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011783 Uri data = intent.getData();
11784 if (data != null) {
11785 String pkgName = data.getSchemeSpecificPart();
11786 if (pkgName != null) {
11787 skipPackages = new String[] { pkgName };
11788 }
11789 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011790 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011791 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011792 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011793 if (skipPackages != null && (skipPackages.length > 0)) {
11794 for (String skipPackage : skipPackages) {
11795 if (skipPackage != null) {
11796 int NT = receivers.size();
11797 for (int it=0; it<NT; it++) {
11798 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11799 if (curt.activityInfo.packageName.equals(skipPackage)) {
11800 receivers.remove(it);
11801 it--;
11802 NT--;
11803 }
11804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805 }
11806 }
11807 }
11808
11809 int NT = receivers != null ? receivers.size() : 0;
11810 int it = 0;
11811 ResolveInfo curt = null;
11812 BroadcastFilter curr = null;
11813 while (it < NT && ir < NR) {
11814 if (curt == null) {
11815 curt = (ResolveInfo)receivers.get(it);
11816 }
11817 if (curr == null) {
11818 curr = registeredReceivers.get(ir);
11819 }
11820 if (curr.getPriority() >= curt.priority) {
11821 // Insert this broadcast record into the final list.
11822 receivers.add(it, curr);
11823 ir++;
11824 curr = null;
11825 it++;
11826 NT++;
11827 } else {
11828 // Skip to the next ResolveInfo in the final list.
11829 it++;
11830 curt = null;
11831 }
11832 }
11833 }
11834 while (ir < NR) {
11835 if (receivers == null) {
11836 receivers = new ArrayList();
11837 }
11838 receivers.add(registeredReceivers.get(ir));
11839 ir++;
11840 }
11841
11842 if ((receivers != null && receivers.size() > 0)
11843 || resultTo != null) {
11844 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11845 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011846 receivers, resultTo, resultCode, resultData, map, ordered,
11847 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011848 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011849 TAG, "Enqueueing ordered broadcast " + r
11850 + ": prev had " + mOrderedBroadcasts.size());
11851 if (DEBUG_BROADCAST) {
11852 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011853 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011854 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011855 boolean replaced = false;
11856 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011857 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011858 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011859 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011860 "***** DROPPING ORDERED: " + intent);
11861 mOrderedBroadcasts.set(i, r);
11862 replaced = true;
11863 break;
11864 }
11865 }
11866 }
11867 if (!replaced) {
11868 mOrderedBroadcasts.add(r);
11869 scheduleBroadcastsLocked();
11870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011871 }
11872
11873 return BROADCAST_SUCCESS;
11874 }
11875
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011876 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011877 // Refuse possible leaked file descriptors
11878 if (intent != null && intent.hasFileDescriptors() == true) {
11879 throw new IllegalArgumentException("File descriptors passed in Intent");
11880 }
11881
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011882 int flags = intent.getFlags();
11883
11884 if (!mProcessesReady) {
11885 // if the caller really truly claims to know what they're doing, go
11886 // ahead and allow the broadcast without launching any receivers
11887 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11888 intent = new Intent(intent);
11889 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11890 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11891 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11892 + " before boot completion");
11893 throw new IllegalStateException("Cannot broadcast before boot completed");
11894 }
11895 }
11896
11897 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11898 throw new IllegalArgumentException(
11899 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11900 }
11901
11902 return intent;
11903 }
11904
11905 public final int broadcastIntent(IApplicationThread caller,
11906 Intent intent, String resolvedType, IIntentReceiver resultTo,
11907 int resultCode, String resultData, Bundle map,
11908 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011909 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011910 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011912 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11913 final int callingPid = Binder.getCallingPid();
11914 final int callingUid = Binder.getCallingUid();
11915 final long origId = Binder.clearCallingIdentity();
11916 int res = broadcastIntentLocked(callerApp,
11917 callerApp != null ? callerApp.info.packageName : null,
11918 intent, resolvedType, resultTo,
11919 resultCode, resultData, map, requiredPermission, serialized,
11920 sticky, callingPid, callingUid);
11921 Binder.restoreCallingIdentity(origId);
11922 return res;
11923 }
11924 }
11925
11926 int broadcastIntentInPackage(String packageName, int uid,
11927 Intent intent, String resolvedType, IIntentReceiver resultTo,
11928 int resultCode, String resultData, Bundle map,
11929 String requiredPermission, boolean serialized, boolean sticky) {
11930 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011931 intent = verifyBroadcastLocked(intent);
11932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011933 final long origId = Binder.clearCallingIdentity();
11934 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11935 resultTo, resultCode, resultData, map, requiredPermission,
11936 serialized, sticky, -1, uid);
11937 Binder.restoreCallingIdentity(origId);
11938 return res;
11939 }
11940 }
11941
11942 public final void unbroadcastIntent(IApplicationThread caller,
11943 Intent intent) {
11944 // Refuse possible leaked file descriptors
11945 if (intent != null && intent.hasFileDescriptors() == true) {
11946 throw new IllegalArgumentException("File descriptors passed in Intent");
11947 }
11948
11949 synchronized(this) {
11950 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11951 != PackageManager.PERMISSION_GRANTED) {
11952 String msg = "Permission Denial: unbroadcastIntent() from pid="
11953 + Binder.getCallingPid()
11954 + ", uid=" + Binder.getCallingUid()
11955 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011956 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011957 throw new SecurityException(msg);
11958 }
11959 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11960 if (list != null) {
11961 int N = list.size();
11962 int i;
11963 for (i=0; i<N; i++) {
11964 if (intent.filterEquals(list.get(i))) {
11965 list.remove(i);
11966 break;
11967 }
11968 }
11969 }
11970 }
11971 }
11972
11973 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11974 String resultData, Bundle resultExtras, boolean resultAbort,
11975 boolean explicit) {
11976 if (mOrderedBroadcasts.size() == 0) {
11977 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011978 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011979 }
11980 return false;
11981 }
11982 BroadcastRecord r = mOrderedBroadcasts.get(0);
11983 if (r.receiver == null) {
11984 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011985 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986 }
11987 return false;
11988 }
11989 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011990 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011991 return false;
11992 }
11993 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011994 r.state = BroadcastRecord.IDLE;
11995 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011996 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011997 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011998 }
11999 }
12000 r.receiver = null;
12001 r.intent.setComponent(null);
12002 if (r.curApp != null) {
12003 r.curApp.curReceiver = null;
12004 }
12005 if (r.curFilter != null) {
12006 r.curFilter.receiverList.curBroadcast = null;
12007 }
12008 r.curFilter = null;
12009 r.curApp = null;
12010 r.curComponent = null;
12011 r.curReceiver = null;
12012 mPendingBroadcast = null;
12013
12014 r.resultCode = resultCode;
12015 r.resultData = resultData;
12016 r.resultExtras = resultExtras;
12017 r.resultAbort = resultAbort;
12018
12019 // We will process the next receiver right now if this is finishing
12020 // an app receiver (which is always asynchronous) or after we have
12021 // come back from calling a receiver.
12022 return state == BroadcastRecord.APP_RECEIVE
12023 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12024 }
12025
12026 public void finishReceiver(IBinder who, int resultCode, String resultData,
12027 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012028 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012029
12030 // Refuse possible leaked file descriptors
12031 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12032 throw new IllegalArgumentException("File descriptors passed in Bundle");
12033 }
12034
12035 boolean doNext;
12036
12037 final long origId = Binder.clearCallingIdentity();
12038
12039 synchronized(this) {
12040 doNext = finishReceiverLocked(
12041 who, resultCode, resultData, resultExtras, resultAbort, true);
12042 }
12043
12044 if (doNext) {
12045 processNextBroadcast(false);
12046 }
12047 trimApplications();
12048
12049 Binder.restoreCallingIdentity(origId);
12050 }
12051
Jeff Brown4d94a762010-09-23 11:33:28 -070012052 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012053 if (r.nextReceiver > 0) {
12054 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12055 if (curReceiver instanceof BroadcastFilter) {
12056 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012057 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 System.identityHashCode(r),
12059 r.intent.getAction(),
12060 r.nextReceiver - 1,
12061 System.identityHashCode(bf));
12062 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012063 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012064 System.identityHashCode(r),
12065 r.intent.getAction(),
12066 r.nextReceiver - 1,
12067 ((ResolveInfo)curReceiver).toString());
12068 }
12069 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012070 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012072 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012073 System.identityHashCode(r),
12074 r.intent.getAction(),
12075 r.nextReceiver,
12076 "NONE");
12077 }
12078 }
12079
Jeff Brown4d94a762010-09-23 11:33:28 -070012080 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12081 if (! mPendingBroadcastTimeoutMessage) {
12082 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12083 mHandler.sendMessageAtTime(msg, timeoutTime);
12084 mPendingBroadcastTimeoutMessage = true;
12085 }
12086 }
12087
12088 private final void cancelBroadcastTimeoutLocked() {
12089 if (mPendingBroadcastTimeoutMessage) {
12090 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12091 mPendingBroadcastTimeoutMessage = false;
12092 }
12093 }
12094
12095 private final void broadcastTimeoutLocked(boolean fromMsg) {
12096 if (fromMsg) {
12097 mPendingBroadcastTimeoutMessage = false;
12098 }
12099
12100 if (mOrderedBroadcasts.size() == 0) {
12101 return;
12102 }
12103
12104 long now = SystemClock.uptimeMillis();
12105 BroadcastRecord r = mOrderedBroadcasts.get(0);
12106 if (fromMsg) {
12107 if (mDidDexOpt) {
12108 // Delay timeouts until dexopt finishes.
12109 mDidDexOpt = false;
12110 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12111 setBroadcastTimeoutLocked(timeoutTime);
12112 return;
12113 }
12114 if (! mProcessesReady) {
12115 // Only process broadcast timeouts if the system is ready. That way
12116 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12117 // to do heavy lifting for system up.
12118 return;
12119 }
12120
12121 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12122 if (timeoutTime > now) {
12123 // We can observe premature timeouts because we do not cancel and reset the
12124 // broadcast timeout message after each receiver finishes. Instead, we set up
12125 // an initial timeout then kick it down the road a little further as needed
12126 // when it expires.
12127 if (DEBUG_BROADCAST) Slog.v(TAG,
12128 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12129 + timeoutTime);
12130 setBroadcastTimeoutLocked(timeoutTime);
12131 return;
12132 }
12133 }
12134
12135 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12136 + ", started " + (now - r.receiverTime) + "ms ago");
12137 r.receiverTime = now;
12138 r.anrCount++;
12139
12140 // Current receiver has passed its expiration date.
12141 if (r.nextReceiver <= 0) {
12142 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12143 return;
12144 }
12145
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012146 ProcessRecord app = null;
12147 String anrMessage = null;
12148
Jeff Brown4d94a762010-09-23 11:33:28 -070012149 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12150 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12151 logBroadcastReceiverDiscardLocked(r);
12152 if (curReceiver instanceof BroadcastFilter) {
12153 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12154 if (bf.receiverList.pid != 0
12155 && bf.receiverList.pid != MY_PID) {
12156 synchronized (this.mPidsSelfLocked) {
12157 app = this.mPidsSelfLocked.get(
12158 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012160 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012161 } else {
12162 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012163 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012164
Jeff Brown4d94a762010-09-23 11:33:28 -070012165 if (app != null) {
12166 anrMessage = "Broadcast of " + r.intent.toString();
12167 }
12168
12169 if (mPendingBroadcast == r) {
12170 mPendingBroadcast = null;
12171 }
12172
12173 // Move on to the next receiver.
12174 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12175 r.resultExtras, r.resultAbort, true);
12176 scheduleBroadcastsLocked();
12177
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012178 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012179 // Post the ANR to the handler since we do not want to process ANRs while
12180 // potentially holding our lock.
12181 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012183 }
12184
12185 private final void processCurBroadcastLocked(BroadcastRecord r,
12186 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012187 if (DEBUG_BROADCAST) Slog.v(TAG,
12188 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012189 if (app.thread == null) {
12190 throw new RemoteException();
12191 }
12192 r.receiver = app.thread.asBinder();
12193 r.curApp = app;
12194 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012195 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196
12197 // Tell the application to launch this receiver.
12198 r.intent.setComponent(r.curComponent);
12199
12200 boolean started = false;
12201 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012202 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012203 "Delivering to component " + r.curComponent
12204 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012205 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012206 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012207 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012208 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012209 if (DEBUG_BROADCAST) Slog.v(TAG,
12210 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012211 started = true;
12212 } finally {
12213 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012214 if (DEBUG_BROADCAST) Slog.v(TAG,
12215 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012216 r.receiver = null;
12217 r.curApp = null;
12218 app.curReceiver = null;
12219 }
12220 }
12221
12222 }
12223
Jeff Brown4d94a762010-09-23 11:33:28 -070012224 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012225 Intent intent, int resultCode, String data, Bundle extras,
12226 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012227 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012228 if (app != null && app.thread != null) {
12229 // If we have an app thread, do the call through that so it is
12230 // correctly ordered with other one-way calls.
12231 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012232 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012233 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012234 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012235 }
12236 }
12237
Jeff Brown4d94a762010-09-23 11:33:28 -070012238 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012239 BroadcastFilter filter, boolean ordered) {
12240 boolean skip = false;
12241 if (filter.requiredPermission != null) {
12242 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012243 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012244 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012245 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 + r.intent.toString()
12247 + " from " + r.callerPackage + " (pid="
12248 + r.callingPid + ", uid=" + r.callingUid + ")"
12249 + " requires " + filter.requiredPermission
12250 + " due to registered receiver " + filter);
12251 skip = true;
12252 }
12253 }
12254 if (r.requiredPermission != null) {
12255 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012256 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012257 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012258 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012259 + r.intent.toString()
12260 + " to " + filter.receiverList.app
12261 + " (pid=" + filter.receiverList.pid
12262 + ", uid=" + filter.receiverList.uid + ")"
12263 + " requires " + r.requiredPermission
12264 + " due to sender " + r.callerPackage
12265 + " (uid " + r.callingUid + ")");
12266 skip = true;
12267 }
12268 }
12269
12270 if (!skip) {
12271 // If this is not being sent as an ordered broadcast, then we
12272 // don't want to touch the fields that keep track of the current
12273 // state of ordered broadcasts.
12274 if (ordered) {
12275 r.receiver = filter.receiverList.receiver.asBinder();
12276 r.curFilter = filter;
12277 filter.receiverList.curBroadcast = r;
12278 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012279 if (filter.receiverList.app != null) {
12280 // Bump hosting application to no longer be in background
12281 // scheduling class. Note that we can't do that if there
12282 // isn't an app... but we can only be in that case for
12283 // things that directly call the IActivityManager API, which
12284 // are already core system stuff so don't matter for this.
12285 r.curApp = filter.receiverList.app;
12286 filter.receiverList.app.curReceiver = r;
12287 updateOomAdjLocked();
12288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289 }
12290 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012291 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012292 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012293 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012294 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012295 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012296 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012297 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012298 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012299 if (ordered) {
12300 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12301 }
12302 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012303 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012304 if (ordered) {
12305 r.receiver = null;
12306 r.curFilter = null;
12307 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012308 if (filter.receiverList.app != null) {
12309 filter.receiverList.app.curReceiver = null;
12310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012311 }
12312 }
12313 }
12314 }
12315
Dianne Hackborn12527f92009-11-11 17:39:50 -080012316 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12317 if (r.callingUid < 0) {
12318 // This was from a registerReceiver() call; ignore it.
12319 return;
12320 }
12321 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12322 MAX_BROADCAST_HISTORY-1);
12323 r.finishTime = SystemClock.uptimeMillis();
12324 mBroadcastHistory[0] = r;
12325 }
12326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012327 private final void processNextBroadcast(boolean fromMsg) {
12328 synchronized(this) {
12329 BroadcastRecord r;
12330
Joe Onorato8a9b2202010-02-26 18:56:32 -080012331 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012333 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012334
12335 updateCpuStats();
12336
12337 if (fromMsg) {
12338 mBroadcastsScheduled = false;
12339 }
12340
12341 // First, deliver any non-serialized broadcasts right away.
12342 while (mParallelBroadcasts.size() > 0) {
12343 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012344 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012345 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012346 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012347 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012348 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 for (int i=0; i<N; i++) {
12350 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012351 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012352 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012353 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012354 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012356 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012357 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012358 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 }
12360
12361 // Now take care of the next serialized one...
12362
12363 // If we are waiting for a process to come up to handle the next
12364 // broadcast, then do nothing at this point. Just in case, we
12365 // check that the process we're waiting for still exists.
12366 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012367 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012368 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012369 + mPendingBroadcast.curApp);
12370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371
12372 boolean isDead;
12373 synchronized (mPidsSelfLocked) {
12374 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12375 }
12376 if (!isDead) {
12377 // It's still alive, so keep waiting
12378 return;
12379 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012380 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012381 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012382 mPendingBroadcast.state = BroadcastRecord.IDLE;
12383 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012384 mPendingBroadcast = null;
12385 }
12386 }
12387
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012388 boolean looped = false;
12389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012390 do {
12391 if (mOrderedBroadcasts.size() == 0) {
12392 // No more broadcasts pending, so all done!
12393 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012394 if (looped) {
12395 // If we had finished the last ordered broadcast, then
12396 // make sure all processes have correct oom and sched
12397 // adjustments.
12398 updateOomAdjLocked();
12399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012400 return;
12401 }
12402 r = mOrderedBroadcasts.get(0);
12403 boolean forceReceive = false;
12404
12405 // Ensure that even if something goes awry with the timeout
12406 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012407 // and continue to make progress.
12408 //
12409 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012410 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012411 // one time heavy lifting after system upgrades and can take
12412 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012414 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012415 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012416 if ((numReceivers > 0) &&
12417 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012418 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012419 + " now=" + now
12420 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012421 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012422 + " intent=" + r.intent
12423 + " numReceivers=" + numReceivers
12424 + " nextReceiver=" + r.nextReceiver
12425 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012426 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012427 forceReceive = true;
12428 r.state = BroadcastRecord.IDLE;
12429 }
12430 }
12431
12432 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012433 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012434 "processNextBroadcast() called when not idle (state="
12435 + r.state + ")");
12436 return;
12437 }
12438
12439 if (r.receivers == null || r.nextReceiver >= numReceivers
12440 || r.resultAbort || forceReceive) {
12441 // No more receivers for this broadcast! Send the final
12442 // result if requested...
12443 if (r.resultTo != null) {
12444 try {
12445 if (DEBUG_BROADCAST) {
12446 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012447 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012448 + " seq=" + seq + " app=" + r.callerApp);
12449 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012450 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012452 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012453 // Set this to null so that the reference
12454 // (local and remote) isnt kept in the mBroadcastHistory.
12455 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012456 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012457 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012458 }
12459 }
12460
Joe Onorato8a9b2202010-02-26 18:56:32 -080012461 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012462 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012463
Joe Onorato8a9b2202010-02-26 18:56:32 -080012464 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012465 + r);
12466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012467 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012468 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012469 mOrderedBroadcasts.remove(0);
12470 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012471 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012472 continue;
12473 }
12474 } while (r == null);
12475
12476 // Get the next receiver...
12477 int recIdx = r.nextReceiver++;
12478
12479 // Keep track of when this receiver started, and make sure there
12480 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012481 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012482 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012483 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012484 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012485 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012486 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012487 }
12488 if (! mPendingBroadcastTimeoutMessage) {
12489 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012490 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012491 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12492 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012493 }
12494
12495 Object nextReceiver = r.receivers.get(recIdx);
12496 if (nextReceiver instanceof BroadcastFilter) {
12497 // Simple case: this is a registered receiver who gets
12498 // a direct call.
12499 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012500 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012501 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012502 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012503 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 if (r.receiver == null || !r.ordered) {
12505 // The receiver has already finished, so schedule to
12506 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012507 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12508 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 r.state = BroadcastRecord.IDLE;
12510 scheduleBroadcastsLocked();
12511 }
12512 return;
12513 }
12514
12515 // Hard case: need to instantiate the receiver, possibly
12516 // starting its application process to host it.
12517
12518 ResolveInfo info =
12519 (ResolveInfo)nextReceiver;
12520
12521 boolean skip = false;
12522 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012523 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12524 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012525 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012526 if (!info.activityInfo.exported) {
12527 Slog.w(TAG, "Permission Denial: broadcasting "
12528 + r.intent.toString()
12529 + " from " + r.callerPackage + " (pid=" + r.callingPid
12530 + ", uid=" + r.callingUid + ")"
12531 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12532 + " due to receiver " + info.activityInfo.packageName
12533 + "/" + info.activityInfo.name);
12534 } else {
12535 Slog.w(TAG, "Permission Denial: broadcasting "
12536 + r.intent.toString()
12537 + " from " + r.callerPackage + " (pid=" + r.callingPid
12538 + ", uid=" + r.callingUid + ")"
12539 + " requires " + info.activityInfo.permission
12540 + " due to receiver " + info.activityInfo.packageName
12541 + "/" + info.activityInfo.name);
12542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012543 skip = true;
12544 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012545 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012546 r.requiredPermission != null) {
12547 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012548 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012549 checkPermission(r.requiredPermission,
12550 info.activityInfo.applicationInfo.packageName);
12551 } catch (RemoteException e) {
12552 perm = PackageManager.PERMISSION_DENIED;
12553 }
12554 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012555 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012556 + r.intent + " to "
12557 + info.activityInfo.applicationInfo.packageName
12558 + " requires " + r.requiredPermission
12559 + " due to sender " + r.callerPackage
12560 + " (uid " + r.callingUid + ")");
12561 skip = true;
12562 }
12563 }
12564 if (r.curApp != null && r.curApp.crashing) {
12565 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012566 if (DEBUG_BROADCAST) Slog.v(TAG,
12567 "Skipping deliver ordered " + r + " to " + r.curApp
12568 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012569 skip = true;
12570 }
12571
12572 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012573 if (DEBUG_BROADCAST) Slog.v(TAG,
12574 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012575 r.receiver = null;
12576 r.curFilter = null;
12577 r.state = BroadcastRecord.IDLE;
12578 scheduleBroadcastsLocked();
12579 return;
12580 }
12581
12582 r.state = BroadcastRecord.APP_RECEIVE;
12583 String targetProcess = info.activityInfo.processName;
12584 r.curComponent = new ComponentName(
12585 info.activityInfo.applicationInfo.packageName,
12586 info.activityInfo.name);
12587 r.curReceiver = info.activityInfo;
12588
Dianne Hackborne7f97212011-02-24 14:40:20 -080012589 // Broadcast is being executed, its package can't be stopped.
12590 try {
12591 AppGlobals.getPackageManager().setPackageStoppedState(
12592 r.curComponent.getPackageName(), false);
12593 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012594 } catch (IllegalArgumentException e) {
12595 Slog.w(TAG, "Failed trying to unstop package "
12596 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012597 }
12598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012599 // Is this receiver's application already running?
12600 ProcessRecord app = getProcessRecordLocked(targetProcess,
12601 info.activityInfo.applicationInfo.uid);
12602 if (app != null && app.thread != null) {
12603 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012604 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012605 processCurBroadcastLocked(r, app);
12606 return;
12607 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012608 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012609 + r.curComponent, e);
12610 }
12611
12612 // If a dead object exception was thrown -- fall through to
12613 // restart the application.
12614 }
12615
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012616 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012617 if (DEBUG_BROADCAST) Slog.v(TAG,
12618 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012619 if ((r.curApp=startProcessLocked(targetProcess,
12620 info.activityInfo.applicationInfo, true,
12621 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012622 "broadcast", r.curComponent,
12623 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12624 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625 // Ah, this recipient is unavailable. Finish it if necessary,
12626 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012627 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012628 + info.activityInfo.applicationInfo.packageName + "/"
12629 + info.activityInfo.applicationInfo.uid + " for broadcast "
12630 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012631 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012632 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12633 r.resultExtras, r.resultAbort, true);
12634 scheduleBroadcastsLocked();
12635 r.state = BroadcastRecord.IDLE;
12636 return;
12637 }
12638
12639 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012640 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012641 }
12642 }
12643
12644 // =========================================================
12645 // INSTRUMENTATION
12646 // =========================================================
12647
12648 public boolean startInstrumentation(ComponentName className,
12649 String profileFile, int flags, Bundle arguments,
12650 IInstrumentationWatcher watcher) {
12651 // Refuse possible leaked file descriptors
12652 if (arguments != null && arguments.hasFileDescriptors()) {
12653 throw new IllegalArgumentException("File descriptors passed in Bundle");
12654 }
12655
12656 synchronized(this) {
12657 InstrumentationInfo ii = null;
12658 ApplicationInfo ai = null;
12659 try {
12660 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012661 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012662 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012663 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012664 } catch (PackageManager.NameNotFoundException e) {
12665 }
12666 if (ii == null) {
12667 reportStartInstrumentationFailure(watcher, className,
12668 "Unable to find instrumentation info for: " + className);
12669 return false;
12670 }
12671 if (ai == null) {
12672 reportStartInstrumentationFailure(watcher, className,
12673 "Unable to find instrumentation target package: " + ii.targetPackage);
12674 return false;
12675 }
12676
12677 int match = mContext.getPackageManager().checkSignatures(
12678 ii.targetPackage, ii.packageName);
12679 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12680 String msg = "Permission Denial: starting instrumentation "
12681 + className + " from pid="
12682 + Binder.getCallingPid()
12683 + ", uid=" + Binder.getCallingPid()
12684 + " not allowed because package " + ii.packageName
12685 + " does not have a signature matching the target "
12686 + ii.targetPackage;
12687 reportStartInstrumentationFailure(watcher, className, msg);
12688 throw new SecurityException(msg);
12689 }
12690
12691 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012692 // Instrumentation can kill and relaunch even persistent processes
12693 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 ProcessRecord app = addAppLocked(ai);
12695 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012696 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 app.instrumentationProfileFile = profileFile;
12698 app.instrumentationArguments = arguments;
12699 app.instrumentationWatcher = watcher;
12700 app.instrumentationResultClass = className;
12701 Binder.restoreCallingIdentity(origId);
12702 }
12703
12704 return true;
12705 }
12706
12707 /**
12708 * Report errors that occur while attempting to start Instrumentation. Always writes the
12709 * error to the logs, but if somebody is watching, send the report there too. This enables
12710 * the "am" command to report errors with more information.
12711 *
12712 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12713 * @param cn The component name of the instrumentation.
12714 * @param report The error report.
12715 */
12716 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12717 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012718 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012719 try {
12720 if (watcher != null) {
12721 Bundle results = new Bundle();
12722 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12723 results.putString("Error", report);
12724 watcher.instrumentationStatus(cn, -1, results);
12725 }
12726 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012727 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012728 }
12729 }
12730
12731 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12732 if (app.instrumentationWatcher != null) {
12733 try {
12734 // NOTE: IInstrumentationWatcher *must* be oneway here
12735 app.instrumentationWatcher.instrumentationFinished(
12736 app.instrumentationClass,
12737 resultCode,
12738 results);
12739 } catch (RemoteException e) {
12740 }
12741 }
12742 app.instrumentationWatcher = null;
12743 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012744 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012745 app.instrumentationProfileFile = null;
12746 app.instrumentationArguments = null;
12747
Christopher Tate3dacd842011-08-19 14:56:15 -070012748 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012749 }
12750
12751 public void finishInstrumentation(IApplicationThread target,
12752 int resultCode, Bundle results) {
12753 // Refuse possible leaked file descriptors
12754 if (results != null && results.hasFileDescriptors()) {
12755 throw new IllegalArgumentException("File descriptors passed in Intent");
12756 }
12757
12758 synchronized(this) {
12759 ProcessRecord app = getRecordForAppLocked(target);
12760 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012761 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 return;
12763 }
12764 final long origId = Binder.clearCallingIdentity();
12765 finishInstrumentationLocked(app, resultCode, results);
12766 Binder.restoreCallingIdentity(origId);
12767 }
12768 }
12769
12770 // =========================================================
12771 // CONFIGURATION
12772 // =========================================================
12773
12774 public ConfigurationInfo getDeviceConfigurationInfo() {
12775 ConfigurationInfo config = new ConfigurationInfo();
12776 synchronized (this) {
12777 config.reqTouchScreen = mConfiguration.touchscreen;
12778 config.reqKeyboardType = mConfiguration.keyboard;
12779 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012780 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12781 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012782 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12783 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012784 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12785 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012786 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12787 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012788 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012789 }
12790 return config;
12791 }
12792
12793 public Configuration getConfiguration() {
12794 Configuration ci;
12795 synchronized(this) {
12796 ci = new Configuration(mConfiguration);
12797 }
12798 return ci;
12799 }
12800
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012801 public void updatePersistentConfiguration(Configuration values) {
12802 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12803 "updateConfiguration()");
12804 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12805 "updateConfiguration()");
12806 if (values == null) {
12807 throw new NullPointerException("Configuration must not be null");
12808 }
12809
12810 synchronized(this) {
12811 final long origId = Binder.clearCallingIdentity();
12812 updateConfigurationLocked(values, null, true);
12813 Binder.restoreCallingIdentity(origId);
12814 }
12815 }
12816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012817 public void updateConfiguration(Configuration values) {
12818 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12819 "updateConfiguration()");
12820
12821 synchronized(this) {
12822 if (values == null && mWindowManager != null) {
12823 // sentinel: fetch the current configuration from the window manager
12824 values = mWindowManager.computeNewConfiguration();
12825 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012826
12827 if (mWindowManager != null) {
12828 mProcessList.applyDisplaySize(mWindowManager);
12829 }
12830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012831 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012832 if (values != null) {
12833 Settings.System.clearConfiguration(values);
12834 }
12835 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012836 Binder.restoreCallingIdentity(origId);
12837 }
12838 }
12839
12840 /**
12841 * Do either or both things: (1) change the current configuration, and (2)
12842 * make sure the given activity is running with the (now) current
12843 * configuration. Returns true if the activity has been left running, or
12844 * false if <var>starting</var> is being destroyed to match the new
12845 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012846 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012847 */
12848 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012849 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012850 int changes = 0;
12851
12852 boolean kept = true;
12853
12854 if (values != null) {
12855 Configuration newConfig = new Configuration(mConfiguration);
12856 changes = newConfig.updateFrom(values);
12857 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012858 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012859 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012860 }
12861
Doug Zongker2bec3d42009-12-04 12:52:44 -080012862 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012863
12864 if (values.locale != null) {
12865 saveLocaleLocked(values.locale,
12866 !values.locale.equals(mConfiguration.locale),
12867 values.userSetLocale);
12868 }
12869
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012870 mConfigurationSeq++;
12871 if (mConfigurationSeq <= 0) {
12872 mConfigurationSeq = 1;
12873 }
12874 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012875 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012876 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012877
12878 AttributeCache ac = AttributeCache.instance();
12879 if (ac != null) {
12880 ac.updateConfiguration(mConfiguration);
12881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012882
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012883 // Make sure all resources in our process are updated
12884 // right now, so that anyone who is going to retrieve
12885 // resource values after we return will be sure to get
12886 // the new ones. This is especially important during
12887 // boot, where the first config change needs to guarantee
12888 // all resources have that config before following boot
12889 // code is executed.
12890 mSystemThread.applyConfigurationToResources(newConfig);
12891
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012892 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012893 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12894 msg.obj = new Configuration(mConfiguration);
12895 mHandler.sendMessage(msg);
12896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012897
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012898 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12899 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900 try {
12901 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012902 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012903 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012904 app.thread.scheduleConfigurationChanged(mConfiguration);
12905 }
12906 } catch (Exception e) {
12907 }
12908 }
12909 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012910 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12911 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012912 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12913 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012914 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12915 broadcastIntentLocked(null, null,
12916 new Intent(Intent.ACTION_LOCALE_CHANGED),
12917 null, null, 0, null, null,
12918 null, false, false, MY_PID, Process.SYSTEM_UID);
12919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012920 }
12921 }
12922
12923 if (changes != 0 && starting == null) {
12924 // If the configuration changed, and the caller is not already
12925 // in the process of starting an activity, then find the top
12926 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012927 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012928 }
12929
12930 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012931 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012932 // And we need to make sure at this point that all other activities
12933 // are made visible with the correct configuration.
12934 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012935 }
12936
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012937 if (values != null && mWindowManager != null) {
12938 mWindowManager.setNewConfiguration(mConfiguration);
12939 }
12940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 return kept;
12942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943
12944 /**
12945 * Save the locale. You must be inside a synchronized (this) block.
12946 */
12947 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12948 if(isDiff) {
12949 SystemProperties.set("user.language", l.getLanguage());
12950 SystemProperties.set("user.region", l.getCountry());
12951 }
12952
12953 if(isPersist) {
12954 SystemProperties.set("persist.sys.language", l.getLanguage());
12955 SystemProperties.set("persist.sys.country", l.getCountry());
12956 SystemProperties.set("persist.sys.localevar", l.getVariant());
12957 }
12958 }
12959
12960 // =========================================================
12961 // LIFETIME MANAGEMENT
12962 // =========================================================
12963
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012964 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012965 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012967 // This adjustment has already been computed. If we are calling
12968 // from the top, we may have already computed our adjustment with
12969 // an earlier hidden adjustment that isn't really for us... if
12970 // so, use the new hidden adjustment.
12971 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012972 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012973 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012974 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012975 }
12976
12977 if (app.thread == null) {
12978 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012979 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012980 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012981 }
12982
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012983 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12984 app.adjSource = null;
12985 app.adjTarget = null;
12986 app.empty = false;
12987 app.hidden = false;
12988
12989 final int activitiesSize = app.activities.size();
12990
Dianne Hackborn7d608422011-08-07 16:24:18 -070012991 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012992 // The max adjustment doesn't allow this app to be anything
12993 // below foreground, so it is not worth doing work for it.
12994 app.adjType = "fixed";
12995 app.adjSeq = mAdjSeq;
12996 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012997 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012998 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012999 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013000 // System process can do UI, and when they do we want to have
13001 // them trim their memory after the user leaves the UI. To
13002 // facilitate this, here we need to determine whether or not it
13003 // is currently showing UI.
13004 app.systemNoUi = true;
13005 if (app == TOP_APP) {
13006 app.systemNoUi = false;
13007 } else if (activitiesSize > 0) {
13008 for (int j = 0; j < activitiesSize; j++) {
13009 final ActivityRecord r = app.activities.get(j);
13010 if (r.visible) {
13011 app.systemNoUi = false;
13012 break;
13013 }
13014 }
13015 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013016 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013017 }
13018
13019 final boolean hadForegroundActivities = app.foregroundActivities;
13020
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013021 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013022 app.keeping = false;
13023 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013024
The Android Open Source Project4df24232009-03-05 14:34:35 -080013025 // Determine the importance of the process, starting with most
13026 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013027 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013028 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013029 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013030 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013031 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013032 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013033 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013034 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013035 } else if (app.instrumentationClass != null) {
13036 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013037 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013038 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013039 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013040 } else if (app.curReceiver != null ||
13041 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13042 // An app that is currently receiving a broadcast also
13043 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013044 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013045 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013046 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013047 } else if (app.executingServices.size() > 0) {
13048 // An app that is currently executing a service callback also
13049 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013050 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013051 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013052 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013053 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013054 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013055 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013056 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013057 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013058 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013059 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013060 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013061 // A very not-needed process. If this is lower in the lru list,
13062 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013063 adj = hiddenAdj;
13064 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013065 app.hidden = true;
13066 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013067 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013068 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013069
13070 // Examine all activities if not already foreground.
13071 if (!app.foregroundActivities && activitiesSize > 0) {
13072 for (int j = 0; j < activitiesSize; j++) {
13073 final ActivityRecord r = app.activities.get(j);
13074 if (r.visible) {
13075 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013076 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13077 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013078 app.adjType = "visible";
13079 }
13080 schedGroup = Process.THREAD_GROUP_DEFAULT;
13081 app.hidden = false;
13082 app.foregroundActivities = true;
13083 break;
13084 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13085 || r.state == ActivityState.STOPPING) {
13086 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013087 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13088 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013089 app.adjType = "stopping";
13090 }
13091 app.foregroundActivities = true;
13092 }
13093 }
13094 }
13095
Dianne Hackborn7d608422011-08-07 16:24:18 -070013096 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013097 if (app.foregroundServices) {
13098 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013099 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013100 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013101 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013102 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013103 } else if (app.forcingToForeground != null) {
13104 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013105 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013106 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013107 app.adjType = "force-foreground";
13108 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013109 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013110 }
13111 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013112
Dianne Hackborn7d608422011-08-07 16:24:18 -070013113 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013114 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013115 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013116 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013117 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013118 app.adjType = "heavy";
13119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013120
Dianne Hackborn7d608422011-08-07 16:24:18 -070013121 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013122 // This process is hosting what we currently consider to be the
13123 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013124 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013125 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013126 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013127 app.adjType = "home";
13128 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013129
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013130 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13131 && app.activities.size() > 0) {
13132 // This was the previous process that showed UI to the user.
13133 // We want to try to keep it around more aggressively, to give
13134 // a good experience around switching between two apps.
13135 adj = ProcessList.PREVIOUS_APP_ADJ;
13136 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13137 app.hidden = false;
13138 app.adjType = "previous";
13139 }
13140
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013141 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13142 + " reason=" + app.adjType);
13143
The Android Open Source Project4df24232009-03-05 14:34:35 -080013144 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 // there are applications dependent on our services or providers, but
13146 // this gives us a baseline and makes sure we don't get into an
13147 // infinite recursion.
13148 app.adjSeq = mAdjSeq;
13149 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013150
Christopher Tate6fa95972009-06-05 18:43:55 -070013151 if (mBackupTarget != null && app == mBackupTarget.app) {
13152 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013153 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013154 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013155 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013156 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013157 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013158 }
13159 }
13160
Dianne Hackborn7d608422011-08-07 16:24:18 -070013161 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013162 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013163 final long now = SystemClock.uptimeMillis();
13164 // This process is more important if the top activity is
13165 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013166 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013167 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013168 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013169 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013170 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013171 // If this process has shown some UI, let it immediately
13172 // go to the LRU list because it may be pretty heavy with
13173 // UI stuff. We'll tag it with a label just to help
13174 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013175 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013176 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013177 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013178 } else {
13179 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13180 // This service has seen some activity within
13181 // recent memory, so we will keep its process ahead
13182 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013183 if (adj > ProcessList.SERVICE_ADJ) {
13184 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013185 app.adjType = "started-services";
13186 app.hidden = false;
13187 }
13188 }
13189 // If we have let the service slide into the background
13190 // state, still have some text describing what it is doing
13191 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013192 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013193 app.adjType = "started-bg-services";
13194 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013195 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013196 // Don't kill this process because it is doing work; it
13197 // has said it is doing work.
13198 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013199 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013200 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013201 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013202 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013203 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013204 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013205 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013206 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013207 // XXX should compute this based on the max of
13208 // all connected clients.
13209 ConnectionRecord cr = clist.get(i);
13210 if (cr.binding.client == app) {
13211 // Binding to ourself is not interesting.
13212 continue;
13213 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013214 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013215 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013216 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013217 int myHiddenAdj = hiddenAdj;
13218 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013219 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013220 myHiddenAdj = client.hiddenAdj;
13221 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013222 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013223 }
13224 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013225 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013226 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013227 String adjType = null;
13228 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13229 // Not doing bind OOM management, so treat
13230 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013231 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013232 // If this process has shown some UI, let it immediately
13233 // go to the LRU list because it may be pretty heavy with
13234 // UI stuff. We'll tag it with a label just to help
13235 // debug and understand what is going on.
13236 if (adj > clientAdj) {
13237 adjType = "bound-bg-ui-services";
13238 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013239 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013240 clientAdj = adj;
13241 } else {
13242 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13243 // This service has not seen activity within
13244 // recent memory, so allow it to drop to the
13245 // LRU list if there is no other reason to keep
13246 // it around. We'll also tag it with a label just
13247 // to help debug and undertand what is going on.
13248 if (adj > clientAdj) {
13249 adjType = "bound-bg-services";
13250 }
13251 clientAdj = adj;
13252 }
13253 }
13254 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013255 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013256 // If this process has recently shown UI, and
13257 // the process that is binding to it is less
13258 // important than being visible, then we don't
13259 // care about the binding as much as we care
13260 // about letting this process get into the LRU
13261 // list to be killed and restarted if needed for
13262 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013263 if (app.hasShownUi && app != mHomeProcess
13264 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013265 adjType = "bound-bg-ui-services";
13266 } else {
13267 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13268 |Context.BIND_IMPORTANT)) != 0) {
13269 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013270 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13271 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13272 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13273 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13274 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013275 adj = clientAdj;
13276 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013277 app.pendingUiClean = true;
13278 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13279 adj = ProcessList.VISIBLE_APP_ADJ;
13280 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013281 }
13282 if (!client.hidden) {
13283 app.hidden = false;
13284 }
13285 if (client.keeping) {
13286 app.keeping = true;
13287 }
13288 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013289 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013290 }
13291 if (adjType != null) {
13292 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013293 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13294 .REASON_SERVICE_IN_USE;
13295 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013296 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013297 app.adjTarget = s.name;
13298 }
13299 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13300 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13301 schedGroup = Process.THREAD_GROUP_DEFAULT;
13302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013303 }
13304 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013305 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13306 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013307 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013308 (a.visible || a.state == ActivityState.RESUMED
13309 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013310 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013311 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13312 schedGroup = Process.THREAD_GROUP_DEFAULT;
13313 }
13314 app.hidden = false;
13315 app.adjType = "service";
13316 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13317 .REASON_SERVICE_IN_USE;
13318 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013319 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013320 app.adjTarget = s.name;
13321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 }
13324 }
13325 }
13326 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013327
Dianne Hackborn287952c2010-09-22 22:34:31 -070013328 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013329 // would like to avoid killing it unless it would prevent the current
13330 // application from running. By default we put the process in
13331 // with the rest of the background processes; as we scan through
13332 // its services we may bump it up from there.
13333 if (adj > hiddenAdj) {
13334 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013335 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013336 app.adjType = "bg-services";
13337 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013338 }
13339
Dianne Hackborn7d608422011-08-07 16:24:18 -070013340 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013341 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013342 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013343 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013344 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013345 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013346 if (cpr.clients.size() != 0) {
13347 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013348 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013349 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013350 if (client == app) {
13351 // Being our own client is not interesting.
13352 continue;
13353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013354 int myHiddenAdj = hiddenAdj;
13355 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013356 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013357 myHiddenAdj = client.hiddenAdj;
13358 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013359 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013360 }
13361 }
13362 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013363 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013364 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013365 if (app.hasShownUi && app != mHomeProcess
13366 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013367 app.adjType = "bg-ui-provider";
13368 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013369 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13370 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013371 app.adjType = "provider";
13372 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013373 if (!client.hidden) {
13374 app.hidden = false;
13375 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013376 if (client.keeping) {
13377 app.keeping = true;
13378 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013379 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13380 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013381 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013382 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013383 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013384 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013385 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13386 schedGroup = Process.THREAD_GROUP_DEFAULT;
13387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013388 }
13389 }
13390 // If the provider has external (non-framework) process
13391 // dependencies, ensure that its adjustment is at least
13392 // FOREGROUND_APP_ADJ.
13393 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013394 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13395 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013396 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013397 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013398 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013399 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013400 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013401 }
13402 }
13403 }
13404 }
13405
13406 app.curRawAdj = adj;
13407
Joe Onorato8a9b2202010-02-26 18:56:32 -080013408 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013409 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13410 if (adj > app.maxAdj) {
13411 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013412 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013413 schedGroup = Process.THREAD_GROUP_DEFAULT;
13414 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013415 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013416 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013417 app.keeping = true;
13418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013419
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013420 if (app.hasAboveClient) {
13421 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13422 // then we need to drop its adjustment to be lower than the service's
13423 // in order to honor the request. We want to drop it by one adjustment
13424 // level... but there is special meaning applied to various levels so
13425 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013426 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013427 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013428 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13429 adj = ProcessList.VISIBLE_APP_ADJ;
13430 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13431 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13432 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13433 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013434 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013435 adj++;
13436 }
13437 }
13438
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013439 if (adj == ProcessList.SERVICE_ADJ) {
13440 if (doingAll) {
13441 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13442 mNewNumServiceProcs++;
13443 }
13444 if (app.serviceb) {
13445 adj = ProcessList.SERVICE_B_ADJ;
13446 }
13447 } else {
13448 app.serviceb = false;
13449 }
13450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013451 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013452 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013453
13454 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013455 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13456 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013457 }
13458
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013459 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013460 }
13461
13462 /**
13463 * Ask a given process to GC right now.
13464 */
13465 final void performAppGcLocked(ProcessRecord app) {
13466 try {
13467 app.lastRequestedGc = SystemClock.uptimeMillis();
13468 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013469 if (app.reportLowMemory) {
13470 app.reportLowMemory = false;
13471 app.thread.scheduleLowMemory();
13472 } else {
13473 app.thread.processInBackground();
13474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013475 }
13476 } catch (Exception e) {
13477 // whatever.
13478 }
13479 }
13480
13481 /**
13482 * Returns true if things are idle enough to perform GCs.
13483 */
Josh Bartel7f208742010-02-25 11:01:44 -060013484 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013485 return mParallelBroadcasts.size() == 0
13486 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013487 && (mSleeping || (mMainStack.mResumedActivity != null &&
13488 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013489 }
13490
13491 /**
13492 * Perform GCs on all processes that are waiting for it, but only
13493 * if things are idle.
13494 */
13495 final void performAppGcsLocked() {
13496 final int N = mProcessesToGc.size();
13497 if (N <= 0) {
13498 return;
13499 }
Josh Bartel7f208742010-02-25 11:01:44 -060013500 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013501 while (mProcessesToGc.size() > 0) {
13502 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013503 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013504 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13505 <= SystemClock.uptimeMillis()) {
13506 // To avoid spamming the system, we will GC processes one
13507 // at a time, waiting a few seconds between each.
13508 performAppGcLocked(proc);
13509 scheduleAppGcsLocked();
13510 return;
13511 } else {
13512 // It hasn't been long enough since we last GCed this
13513 // process... put it in the list to wait for its time.
13514 addProcessToGcListLocked(proc);
13515 break;
13516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 }
13518 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013519
13520 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013521 }
13522 }
13523
13524 /**
13525 * If all looks good, perform GCs on all processes waiting for them.
13526 */
13527 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013528 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013529 performAppGcsLocked();
13530 return;
13531 }
13532 // Still not idle, wait some more.
13533 scheduleAppGcsLocked();
13534 }
13535
13536 /**
13537 * Schedule the execution of all pending app GCs.
13538 */
13539 final void scheduleAppGcsLocked() {
13540 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013541
13542 if (mProcessesToGc.size() > 0) {
13543 // Schedule a GC for the time to the next process.
13544 ProcessRecord proc = mProcessesToGc.get(0);
13545 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13546
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013547 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013548 long now = SystemClock.uptimeMillis();
13549 if (when < (now+GC_TIMEOUT)) {
13550 when = now + GC_TIMEOUT;
13551 }
13552 mHandler.sendMessageAtTime(msg, when);
13553 }
13554 }
13555
13556 /**
13557 * Add a process to the array of processes waiting to be GCed. Keeps the
13558 * list in sorted order by the last GC time. The process can't already be
13559 * on the list.
13560 */
13561 final void addProcessToGcListLocked(ProcessRecord proc) {
13562 boolean added = false;
13563 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13564 if (mProcessesToGc.get(i).lastRequestedGc <
13565 proc.lastRequestedGc) {
13566 added = true;
13567 mProcessesToGc.add(i+1, proc);
13568 break;
13569 }
13570 }
13571 if (!added) {
13572 mProcessesToGc.add(0, proc);
13573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013574 }
13575
13576 /**
13577 * Set up to ask a process to GC itself. This will either do it
13578 * immediately, or put it on the list of processes to gc the next
13579 * time things are idle.
13580 */
13581 final void scheduleAppGcLocked(ProcessRecord app) {
13582 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013583 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013584 return;
13585 }
13586 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013587 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013588 scheduleAppGcsLocked();
13589 }
13590 }
13591
Dianne Hackborn287952c2010-09-22 22:34:31 -070013592 final void checkExcessivePowerUsageLocked(boolean doKills) {
13593 updateCpuStatsNow();
13594
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013595 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013596 boolean doWakeKills = doKills;
13597 boolean doCpuKills = doKills;
13598 if (mLastPowerCheckRealtime == 0) {
13599 doWakeKills = false;
13600 }
13601 if (mLastPowerCheckUptime == 0) {
13602 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013603 }
13604 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013605 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013606 }
13607 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013608 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13609 final long curUptime = SystemClock.uptimeMillis();
13610 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13611 mLastPowerCheckRealtime = curRealtime;
13612 mLastPowerCheckUptime = curUptime;
13613 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13614 doWakeKills = false;
13615 }
13616 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13617 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013618 }
13619 int i = mLruProcesses.size();
13620 while (i > 0) {
13621 i--;
13622 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013623 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013624 long wtime;
13625 synchronized (stats) {
13626 wtime = stats.getProcessWakeTime(app.info.uid,
13627 app.pid, curRealtime);
13628 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013629 long wtimeUsed = wtime - app.lastWakeTime;
13630 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13631 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013632 StringBuilder sb = new StringBuilder(128);
13633 sb.append("Wake for ");
13634 app.toShortString(sb);
13635 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013636 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013637 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013638 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013639 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013640 sb.append((wtimeUsed*100)/realtimeSince);
13641 sb.append("%)");
13642 Slog.i(TAG, sb.toString());
13643 sb.setLength(0);
13644 sb.append("CPU for ");
13645 app.toShortString(sb);
13646 sb.append(": over ");
13647 TimeUtils.formatDuration(uptimeSince, sb);
13648 sb.append(" used ");
13649 TimeUtils.formatDuration(cputimeUsed, sb);
13650 sb.append(" (");
13651 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013652 sb.append("%)");
13653 Slog.i(TAG, sb.toString());
13654 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013655 // If a process has held a wake lock for more
13656 // than 50% of the time during this period,
13657 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013658 if (doWakeKills && realtimeSince > 0
13659 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13660 synchronized (stats) {
13661 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13662 realtimeSince, wtimeUsed);
13663 }
13664 Slog.w(TAG, "Excessive wake lock in " + app.processName
13665 + " (pid " + app.pid + "): held " + wtimeUsed
13666 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013667 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13668 app.processName, app.setAdj, "excessive wake lock");
13669 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013670 } else if (doCpuKills && uptimeSince > 0
13671 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13672 synchronized (stats) {
13673 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13674 uptimeSince, cputimeUsed);
13675 }
13676 Slog.w(TAG, "Excessive CPU in " + app.processName
13677 + " (pid " + app.pid + "): used " + cputimeUsed
13678 + " during " + uptimeSince);
13679 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13680 app.processName, app.setAdj, "excessive cpu");
13681 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013682 } else {
13683 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013684 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013685 }
13686 }
13687 }
13688 }
13689
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013690 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013691 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013692 app.hiddenAdj = hiddenAdj;
13693
13694 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013695 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013696 }
13697
Dianne Hackborn287952c2010-09-22 22:34:31 -070013698 final boolean wasKeeping = app.keeping;
13699
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013700 boolean success = true;
13701
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013702 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013703
Jeff Brown10e89712011-07-08 18:52:57 -070013704 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013705 if (false) {
13706 // Removing for now. Forcing GCs is not so useful anymore
13707 // with Dalvik, and the new memory level hint facility is
13708 // better for what we need to do these days.
13709 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13710 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13711 // If this app is transitioning from foreground to
13712 // non-foreground, have it do a gc.
13713 scheduleAppGcLocked(app);
13714 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13715 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13716 // Likewise do a gc when an app is moving in to the
13717 // background (such as a service stopping).
13718 scheduleAppGcLocked(app);
13719 }
Jeff Brown10e89712011-07-08 18:52:57 -070013720 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013721
Jeff Brown10e89712011-07-08 18:52:57 -070013722 if (wasKeeping && !app.keeping) {
13723 // This app is no longer something we want to keep. Note
13724 // its current wake lock time to later know to kill it if
13725 // it is not behaving well.
13726 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13727 synchronized (stats) {
13728 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13729 app.pid, SystemClock.elapsedRealtime());
13730 }
13731 app.lastCpuTime = app.curCpuTime;
13732 }
13733
13734 app.setRawAdj = app.curRawAdj;
13735 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013736
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013737 if (app.curAdj != app.setAdj) {
13738 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013739 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13740 TAG, "Set " + app.pid + " " + app.processName +
13741 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013742 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013743 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013744 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013745 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013746 }
13747 }
13748 if (app.setSchedGroup != app.curSchedGroup) {
13749 app.setSchedGroup = app.curSchedGroup;
13750 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13751 "Setting process group of " + app.processName
13752 + " to " + app.curSchedGroup);
13753 if (app.waitingToKill != null &&
13754 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13755 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13756 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13757 app.processName, app.setAdj, app.waitingToKill);
13758 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013759 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013760 } else {
13761 if (true) {
13762 long oldId = Binder.clearCallingIdentity();
13763 try {
13764 Process.setProcessGroup(app.pid, app.curSchedGroup);
13765 } catch (Exception e) {
13766 Slog.w(TAG, "Failed setting process group of " + app.pid
13767 + " to " + app.curSchedGroup);
13768 e.printStackTrace();
13769 } finally {
13770 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013771 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013772 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013773 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013774 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013775 app.thread.setSchedulingGroup(app.curSchedGroup);
13776 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013777 }
13778 }
13779 }
13780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013781 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013782 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013783 }
13784
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013785 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013786 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013787 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013788 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013789 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013790 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013791 }
13792 }
13793 return resumedActivity;
13794 }
13795
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013796 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013797 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013798 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13799 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013800 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13801 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013802
13803 mAdjSeq++;
13804
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013805 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013806 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13807 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013808 if (nowHidden != wasHidden) {
13809 // Changed to/from hidden state, so apps after it in the LRU
13810 // list may also be changed.
13811 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013812 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013813 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013814 }
13815
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013816 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013817 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013818 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13819
13820 if (false) {
13821 RuntimeException e = new RuntimeException();
13822 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013823 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013824 }
13825
13826 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013827 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013828
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013829 // Let's determine how many processes we have running vs.
13830 // how many slots we have for background processes; we may want
13831 // to put multiple processes in a slot of there are enough of
13832 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013833 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013834 int factor = (mLruProcesses.size()-4)/numSlots;
13835 if (factor < 1) factor = 1;
13836 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013837 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013838
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013839 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013840 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013841 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013842 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013843 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013844 while (i > 0) {
13845 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013846 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013847 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013848 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
13849 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013850 && app.curAdj == curHiddenAdj) {
13851 step++;
13852 if (step >= factor) {
13853 step = 0;
13854 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013855 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013856 }
13857 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013858 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013859 numHidden++;
13860 if (numHidden > mProcessLimit) {
13861 Slog.i(TAG, "No longer want " + app.processName
13862 + " (pid " + app.pid + "): hidden #" + numHidden);
13863 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13864 app.processName, app.setAdj, "too many background");
13865 app.killedBackground = true;
13866 Process.killProcessQuiet(app.pid);
13867 } else {
13868 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013869 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013870 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ
13871 && app.curAdj != ProcessList.SERVICE_B_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013872 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013874 }
13875 }
13876
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013877 mNumServiceProcs = mNewNumServiceProcs;
13878
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013879 // Now determine the memory trimming level of background processes.
13880 // Unfortunately we need to start at the back of the list to do this
13881 // properly. We only do this if the number of background apps we
13882 // are managing to keep around is less than half the maximum we desire;
13883 // if we are keeping a good number around, we'll let them use whatever
13884 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013885 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013886 final int N = mLruProcesses.size();
13887 factor = numBg/3;
13888 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013889 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013890 for (i=0; i<N; i++) {
13891 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013892 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013893 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13894 try {
13895 app.thread.scheduleTrimMemory(curLevel);
13896 } catch (RemoteException e) {
13897 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013898 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013899 // For these apps we will also finish their activities
13900 // to help them free memory.
13901 mMainStack.destroyActivitiesLocked(app, false);
13902 }
13903 }
13904 app.trimMemoryLevel = curLevel;
13905 step++;
13906 if (step >= factor) {
13907 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013908 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13909 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013910 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013911 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13912 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013913 break;
13914 }
13915 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013916 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013917 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013918 && app.thread != null) {
13919 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013920 app.thread.scheduleTrimMemory(
13921 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013922 } catch (RemoteException e) {
13923 }
13924 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013925 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013926 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013927 && app.pendingUiClean) {
13928 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13929 && app.thread != null) {
13930 try {
13931 app.thread.scheduleTrimMemory(
13932 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13933 } catch (RemoteException e) {
13934 }
13935 }
13936 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13937 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013938 } else {
13939 app.trimMemoryLevel = 0;
13940 }
13941 }
13942 } else {
13943 final int N = mLruProcesses.size();
13944 for (i=0; i<N; i++) {
13945 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013946 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013947 && app.pendingUiClean) {
13948 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13949 && app.thread != null) {
13950 try {
13951 app.thread.scheduleTrimMemory(
13952 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13953 } catch (RemoteException e) {
13954 }
13955 }
13956 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13957 app.pendingUiClean = false;
13958 } else {
13959 app.trimMemoryLevel = 0;
13960 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013961 }
13962 }
13963
13964 if (mAlwaysFinishActivities) {
13965 mMainStack.destroyActivitiesLocked(null, false);
13966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013967 }
13968
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013969 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013970 synchronized (this) {
13971 int i;
13972
13973 // First remove any unused application processes whose package
13974 // has been removed.
13975 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13976 final ProcessRecord app = mRemovedProcesses.get(i);
13977 if (app.activities.size() == 0
13978 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013979 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013980 TAG, "Exiting empty application process "
13981 + app.processName + " ("
13982 + (app.thread != null ? app.thread.asBinder() : null)
13983 + ")\n");
13984 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013985 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13986 app.processName, app.setAdj, "empty");
13987 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013988 } else {
13989 try {
13990 app.thread.scheduleExit();
13991 } catch (Exception e) {
13992 // Ignore exceptions.
13993 }
13994 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013995 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013996 mRemovedProcesses.remove(i);
13997
13998 if (app.persistent) {
13999 if (app.persistent) {
14000 addAppLocked(app.info);
14001 }
14002 }
14003 }
14004 }
14005
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014006 // Now update the oom adj for all processes.
14007 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014008 }
14009 }
14010
14011 /** This method sends the specified signal to each of the persistent apps */
14012 public void signalPersistentProcesses(int sig) throws RemoteException {
14013 if (sig != Process.SIGNAL_USR1) {
14014 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14015 }
14016
14017 synchronized (this) {
14018 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14019 != PackageManager.PERMISSION_GRANTED) {
14020 throw new SecurityException("Requires permission "
14021 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14022 }
14023
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14025 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014026 if (r.thread != null && r.persistent) {
14027 Process.sendSignal(r.pid, sig);
14028 }
14029 }
14030 }
14031 }
14032
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014033 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14034 if (proc == null || proc == mProfileProc) {
14035 proc = mProfileProc;
14036 path = mProfileFile;
14037 profileType = mProfileType;
14038 clearProfilerLocked();
14039 }
14040 if (proc == null) {
14041 return;
14042 }
14043 try {
14044 proc.thread.profilerControl(false, path, null, profileType);
14045 } catch (RemoteException e) {
14046 throw new IllegalStateException("Process disappeared");
14047 }
14048 }
14049
14050 private void clearProfilerLocked() {
14051 if (mProfileFd != null) {
14052 try {
14053 mProfileFd.close();
14054 } catch (IOException e) {
14055 }
14056 }
14057 mProfileApp = null;
14058 mProfileProc = null;
14059 mProfileFile = null;
14060 mProfileType = 0;
14061 mAutoStopProfiler = false;
14062 }
14063
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014064 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014065 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014066
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014067 try {
14068 synchronized (this) {
14069 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14070 // its own permission.
14071 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14072 != PackageManager.PERMISSION_GRANTED) {
14073 throw new SecurityException("Requires permission "
14074 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014075 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014076
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014077 if (start && fd == null) {
14078 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014079 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014080
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014081 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014082 if (process != null) {
14083 try {
14084 int pid = Integer.parseInt(process);
14085 synchronized (mPidsSelfLocked) {
14086 proc = mPidsSelfLocked.get(pid);
14087 }
14088 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014089 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014090
14091 if (proc == null) {
14092 HashMap<String, SparseArray<ProcessRecord>> all
14093 = mProcessNames.getMap();
14094 SparseArray<ProcessRecord> procs = all.get(process);
14095 if (procs != null && procs.size() > 0) {
14096 proc = procs.valueAt(0);
14097 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014098 }
14099 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014100
14101 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014102 throw new IllegalArgumentException("Unknown process: " + process);
14103 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014104
14105 if (start) {
14106 stopProfilerLocked(null, null, 0);
14107 setProfileApp(proc.info, proc.processName, path, fd, false);
14108 mProfileProc = proc;
14109 mProfileType = profileType;
14110 try {
14111 fd = fd.dup();
14112 } catch (IOException e) {
14113 fd = null;
14114 }
14115 proc.thread.profilerControl(start, path, fd, profileType);
14116 fd = null;
14117 mProfileFd = null;
14118 } else {
14119 stopProfilerLocked(proc, path, profileType);
14120 if (fd != null) {
14121 try {
14122 fd.close();
14123 } catch (IOException e) {
14124 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014125 }
14126 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014127
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014128 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014129 }
14130 } catch (RemoteException e) {
14131 throw new IllegalStateException("Process disappeared");
14132 } finally {
14133 if (fd != null) {
14134 try {
14135 fd.close();
14136 } catch (IOException e) {
14137 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014138 }
14139 }
14140 }
Andy McFadden824c5102010-07-09 16:26:57 -070014141
14142 public boolean dumpHeap(String process, boolean managed,
14143 String path, ParcelFileDescriptor fd) throws RemoteException {
14144
14145 try {
14146 synchronized (this) {
14147 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14148 // its own permission (same as profileControl).
14149 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14150 != PackageManager.PERMISSION_GRANTED) {
14151 throw new SecurityException("Requires permission "
14152 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14153 }
14154
14155 if (fd == null) {
14156 throw new IllegalArgumentException("null fd");
14157 }
14158
14159 ProcessRecord proc = null;
14160 try {
14161 int pid = Integer.parseInt(process);
14162 synchronized (mPidsSelfLocked) {
14163 proc = mPidsSelfLocked.get(pid);
14164 }
14165 } catch (NumberFormatException e) {
14166 }
14167
14168 if (proc == null) {
14169 HashMap<String, SparseArray<ProcessRecord>> all
14170 = mProcessNames.getMap();
14171 SparseArray<ProcessRecord> procs = all.get(process);
14172 if (procs != null && procs.size() > 0) {
14173 proc = procs.valueAt(0);
14174 }
14175 }
14176
14177 if (proc == null || proc.thread == null) {
14178 throw new IllegalArgumentException("Unknown process: " + process);
14179 }
14180
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014181 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14182 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014183 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14184 throw new SecurityException("Process not debuggable: " + proc);
14185 }
14186 }
14187
14188 proc.thread.dumpHeap(managed, path, fd);
14189 fd = null;
14190 return true;
14191 }
14192 } catch (RemoteException e) {
14193 throw new IllegalStateException("Process disappeared");
14194 } finally {
14195 if (fd != null) {
14196 try {
14197 fd.close();
14198 } catch (IOException e) {
14199 }
14200 }
14201 }
14202 }
14203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014204 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14205 public void monitor() {
14206 synchronized (this) { }
14207 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014208
14209 public void onCoreSettingsChange(Bundle settings) {
14210 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14211 ProcessRecord processRecord = mLruProcesses.get(i);
14212 try {
14213 if (processRecord.thread != null) {
14214 processRecord.thread.setCoreSettings(settings);
14215 }
14216 } catch (RemoteException re) {
14217 /* ignore */
14218 }
14219 }
14220 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014221
14222 // Multi-user methods
14223
14224 public boolean switchUser(int userid) {
14225 // TODO
14226 return true;
14227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014228}