blob: cffb3912780b5f64536ab037bac3fdb9bdc6edb7 [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;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700108import android.text.format.Time;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700110import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800111import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800112import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.util.PrintWriterPrinter;
114import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700115import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import android.view.Gravity;
117import android.view.LayoutInflater;
118import android.view.View;
119import android.view.WindowManager;
120import android.view.WindowManagerPolicy;
121
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700122import java.io.BufferedInputStream;
123import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700124import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700125import java.io.DataInputStream;
126import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.File;
128import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700131import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200132import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800133import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700135import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.lang.IllegalStateException;
137import java.lang.ref.WeakReference;
138import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700139import java.util.Collections;
140import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141import java.util.HashMap;
142import java.util.HashSet;
143import java.util.Iterator;
144import java.util.List;
145import java.util.Locale;
146import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700147import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700148import java.util.concurrent.atomic.AtomicBoolean;
149import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700151public final class ActivityManagerService extends ActivityManagerNative
152 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final String TAG = "ActivityManager";
154 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400155 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 static final boolean DEBUG_SWITCH = localLOGV || false;
157 static final boolean DEBUG_TASKS = localLOGV || false;
158 static final boolean DEBUG_PAUSE = localLOGV || false;
159 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
160 static final boolean DEBUG_TRANSITION = localLOGV || false;
161 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700162 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700164 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_VISBILITY = localLOGV || false;
166 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700167 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800168 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700170 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700171 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700172 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700173 static final boolean DEBUG_POWER = localLOGV || false;
174 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 static final boolean VALIDATE_TOKENS = false;
176 static final boolean SHOW_ACTIVITY_START_TIME = true;
177
178 // Control over CPU and battery monitoring.
179 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
180 static final boolean MONITOR_CPU_USAGE = true;
181 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
182 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
183 static final boolean MONITOR_THREAD_CPU_USAGE = false;
184
Dianne Hackborn1655be42009-05-08 14:29:01 -0700185 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700186 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700187
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800188 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700190 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 // Maximum number of recent tasks that we can remember.
193 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700194
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700195 // Amount of time after a call to stopAppSwitches() during which we will
196 // prevent further untrusted switches from happening.
197 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198
199 // How long we wait for a launched process to attach to the activity manager
200 // before we decide it's never going to come up for real.
201 static final int PROC_START_TIMEOUT = 10*1000;
202
Jeff Brown3f9dd282011-07-08 20:02:19 -0700203 // How long we wait for a launched process to attach to the activity manager
204 // before we decide it's never going to come up for real, when the process was
205 // started with a wrapper for instrumentation (such as Valgrind) because it
206 // could take much longer than usual.
207 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 // How long to wait after going idle before forcing apps to GC.
210 static final int GC_TIMEOUT = 5*1000;
211
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700212 // The minimum amount of time between successive GC requests for a process.
213 static final int GC_MIN_INTERVAL = 60*1000;
214
Dianne Hackborn287952c2010-09-22 22:34:31 -0700215 // The rate at which we check for apps using excessive power -- 15 mins.
216 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
217
218 // The minimum sample duration we will allow before deciding we have
219 // enough data on wake locks to start killing things.
220 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
221
222 // The minimum sample duration we will allow before deciding we have
223 // enough data on CPU usage to start killing things.
224 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 // How long we allow a receiver to run before giving up on it.
227 static final int BROADCAST_TIMEOUT = 10*1000;
228
229 // How long we wait for a service to finish executing.
230 static final int SERVICE_TIMEOUT = 20*1000;
231
232 // How long a service needs to be running until restarting its process
233 // is no longer considered to be a relaunch of the service.
234 static final int SERVICE_RESTART_DURATION = 5*1000;
235
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700236 // How long a service needs to be running until it will start back at
237 // SERVICE_RESTART_DURATION after being killed.
238 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
239
240 // Multiplying factor to increase restart duration time by, for each time
241 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
242 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
243
244 // The minimum amount of time between restarting services that we allow.
245 // That is, when multiple services are restarting, we won't allow each
246 // to restart less than this amount of time from the last one.
247 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 // Maximum amount of time for there to be no activity on a service before
250 // we consider it non-essential and allow its process to go on the
251 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700252 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253
254 // How long we wait until we timeout on key dispatching.
255 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 // How long we wait until we timeout on key dispatching during instrumentation.
258 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
259
Dan Egnor42471dd2010-01-07 17:25:22 -0800260 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261
262 static final String[] EMPTY_STRING_ARRAY = new String[0];
263
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700264 public ActivityStack mMainStack;
265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700267 * Description of a request to start a new activity, which has been held
268 * due to app switches being disabled.
269 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700270 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700271 ActivityRecord r;
272 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700273 Uri[] grantedUriPermissions;
274 int grantedMode;
275 boolean onlyIfNeeded;
276 }
277
278 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
279 = new ArrayList<PendingActivityLaunch>();
280
281 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 * List of all active broadcasts that are to be executed immediately
283 * (without waiting for another broadcast to finish). Currently this only
284 * contains broadcasts to registered receivers, to avoid spinning up
285 * a bunch of processes to execute IntentReceiver components.
286 */
287 final ArrayList<BroadcastRecord> mParallelBroadcasts
288 = new ArrayList<BroadcastRecord>();
289
290 /**
291 * List of all active broadcasts that are to be executed one at a time.
292 * The object at the top of the list is the currently activity broadcasts;
293 * those after it are waiting for the top to finish..
294 */
295 final ArrayList<BroadcastRecord> mOrderedBroadcasts
296 = new ArrayList<BroadcastRecord>();
297
298 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800299 * Historical data of past broadcasts, for debugging.
300 */
Dianne Hackborn28695e02011-11-02 21:59:51 -0700301 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800302 final BroadcastRecord[] mBroadcastHistory
303 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Set when we current have a BROADCAST_INTENT_MSG in flight.
307 */
308 boolean mBroadcastsScheduled = false;
309
310 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 * Activity we have told the window manager to have key focus.
312 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700313 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700314 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 * List of intents that were used to start the most recent tasks.
316 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700317 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318
319 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700320 * Process management.
321 */
322 final ProcessList mProcessList = new ProcessList();
323
324 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 * All of the applications we currently have running organized by name.
326 * The keys are strings of the application package name (as
327 * returned by the package manager), and the keys are ApplicationRecord
328 * objects.
329 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700330 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331
332 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700333 * The currently running heavy-weight process, if any.
334 */
335 ProcessRecord mHeavyWeightProcess = null;
336
337 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 * The last time that various processes have crashed.
339 */
340 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
341
342 /**
343 * Set of applications that we consider to be bad, and will reject
344 * incoming broadcasts from (which the user has no control over).
345 * Processes are added to this set when they have crashed twice within
346 * a minimum amount of time; they are removed from it when they are
347 * later restarted (hopefully due to some user action). The value is the
348 * time it was added to the list.
349 */
350 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
351
352 /**
353 * All of the processes we currently have running organized by pid.
354 * The keys are the pid running the application.
355 *
356 * <p>NOTE: This object is protected by its own lock, NOT the global
357 * activity manager lock!
358 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700359 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360
361 /**
362 * All of the processes that have been forced to be foreground. The key
363 * is the pid of the caller who requested it (we hold a death
364 * link on it).
365 */
366 abstract class ForegroundToken implements IBinder.DeathRecipient {
367 int pid;
368 IBinder token;
369 }
370 final SparseArray<ForegroundToken> mForegroundProcesses
371 = new SparseArray<ForegroundToken>();
372
373 /**
374 * List of records for processes that someone had tried to start before the
375 * system was ready. We don't start them at that point, but ensure they
376 * are started by the time booting is complete.
377 */
378 final ArrayList<ProcessRecord> mProcessesOnHold
379 = new ArrayList<ProcessRecord>();
380
381 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 * List of persistent applications that are in the process
383 * of being started.
384 */
385 final ArrayList<ProcessRecord> mPersistentStartingProcesses
386 = new ArrayList<ProcessRecord>();
387
388 /**
389 * Processes that are being forcibly torn down.
390 */
391 final ArrayList<ProcessRecord> mRemovedProcesses
392 = new ArrayList<ProcessRecord>();
393
394 /**
395 * List of running applications, sorted by recent usage.
396 * The first entry in the list is the least recently used.
397 * It contains ApplicationRecord objects. This list does NOT include
398 * any persistent application records (since we never want to exit them).
399 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800400 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 = new ArrayList<ProcessRecord>();
402
403 /**
404 * List of processes that should gc as soon as things are idle.
405 */
406 final ArrayList<ProcessRecord> mProcessesToGc
407 = new ArrayList<ProcessRecord>();
408
409 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800410 * This is the process holding what we currently consider to be
411 * the "home" activity.
412 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700413 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800414
415 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700416 * This is the process holding the activity the user last visited that
417 * is in a different process from the one they are currently in.
418 */
419 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -0800420
421 /**
422 * The time at which the previous process was last visible.
423 */
424 long mPreviousProcessVisibleTime;
425
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700426 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400427 * Packages that the user has asked to have run in screen size
428 * compatibility mode instead of filling the screen.
429 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700430 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400431
432 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 * Set of PendingResultRecord objects that are currently active.
434 */
435 final HashSet mPendingResultRecords = new HashSet();
436
437 /**
438 * Set of IntentSenderRecord objects that are currently active.
439 */
440 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
441 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
442
443 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800444 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700445 * already logged DropBox entries for. Guarded by itself. If
446 * something (rogue user app) forces this over
447 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
448 */
449 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
450 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
451
452 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700453 * Strict Mode background batched logging state.
454 *
455 * The string buffer is guarded by itself, and its lock is also
456 * used to determine if another batched write is already
457 * in-flight.
458 */
459 private final StringBuilder mStrictModeBuffer = new StringBuilder();
460
461 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700462 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
463 */
464 private boolean mPendingBroadcastTimeoutMessage;
465
466 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 * Intent broadcast that we have tried to start, but are
468 * waiting for its application's process to be created. We only
469 * need one (instead of a list) because we always process broadcasts
470 * one at a time, so no others can be started while waiting for this
471 * one.
472 */
473 BroadcastRecord mPendingBroadcast = null;
474
475 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700476 * The receiver index that is pending, to restart the broadcast if needed.
477 */
478 int mPendingBroadcastRecvIndex;
479
480 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 * Keeps track of all IIntentReceivers that have been registered for
482 * broadcasts. Hash keys are the receiver IBinder, hash value is
483 * a ReceiverList.
484 */
485 final HashMap mRegisteredReceivers = new HashMap();
486
487 /**
488 * Resolver for broadcast intents to registered receivers.
489 * Holds BroadcastFilter (subclass of IntentFilter).
490 */
491 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
492 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
493 @Override
494 protected boolean allowFilterResult(
495 BroadcastFilter filter, List<BroadcastFilter> dest) {
496 IBinder target = filter.receiverList.receiver.asBinder();
497 for (int i=dest.size()-1; i>=0; i--) {
498 if (dest.get(i).receiverList.receiver.asBinder() == target) {
499 return false;
500 }
501 }
502 return true;
503 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700504
505 @Override
506 protected String packageForFilter(BroadcastFilter filter) {
507 return filter.packageName;
508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 };
510
511 /**
512 * State of all active sticky broadcasts. Keys are the action of the
513 * sticky Intent, values are an ArrayList of all broadcasted intents with
514 * that action (which should usually be one).
515 */
516 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
517 new HashMap<String, ArrayList<Intent>>();
518
519 /**
520 * All currently running services.
521 */
522 final HashMap<ComponentName, ServiceRecord> mServices =
523 new HashMap<ComponentName, ServiceRecord>();
524
525 /**
526 * All currently running services indexed by the Intent used to start them.
527 */
528 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
529 new HashMap<Intent.FilterComparison, ServiceRecord>();
530
531 /**
532 * All currently bound service connections. Keys are the IBinder of
533 * the client's IServiceConnection.
534 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700535 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
536 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537
538 /**
539 * List of services that we have been asked to start,
540 * but haven't yet been able to. It is used to hold start requests
541 * while waiting for their corresponding application thread to get
542 * going.
543 */
544 final ArrayList<ServiceRecord> mPendingServices
545 = new ArrayList<ServiceRecord>();
546
547 /**
548 * List of services that are scheduled to restart following a crash.
549 */
550 final ArrayList<ServiceRecord> mRestartingServices
551 = new ArrayList<ServiceRecord>();
552
553 /**
554 * List of services that are in the process of being stopped.
555 */
556 final ArrayList<ServiceRecord> mStoppingServices
557 = new ArrayList<ServiceRecord>();
558
559 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700560 * Backup/restore process management
561 */
562 String mBackupAppName = null;
563 BackupRecord mBackupTarget = null;
564
565 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 * List of PendingThumbnailsRecord objects of clients who are still
567 * waiting to receive all of the thumbnails for a task.
568 */
569 final ArrayList mPendingThumbnails = new ArrayList();
570
571 /**
572 * List of HistoryRecord objects that have been finished and must
573 * still report back to a pending thumbnail receiver.
574 */
575 final ArrayList mCancelledThumbnails = new ArrayList();
576
577 /**
578 * All of the currently running global content providers. Keys are a
579 * string containing the provider name and values are a
580 * ContentProviderRecord object containing the data about it. Note
581 * that a single provider may be published under multiple names, so
582 * there may be multiple entries here for a single one in mProvidersByClass.
583 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700584 final HashMap<String, ContentProviderRecord> mProvidersByName
585 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * All of the currently running global content providers. Keys are a
589 * string containing the provider's implementation class and values are a
590 * ContentProviderRecord object containing the data about it.
591 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700592 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
593 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594
595 /**
596 * List of content providers who have clients waiting for them. The
597 * application is currently being launched and the provider will be
598 * removed from this list once it is published.
599 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700600 final ArrayList<ContentProviderRecord> mLaunchingProviders
601 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602
603 /**
604 * Global set of specific Uri permissions that have been granted.
605 */
606 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
607 = new SparseArray<HashMap<Uri, UriPermission>>();
608
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800609 CoreSettingsObserver mCoreSettingsObserver;
610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 /**
612 * Thread-local storage used to carry caller permissions over through
613 * indirect content-provider access.
614 * @see #ActivityManagerService.openContentUri()
615 */
616 private class Identity {
617 public int pid;
618 public int uid;
619
620 Identity(int _pid, int _uid) {
621 pid = _pid;
622 uid = _uid;
623 }
624 }
625 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
626
627 /**
628 * All information we have collected about the runtime performance of
629 * any user id that can impact battery performance.
630 */
631 final BatteryStatsService mBatteryStatsService;
632
633 /**
634 * information about component usage
635 */
636 final UsageStatsService mUsageStatsService;
637
638 /**
639 * Current configuration information. HistoryRecord objects are given
640 * a reference to this object to indicate which configuration they are
641 * currently running in, so this object must be kept immutable.
642 */
643 Configuration mConfiguration = new Configuration();
644
645 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800646 * Current sequencing integer of the configuration, for skipping old
647 * configurations.
648 */
649 int mConfigurationSeq = 0;
650
651 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700652 * Hardware-reported OpenGLES version.
653 */
654 final int GL_ES_VERSION;
655
656 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657 * List of initialization arguments to pass to all processes when binding applications to them.
658 * For example, references to the commonly used services.
659 */
660 HashMap<String, IBinder> mAppBindArgs;
661
662 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700663 * Temporary to avoid allocations. Protected by main lock.
664 */
665 final StringBuilder mStringBuilder = new StringBuilder(256);
666
667 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 * Used to control how we initialize the service.
669 */
670 boolean mStartRunning = false;
671 ComponentName mTopComponent;
672 String mTopAction;
673 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700674 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 boolean mSystemReady = false;
676 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700677 boolean mWaitingUpdate = false;
678 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700679 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700680 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681
682 Context mContext;
683
684 int mFactoryTest;
685
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700686 boolean mCheckedForSetup;
687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700689 * The time at which we will allow normal application switches again,
690 * after a call to {@link #stopAppSwitches()}.
691 */
692 long mAppSwitchesAllowedTime;
693
694 /**
695 * This is set to true after the first switch after mAppSwitchesAllowedTime
696 * is set; any switches after that will clear the time.
697 */
698 boolean mDidAppSwitch;
699
700 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700701 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700702 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700703 long mLastPowerCheckRealtime;
704
705 /**
706 * Last time (in uptime) at which we checked for power usage.
707 */
708 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700709
710 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 * Set while we are wanting to sleep, to prevent any
712 * activities from being started/resumed.
713 */
714 boolean mSleeping = false;
715
716 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700717 * Set if we are shutting down the system, similar to sleeping.
718 */
719 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720
721 /**
722 * Task identifier that activities are currently being started
723 * in. Incremented each time a new task is created.
724 * todo: Replace this with a TokenSpace class that generates non-repeating
725 * integers that won't wrap.
726 */
727 int mCurTask = 1;
728
729 /**
730 * Current sequence id for oom_adj computation traversal.
731 */
732 int mAdjSeq = 0;
733
734 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700735 * Current sequence id for process LRU updating.
736 */
737 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738
739 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700740 * Keep track of the number of service processes we last found, to
741 * determine on the next iteration which should be B services.
742 */
743 int mNumServiceProcs = 0;
744 int mNewNumServiceProcs = 0;
745
746 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 * System monitoring: number of processes that died since the last
748 * N procs were started.
749 */
750 int[] mProcDeaths = new int[20];
751
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700752 /**
753 * This is set if we had to do a delayed dexopt of an app before launching
754 * it, to increasing the ANR timeouts in that case.
755 */
756 boolean mDidDexOpt;
757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 String mDebugApp = null;
759 boolean mWaitForDebugger = false;
760 boolean mDebugTransient = false;
761 String mOrigDebugApp = null;
762 boolean mOrigWaitForDebugger = false;
763 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700764 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700765 String mProfileApp = null;
766 ProcessRecord mProfileProc = null;
767 String mProfileFile;
768 ParcelFileDescriptor mProfileFd;
769 int mProfileType = 0;
770 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700772 final RemoteCallbackList<IActivityWatcher> mWatchers
773 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700774
775 final RemoteCallbackList<IProcessObserver> mProcessObservers
776 = new RemoteCallbackList<IProcessObserver>();
777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 /**
779 * Callback of last caller to {@link #requestPss}.
780 */
781 Runnable mRequestPssCallback;
782
783 /**
784 * Remaining processes for which we are waiting results from the last
785 * call to {@link #requestPss}.
786 */
787 final ArrayList<ProcessRecord> mRequestPssList
788 = new ArrayList<ProcessRecord>();
789
790 /**
791 * Runtime statistics collection thread. This object's lock is used to
792 * protect all related state.
793 */
794 final Thread mProcessStatsThread;
795
796 /**
797 * Used to collect process stats when showing not responding dialog.
798 * Protected by mProcessStatsThread.
799 */
800 final ProcessStats mProcessStats = new ProcessStats(
801 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700802 final AtomicLong mLastCpuTime = new AtomicLong(0);
803 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 long mLastWriteTime = 0;
806
807 /**
808 * Set to true after the system has finished booting.
809 */
810 boolean mBooted = false;
811
Dianne Hackborn7d608422011-08-07 16:24:18 -0700812 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700813 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814
815 WindowManagerService mWindowManager;
816
817 static ActivityManagerService mSelf;
818 static ActivityThread mSystemThread;
819
820 private final class AppDeathRecipient implements IBinder.DeathRecipient {
821 final ProcessRecord mApp;
822 final int mPid;
823 final IApplicationThread mAppThread;
824
825 AppDeathRecipient(ProcessRecord app, int pid,
826 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800827 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 TAG, "New death recipient " + this
829 + " for thread " + thread.asBinder());
830 mApp = app;
831 mPid = pid;
832 mAppThread = thread;
833 }
834
835 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800836 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 TAG, "Death received in " + this
838 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 synchronized(ActivityManagerService.this) {
840 appDiedLocked(mApp, mPid, mAppThread);
841 }
842 }
843 }
844
845 static final int SHOW_ERROR_MSG = 1;
846 static final int SHOW_NOT_RESPONDING_MSG = 2;
847 static final int SHOW_FACTORY_ERROR_MSG = 3;
848 static final int UPDATE_CONFIGURATION_MSG = 4;
849 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
850 static final int WAIT_FOR_DEBUGGER_MSG = 6;
851 static final int BROADCAST_INTENT_MSG = 7;
852 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 static final int SERVICE_TIMEOUT_MSG = 12;
854 static final int UPDATE_TIME_ZONE = 13;
855 static final int SHOW_UID_ERROR_MSG = 14;
856 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700858 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700859 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800860 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700861 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
862 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700863 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700864 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700865 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700866 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700867 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700868 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
869 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700870 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871
872 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700873 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700874 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875
876 final Handler mHandler = new Handler() {
877 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800878 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 //}
880
881 public void handleMessage(Message msg) {
882 switch (msg.what) {
883 case SHOW_ERROR_MSG: {
884 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 synchronized (ActivityManagerService.this) {
886 ProcessRecord proc = (ProcessRecord)data.get("app");
887 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800888 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 return;
890 }
891 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700892 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800893 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 d.show();
895 proc.crashDialog = d;
896 } else {
897 // The device is asleep, so just pretend that the user
898 // saw a crash dialog and hit "force quit".
899 res.set(0);
900 }
901 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700902
903 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 } break;
905 case SHOW_NOT_RESPONDING_MSG: {
906 synchronized (ActivityManagerService.this) {
907 HashMap data = (HashMap) msg.obj;
908 ProcessRecord proc = (ProcessRecord)data.get("app");
909 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800910 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 return;
912 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800913
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700914 Intent intent = new Intent("android.intent.action.ANR");
915 if (!mProcessesReady) {
916 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
917 }
918 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800919 null, null, 0, null, null, null,
920 false, false, MY_PID, Process.SYSTEM_UID);
921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700923 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 d.show();
925 proc.anrDialog = d;
926 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700927
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700928 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700930 case SHOW_STRICT_MODE_VIOLATION_MSG: {
931 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
932 synchronized (ActivityManagerService.this) {
933 ProcessRecord proc = (ProcessRecord) data.get("app");
934 if (proc == null) {
935 Slog.e(TAG, "App not found when showing strict mode dialog.");
936 break;
937 }
938 if (proc.crashDialog != null) {
939 Slog.e(TAG, "App already has strict mode dialog: " + proc);
940 return;
941 }
942 AppErrorResult res = (AppErrorResult) data.get("result");
943 if (!mSleeping && !mShuttingDown) {
944 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
945 d.show();
946 proc.crashDialog = d;
947 } else {
948 // The device is asleep, so just pretend that the user
949 // saw a crash dialog and hit "force quit".
950 res.set(0);
951 }
952 }
953 ensureBootCompleted();
954 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 case SHOW_FACTORY_ERROR_MSG: {
956 Dialog d = new FactoryErrorDialog(
957 mContext, msg.getData().getCharSequence("msg"));
958 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700959 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 } break;
961 case UPDATE_CONFIGURATION_MSG: {
962 final ContentResolver resolver = mContext.getContentResolver();
963 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
964 } break;
965 case GC_BACKGROUND_PROCESSES_MSG: {
966 synchronized (ActivityManagerService.this) {
967 performAppGcsIfAppropriateLocked();
968 }
969 } break;
970 case WAIT_FOR_DEBUGGER_MSG: {
971 synchronized (ActivityManagerService.this) {
972 ProcessRecord app = (ProcessRecord)msg.obj;
973 if (msg.arg1 != 0) {
974 if (!app.waitedForDebugger) {
975 Dialog d = new AppWaitingForDebuggerDialog(
976 ActivityManagerService.this,
977 mContext, app);
978 app.waitDialog = d;
979 app.waitedForDebugger = true;
980 d.show();
981 }
982 } else {
983 if (app.waitDialog != null) {
984 app.waitDialog.dismiss();
985 app.waitDialog = null;
986 }
987 }
988 }
989 } break;
990 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800991 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 TAG, "Received BROADCAST_INTENT_MSG");
993 processNextBroadcast(true);
994 } break;
995 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700996 synchronized (ActivityManagerService.this) {
997 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001001 if (mDidDexOpt) {
1002 mDidDexOpt = false;
1003 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1004 nmsg.obj = msg.obj;
1005 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1006 return;
1007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 serviceTimeout((ProcessRecord)msg.obj);
1009 } break;
1010 case UPDATE_TIME_ZONE: {
1011 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001012 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1013 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 if (r.thread != null) {
1015 try {
1016 r.thread.updateTimeZone();
1017 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001018 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 }
1020 }
1021 }
1022 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001023 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001024 case CLEAR_DNS_CACHE: {
1025 synchronized (ActivityManagerService.this) {
1026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1027 ProcessRecord r = mLruProcesses.get(i);
1028 if (r.thread != null) {
1029 try {
1030 r.thread.clearDnsCache();
1031 } catch (RemoteException ex) {
1032 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1033 }
1034 }
1035 }
1036 }
1037 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001038 case UPDATE_HTTP_PROXY: {
1039 ProxyProperties proxy = (ProxyProperties)msg.obj;
1040 String host = "";
1041 String port = "";
1042 String exclList = "";
1043 if (proxy != null) {
1044 host = proxy.getHost();
1045 port = Integer.toString(proxy.getPort());
1046 exclList = proxy.getExclusionList();
1047 }
1048 synchronized (ActivityManagerService.this) {
1049 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1050 ProcessRecord r = mLruProcesses.get(i);
1051 if (r.thread != null) {
1052 try {
1053 r.thread.setHttpProxy(host, port, exclList);
1054 } catch (RemoteException ex) {
1055 Slog.w(TAG, "Failed to update http proxy for: " +
1056 r.info.processName);
1057 }
1058 }
1059 }
1060 }
1061 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 case SHOW_UID_ERROR_MSG: {
1063 // XXX This is a temporary dialog, no need to localize.
1064 AlertDialog d = new BaseErrorDialog(mContext);
1065 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1066 d.setCancelable(false);
1067 d.setTitle("System UIDs Inconsistent");
1068 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 +02001069 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1071 mUidAlert = d;
1072 d.show();
1073 } break;
1074 case IM_FEELING_LUCKY_MSG: {
1075 if (mUidAlert != null) {
1076 mUidAlert.dismiss();
1077 mUidAlert = null;
1078 }
1079 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001081 if (mDidDexOpt) {
1082 mDidDexOpt = false;
1083 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1084 nmsg.obj = msg.obj;
1085 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1086 return;
1087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 ProcessRecord app = (ProcessRecord)msg.obj;
1089 synchronized (ActivityManagerService.this) {
1090 processStartTimedOutLocked(app);
1091 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001092 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001093 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1094 synchronized (ActivityManagerService.this) {
1095 doPendingActivityLaunchesLocked(true);
1096 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001097 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001098 case KILL_APPLICATION_MSG: {
1099 synchronized (ActivityManagerService.this) {
1100 int uid = msg.arg1;
1101 boolean restart = (msg.arg2 == 1);
1102 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001103 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001104 }
1105 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001106 case FINALIZE_PENDING_INTENT_MSG: {
1107 ((PendingIntentRecord)msg.obj).completeFinalize();
1108 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001109 case POST_HEAVY_NOTIFICATION_MSG: {
1110 INotificationManager inm = NotificationManager.getService();
1111 if (inm == null) {
1112 return;
1113 }
1114
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001115 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001116 ProcessRecord process = root.app;
1117 if (process == null) {
1118 return;
1119 }
1120
1121 try {
1122 Context context = mContext.createPackageContext(process.info.packageName, 0);
1123 String text = mContext.getString(R.string.heavy_weight_notification,
1124 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1125 Notification notification = new Notification();
1126 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1127 notification.when = 0;
1128 notification.flags = Notification.FLAG_ONGOING_EVENT;
1129 notification.tickerText = text;
1130 notification.defaults = 0; // please be quiet
1131 notification.sound = null;
1132 notification.vibrate = null;
1133 notification.setLatestEventInfo(context, text,
1134 mContext.getText(R.string.heavy_weight_notification_detail),
1135 PendingIntent.getActivity(mContext, 0, root.intent,
1136 PendingIntent.FLAG_CANCEL_CURRENT));
1137
1138 try {
1139 int[] outId = new int[1];
1140 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1141 notification, outId);
1142 } catch (RuntimeException e) {
1143 Slog.w(ActivityManagerService.TAG,
1144 "Error showing notification for heavy-weight app", e);
1145 } catch (RemoteException e) {
1146 }
1147 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001148 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001149 }
1150 } break;
1151 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1152 INotificationManager inm = NotificationManager.getService();
1153 if (inm == null) {
1154 return;
1155 }
1156 try {
1157 inm.cancelNotification("android",
1158 R.string.heavy_weight_notification);
1159 } catch (RuntimeException e) {
1160 Slog.w(ActivityManagerService.TAG,
1161 "Error canceling notification for service", e);
1162 } catch (RemoteException e) {
1163 }
1164 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001165 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1166 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001167 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001168 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001169 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1170 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001171 }
1172 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001173 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1174 synchronized (ActivityManagerService.this) {
1175 ActivityRecord ar = (ActivityRecord)msg.obj;
1176 if (mCompatModeDialog != null) {
1177 if (mCompatModeDialog.mAppInfo.packageName.equals(
1178 ar.info.applicationInfo.packageName)) {
1179 return;
1180 }
1181 mCompatModeDialog.dismiss();
1182 mCompatModeDialog = null;
1183 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001184 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001185 if (mCompatModePackages.getPackageAskCompatModeLocked(
1186 ar.packageName)) {
1187 int mode = mCompatModePackages.computeCompatModeLocked(
1188 ar.info.applicationInfo);
1189 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1190 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1191 mCompatModeDialog = new CompatModeDialog(
1192 ActivityManagerService.this, mContext,
1193 ar.info.applicationInfo);
1194 mCompatModeDialog.show();
1195 }
1196 }
1197 }
1198 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001199 break;
1200 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001201 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001202 final int pid = msg.arg1;
1203 final int uid = msg.arg2;
1204 final boolean foregroundActivities = (Boolean) msg.obj;
1205 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001206 break;
1207 }
1208 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001209 final int pid = msg.arg1;
1210 final int uid = msg.arg2;
1211 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001212 break;
1213 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001214 case REPORT_MEM_USAGE: {
1215 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1216 if (!isDebuggable) {
1217 return;
1218 }
1219 synchronized (ActivityManagerService.this) {
1220 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001221 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1222 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001223 // avoid spamming.
1224 return;
1225 }
1226 mLastMemUsageReportTime = now;
1227 }
1228 Thread thread = new Thread() {
1229 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001230 StringBuilder dropBuilder = new StringBuilder(1024);
1231 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001232 StringWriter oomSw = new StringWriter();
1233 PrintWriter oomPw = new PrintWriter(oomSw);
1234 StringWriter catSw = new StringWriter();
1235 PrintWriter catPw = new PrintWriter(catSw);
1236 String[] emptyArgs = new String[] { };
1237 StringBuilder tag = new StringBuilder(128);
1238 StringBuilder stack = new StringBuilder(128);
1239 tag.append("Low on memory -- ");
1240 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1241 tag, stack);
1242 dropBuilder.append(stack);
1243 dropBuilder.append('\n');
1244 dropBuilder.append('\n');
1245 String oomString = oomSw.toString();
1246 dropBuilder.append(oomString);
1247 dropBuilder.append('\n');
1248 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001249 try {
1250 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1251 "procrank", });
1252 final InputStreamReader converter = new InputStreamReader(
1253 proc.getInputStream());
1254 BufferedReader in = new BufferedReader(converter);
1255 String line;
1256 while (true) {
1257 line = in.readLine();
1258 if (line == null) {
1259 break;
1260 }
1261 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001262 logBuilder.append(line);
1263 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001264 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001265 dropBuilder.append(line);
1266 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001267 }
1268 converter.close();
1269 } catch (IOException e) {
1270 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001271 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001272 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001273 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001274 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001275 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001276 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001277 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001278 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001279 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001280 addErrorToDropBox("lowmem", null, "system_server", null,
1281 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001282 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001283 synchronized (ActivityManagerService.this) {
1284 long now = SystemClock.uptimeMillis();
1285 if (mLastMemUsageReportTime < now) {
1286 mLastMemUsageReportTime = now;
1287 }
1288 }
1289 }
1290 };
1291 thread.start();
1292 break;
1293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 }
1295 }
1296 };
1297
1298 public static void setSystemProcess() {
1299 try {
1300 ActivityManagerService m = mSelf;
1301
1302 ServiceManager.addService("activity", m);
1303 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001304 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 if (MONITOR_CPU_USAGE) {
1306 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 ServiceManager.addService("permission", new PermissionController(m));
1309
1310 ApplicationInfo info =
1311 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001312 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001313 mSystemThread.installSystemApplicationInfo(info);
1314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 synchronized (mSelf) {
1316 ProcessRecord app = mSelf.newProcessRecordLocked(
1317 mSystemThread.getApplicationThread(), info,
1318 info.processName);
1319 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001320 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001321 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1323 synchronized (mSelf.mPidsSelfLocked) {
1324 mSelf.mPidsSelfLocked.put(app.pid, app);
1325 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001326 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 }
1328 } catch (PackageManager.NameNotFoundException e) {
1329 throw new RuntimeException(
1330 "Unable to find android system package", e);
1331 }
1332 }
1333
1334 public void setWindowManager(WindowManagerService wm) {
1335 mWindowManager = wm;
1336 }
1337
1338 public static final Context main(int factoryTest) {
1339 AThread thr = new AThread();
1340 thr.start();
1341
1342 synchronized (thr) {
1343 while (thr.mService == null) {
1344 try {
1345 thr.wait();
1346 } catch (InterruptedException e) {
1347 }
1348 }
1349 }
1350
1351 ActivityManagerService m = thr.mService;
1352 mSelf = m;
1353 ActivityThread at = ActivityThread.systemMain();
1354 mSystemThread = at;
1355 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001356 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 m.mContext = context;
1358 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001359 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360
1361 m.mBatteryStatsService.publish(context);
1362 m.mUsageStatsService.publish(context);
1363
1364 synchronized (thr) {
1365 thr.mReady = true;
1366 thr.notifyAll();
1367 }
1368
1369 m.startRunning(null, null, null, null);
1370
1371 return context;
1372 }
1373
1374 public static ActivityManagerService self() {
1375 return mSelf;
1376 }
1377
1378 static class AThread extends Thread {
1379 ActivityManagerService mService;
1380 boolean mReady = false;
1381
1382 public AThread() {
1383 super("ActivityManager");
1384 }
1385
1386 public void run() {
1387 Looper.prepare();
1388
1389 android.os.Process.setThreadPriority(
1390 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001391 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392
1393 ActivityManagerService m = new ActivityManagerService();
1394
1395 synchronized (this) {
1396 mService = m;
1397 notifyAll();
1398 }
1399
1400 synchronized (this) {
1401 while (!mReady) {
1402 try {
1403 wait();
1404 } catch (InterruptedException e) {
1405 }
1406 }
1407 }
1408
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001409 // For debug builds, log event loop stalls to dropbox for analysis.
1410 if (StrictMode.conditionallyEnableDebugLogging()) {
1411 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1412 }
1413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 Looper.loop();
1415 }
1416 }
1417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 static class MemBinder extends Binder {
1419 ActivityManagerService mActivityManagerService;
1420 MemBinder(ActivityManagerService activityManagerService) {
1421 mActivityManagerService = activityManagerService;
1422 }
1423
1424 @Override
1425 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001426 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1427 != PackageManager.PERMISSION_GRANTED) {
1428 pw.println("Permission Denial: can't dump meminfo from from pid="
1429 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1430 + " without permission " + android.Manifest.permission.DUMP);
1431 return;
1432 }
1433
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001434 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001435 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 }
1437 }
1438
Chet Haase9c1e23b2011-03-24 10:51:31 -07001439 static class GraphicsBinder extends Binder {
1440 ActivityManagerService mActivityManagerService;
1441 GraphicsBinder(ActivityManagerService activityManagerService) {
1442 mActivityManagerService = activityManagerService;
1443 }
1444
1445 @Override
1446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001447 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1448 != PackageManager.PERMISSION_GRANTED) {
1449 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1450 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1451 + " without permission " + android.Manifest.permission.DUMP);
1452 return;
1453 }
1454
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001455 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001456 }
1457 }
1458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 static class CpuBinder extends Binder {
1460 ActivityManagerService mActivityManagerService;
1461 CpuBinder(ActivityManagerService activityManagerService) {
1462 mActivityManagerService = activityManagerService;
1463 }
1464
1465 @Override
1466 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001467 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1468 != PackageManager.PERMISSION_GRANTED) {
1469 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1470 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1471 + " without permission " + android.Manifest.permission.DUMP);
1472 return;
1473 }
1474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001476 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1477 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1478 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 }
1480 }
1481 }
1482
1483 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001484 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 File dataDir = Environment.getDataDirectory();
1487 File systemDir = new File(dataDir, "system");
1488 systemDir.mkdirs();
1489 mBatteryStatsService = new BatteryStatsService(new File(
1490 systemDir, "batterystats.bin").toString());
1491 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001492 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001493 mOnBattery = DEBUG_POWER ? true
1494 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001495 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001497 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001498 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499
Jack Palevichb90d28c2009-07-22 15:35:24 -07001500 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1501 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1502
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001503 mConfiguration.setToDefaults();
1504 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001505 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 mProcessStats.init();
1507
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001508 mCompatModePackages = new CompatModePackages(this, systemDir);
1509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 // Add ourself to the Watchdog monitors.
1511 Watchdog.getInstance().addMonitor(this);
1512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 mProcessStatsThread = new Thread("ProcessStats") {
1514 public void run() {
1515 while (true) {
1516 try {
1517 try {
1518 synchronized(this) {
1519 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001520 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001522 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 // + ", write delay=" + nextWriteDelay);
1524 if (nextWriteDelay < nextCpuDelay) {
1525 nextCpuDelay = nextWriteDelay;
1526 }
1527 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001528 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 this.wait(nextCpuDelay);
1530 }
1531 }
1532 } catch (InterruptedException e) {
1533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 updateCpuStatsNow();
1535 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001536 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 }
1538 }
1539 }
1540 };
1541 mProcessStatsThread.start();
1542 }
1543
1544 @Override
1545 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1546 throws RemoteException {
1547 try {
1548 return super.onTransact(code, data, reply, flags);
1549 } catch (RuntimeException e) {
1550 // The activity manager only throws security exceptions, so let's
1551 // log all others.
1552 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001553 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 }
1555 throw e;
1556 }
1557 }
1558
1559 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001560 final long now = SystemClock.uptimeMillis();
1561 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1562 return;
1563 }
1564 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1565 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 mProcessStatsThread.notify();
1567 }
1568 }
1569 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 void updateCpuStatsNow() {
1572 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001573 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 final long now = SystemClock.uptimeMillis();
1575 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001578 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1579 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 haveNewCpuStats = true;
1581 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001582 //Slog.i(TAG, mProcessStats.printCurrentState());
1583 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 // + mProcessStats.getTotalCpuPercent() + "%");
1585
Joe Onorato8a9b2202010-02-26 18:56:32 -08001586 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 if ("true".equals(SystemProperties.get("events.cpu"))) {
1588 int user = mProcessStats.getLastUserTime();
1589 int system = mProcessStats.getLastSystemTime();
1590 int iowait = mProcessStats.getLastIoWaitTime();
1591 int irq = mProcessStats.getLastIrqTime();
1592 int softIrq = mProcessStats.getLastSoftIrqTime();
1593 int idle = mProcessStats.getLastIdleTime();
1594
1595 int total = user + system + iowait + irq + softIrq + idle;
1596 if (total == 0) total = 1;
1597
Doug Zongker2bec3d42009-12-04 12:52:44 -08001598 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 ((user+system+iowait+irq+softIrq) * 100) / total,
1600 (user * 100) / total,
1601 (system * 100) / total,
1602 (iowait * 100) / total,
1603 (irq * 100) / total,
1604 (softIrq * 100) / total);
1605 }
1606 }
1607
Amith Yamasanie43530a2009-08-21 13:11:37 -07001608 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001609 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001610 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 synchronized(mPidsSelfLocked) {
1612 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001613 if (mOnBattery) {
1614 int perc = bstats.startAddingCpuLocked();
1615 int totalUTime = 0;
1616 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001617 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001618 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001619 ProcessStats.Stats st = mProcessStats.getStats(i);
1620 if (!st.working) {
1621 continue;
1622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001624 int otherUTime = (st.rel_utime*perc)/100;
1625 int otherSTime = (st.rel_stime*perc)/100;
1626 totalUTime += otherUTime;
1627 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 if (pr != null) {
1629 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001630 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1631 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001632 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001633 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001634 } else {
1635 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001636 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001637 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001638 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1639 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001640 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 }
1643 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001644 bstats.finishAddingCpuLocked(perc, totalUTime,
1645 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001646 }
1647 }
1648 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1651 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001652 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 }
1654 }
1655 }
1656 }
1657
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001658 @Override
1659 public void batteryNeedsCpuUpdate() {
1660 updateCpuStatsNow();
1661 }
1662
1663 @Override
1664 public void batteryPowerChanged(boolean onBattery) {
1665 // When plugging in, update the CPU stats first before changing
1666 // the plug state.
1667 updateCpuStatsNow();
1668 synchronized (this) {
1669 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001670 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001671 }
1672 }
1673 }
1674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 /**
1676 * Initialize the application bind args. These are passed to each
1677 * process when the bindApplication() IPC is sent to the process. They're
1678 * lazily setup to make sure the services are running when they're asked for.
1679 */
1680 private HashMap<String, IBinder> getCommonServicesLocked() {
1681 if (mAppBindArgs == null) {
1682 mAppBindArgs = new HashMap<String, IBinder>();
1683
1684 // Setup the application init args
1685 mAppBindArgs.put("package", ServiceManager.getService("package"));
1686 mAppBindArgs.put("window", ServiceManager.getService("window"));
1687 mAppBindArgs.put(Context.ALARM_SERVICE,
1688 ServiceManager.getService(Context.ALARM_SERVICE));
1689 }
1690 return mAppBindArgs;
1691 }
1692
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001693 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 if (mFocusedActivity != r) {
1695 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001696 if (r != null) {
1697 mWindowManager.setFocusedApp(r.appToken, true);
1698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 }
1700 }
1701
Dianne Hackborn906497c2010-05-10 15:57:38 -07001702 private final void updateLruProcessInternalLocked(ProcessRecord app,
1703 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001704 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001705 int lrui = mLruProcesses.indexOf(app);
1706 if (lrui >= 0) mLruProcesses.remove(lrui);
1707
1708 int i = mLruProcesses.size()-1;
1709 int skipTop = 0;
1710
Dianne Hackborn906497c2010-05-10 15:57:38 -07001711 app.lruSeq = mLruSeq;
1712
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001713 // compute the new weight for this process.
1714 if (updateActivityTime) {
1715 app.lastActivityTime = SystemClock.uptimeMillis();
1716 }
1717 if (app.activities.size() > 0) {
1718 // If this process has activities, we more strongly want to keep
1719 // it around.
1720 app.lruWeight = app.lastActivityTime;
1721 } else if (app.pubProviders.size() > 0) {
1722 // If this process contains content providers, we want to keep
1723 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001724 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001725 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001726 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001727 } else {
1728 // If this process doesn't have activities, we less strongly
1729 // want to keep it around, and generally want to avoid getting
1730 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001731 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001732 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001733 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001734 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001735
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001736 while (i >= 0) {
1737 ProcessRecord p = mLruProcesses.get(i);
1738 // If this app shouldn't be in front of the first N background
1739 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001740 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001741 skipTop--;
1742 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001743 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001744 mLruProcesses.add(i+1, app);
1745 break;
1746 }
1747 i--;
1748 }
1749 if (i < 0) {
1750 mLruProcesses.add(0, app);
1751 }
1752
Dianne Hackborn906497c2010-05-10 15:57:38 -07001753 // If the app is currently using a content provider or service,
1754 // bump those processes as well.
1755 if (app.connections.size() > 0) {
1756 for (ConnectionRecord cr : app.connections) {
1757 if (cr.binding != null && cr.binding.service != null
1758 && cr.binding.service.app != null
1759 && cr.binding.service.app.lruSeq != mLruSeq) {
1760 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1761 updateActivityTime, i+1);
1762 }
1763 }
1764 }
1765 if (app.conProviders.size() > 0) {
1766 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001767 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1768 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001769 updateActivityTime, i+1);
1770 }
1771 }
1772 }
1773
Joe Onorato8a9b2202010-02-26 18:56:32 -08001774 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 if (oomAdj) {
1776 updateOomAdjLocked();
1777 }
1778 }
1779
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001780 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001781 boolean oomAdj, boolean updateActivityTime) {
1782 mLruSeq++;
1783 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1784 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001785
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001786 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 String processName, int uid) {
1788 if (uid == Process.SYSTEM_UID) {
1789 // The system gets to run in any process. If there are multiple
1790 // processes with the same uid, just pick the first (this
1791 // should never happen).
1792 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1793 processName);
1794 return procs != null ? procs.valueAt(0) : null;
1795 }
1796 ProcessRecord proc = mProcessNames.get(processName, uid);
1797 return proc;
1798 }
1799
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001800 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001801 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001802 try {
1803 if (pm.performDexOpt(packageName)) {
1804 mDidDexOpt = true;
1805 }
1806 } catch (RemoteException e) {
1807 }
1808 }
1809
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001810 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811 int transit = mWindowManager.getPendingAppTransition();
1812 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1813 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1814 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1815 }
1816
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001817 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001818 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001819 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001820 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1821 // We don't have to do anything more if:
1822 // (1) There is an existing application record; and
1823 // (2) The caller doesn't think it is dead, OR there is no thread
1824 // object attached to it so we know it couldn't have crashed; and
1825 // (3) There is a pid assigned to it, so it is either starting or
1826 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001827 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001828 + " app=" + app + " knownToBeDead=" + knownToBeDead
1829 + " thread=" + (app != null ? app.thread : null)
1830 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001831 if (app != null && app.pid > 0) {
1832 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001833 // We already have the app running, or are waiting for it to
1834 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001835 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001836 // If this is a new package in the process, add the package to the list
1837 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001838 return app;
1839 } else {
1840 // An application record is attached to a previous process,
1841 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001842 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001843 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 String hostingNameStr = hostingName != null
1848 ? hostingName.flattenToShortString() : null;
1849
1850 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1851 // If we are in the background, then check to see if this process
1852 // is bad. If so, we will just silently fail.
1853 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001854 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1855 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 return null;
1857 }
1858 } else {
1859 // When the user is explicitly starting a process, then clear its
1860 // crash count so that we won't make it bad until they see at
1861 // least one crash dialog again, and make the process good again
1862 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001863 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1864 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 mProcessCrashTimes.remove(info.processName, info.uid);
1866 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001867 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001868 info.processName);
1869 mBadProcesses.remove(info.processName, info.uid);
1870 if (app != null) {
1871 app.bad = false;
1872 }
1873 }
1874 }
1875
1876 if (app == null) {
1877 app = newProcessRecordLocked(null, info, processName);
1878 mProcessNames.put(processName, info.uid, app);
1879 } else {
1880 // If this is a new package in the process, add the package to the list
1881 app.addPackage(info.packageName);
1882 }
1883
1884 // If the system is not ready yet, then hold off on starting this
1885 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001886 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001887 && !isAllowedWhileBooting(info)
1888 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001889 if (!mProcessesOnHold.contains(app)) {
1890 mProcessesOnHold.add(app);
1891 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001892 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 return app;
1894 }
1895
1896 startProcessLocked(app, hostingType, hostingNameStr);
1897 return (app.pid != 0) ? app : null;
1898 }
1899
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001900 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1901 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1902 }
1903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001904 private final void startProcessLocked(ProcessRecord app,
1905 String hostingType, String hostingNameStr) {
1906 if (app.pid > 0 && app.pid != MY_PID) {
1907 synchronized (mPidsSelfLocked) {
1908 mPidsSelfLocked.remove(app.pid);
1909 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1910 }
1911 app.pid = 0;
1912 }
1913
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001914 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1915 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 mProcessesOnHold.remove(app);
1917
1918 updateCpuStats();
1919
1920 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1921 mProcDeaths[0] = 0;
1922
1923 try {
1924 int uid = app.info.uid;
1925 int[] gids = null;
1926 try {
1927 gids = mContext.getPackageManager().getPackageGids(
1928 app.info.packageName);
1929 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001930 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001931 }
1932 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1933 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1934 && mTopComponent != null
1935 && app.processName.equals(mTopComponent.getPackageName())) {
1936 uid = 0;
1937 }
1938 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1939 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1940 uid = 0;
1941 }
1942 }
1943 int debugFlags = 0;
1944 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1945 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001946 // Also turn on CheckJNI for debuggable apps. It's quite
1947 // awkward to turn on otherwise.
1948 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001950 // Run the app in safe mode if its manifest requests so or the
1951 // system is booted in safe mode.
1952 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1953 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001954 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1957 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1958 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001959 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1960 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 if ("1".equals(SystemProperties.get("debug.assert"))) {
1963 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1964 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001965
1966 // Start the process. It will either succeed and return a result containing
1967 // the PID of the new process, or else throw a RuntimeException.
1968 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001969 app.processName, uid, uid, gids, debugFlags,
1970 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1973 synchronized (bs) {
1974 if (bs.isOnBattery()) {
1975 app.batteryStats.incStartsLocked();
1976 }
1977 }
1978
Jeff Brown3f9dd282011-07-08 20:02:19 -07001979 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 app.processName, hostingType,
1981 hostingNameStr != null ? hostingNameStr : "");
1982
1983 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001984 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 }
1986
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001987 StringBuilder buf = mStringBuilder;
1988 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 buf.append("Start proc ");
1990 buf.append(app.processName);
1991 buf.append(" for ");
1992 buf.append(hostingType);
1993 if (hostingNameStr != null) {
1994 buf.append(" ");
1995 buf.append(hostingNameStr);
1996 }
1997 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001998 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 buf.append(" uid=");
2000 buf.append(uid);
2001 buf.append(" gids={");
2002 if (gids != null) {
2003 for (int gi=0; gi<gids.length; gi++) {
2004 if (gi != 0) buf.append(", ");
2005 buf.append(gids[gi]);
2006
2007 }
2008 }
2009 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002010 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002011 app.pid = startResult.pid;
2012 app.usingWrapper = startResult.usingWrapper;
2013 app.removed = false;
2014 synchronized (mPidsSelfLocked) {
2015 this.mPidsSelfLocked.put(startResult.pid, app);
2016 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2017 msg.obj = app;
2018 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2019 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 }
2021 } catch (RuntimeException e) {
2022 // XXX do better error recovery.
2023 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002024 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002025 }
2026 }
2027
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002028 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 if (resumed) {
2030 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2031 } else {
2032 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2033 }
2034 }
2035
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002036 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002037 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2038 && mTopAction == null) {
2039 // We are running in factory test mode, but unable to find
2040 // the factory test app, so just sit around displaying the
2041 // error message and don't try to start anything.
2042 return false;
2043 }
2044 Intent intent = new Intent(
2045 mTopAction,
2046 mTopData != null ? Uri.parse(mTopData) : null);
2047 intent.setComponent(mTopComponent);
2048 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2049 intent.addCategory(Intent.CATEGORY_HOME);
2050 }
2051 ActivityInfo aInfo =
2052 intent.resolveActivityInfo(mContext.getPackageManager(),
2053 STOCK_PM_FLAGS);
2054 if (aInfo != null) {
2055 intent.setComponent(new ComponentName(
2056 aInfo.applicationInfo.packageName, aInfo.name));
2057 // Don't do this if the home app is currently being
2058 // instrumented.
2059 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2060 aInfo.applicationInfo.uid);
2061 if (app == null || app.instrumentationClass == null) {
2062 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002063 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002064 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002065 }
2066 }
2067
2068
2069 return true;
2070 }
2071
2072 /**
2073 * Starts the "new version setup screen" if appropriate.
2074 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002075 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002076 // Only do this once per boot.
2077 if (mCheckedForSetup) {
2078 return;
2079 }
2080
2081 // We will show this screen if the current one is a different
2082 // version than the last one shown, and we are not running in
2083 // low-level factory test mode.
2084 final ContentResolver resolver = mContext.getContentResolver();
2085 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2086 Settings.Secure.getInt(resolver,
2087 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2088 mCheckedForSetup = true;
2089
2090 // See if we should be showing the platform update setup UI.
2091 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2092 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2093 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2094
2095 // We don't allow third party apps to replace this.
2096 ResolveInfo ri = null;
2097 for (int i=0; ris != null && i<ris.size(); i++) {
2098 if ((ris.get(i).activityInfo.applicationInfo.flags
2099 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2100 ri = ris.get(i);
2101 break;
2102 }
2103 }
2104
2105 if (ri != null) {
2106 String vers = ri.activityInfo.metaData != null
2107 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2108 : null;
2109 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2110 vers = ri.activityInfo.applicationInfo.metaData.getString(
2111 Intent.METADATA_SETUP_VERSION);
2112 }
2113 String lastVers = Settings.Secure.getString(
2114 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2115 if (vers != null && !vers.equals(lastVers)) {
2116 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2117 intent.setComponent(new ComponentName(
2118 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002119 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002120 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002121 }
2122 }
2123 }
2124 }
2125
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002126 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002127 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002128 }
2129
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002130 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002131 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002132 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2133 }
2134 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002135
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002136 public void setFrontActivityScreenCompatMode(int mode) {
2137 synchronized (this) {
2138 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2139 }
2140 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002141
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002142 public int getPackageScreenCompatMode(String packageName) {
2143 synchronized (this) {
2144 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2145 }
2146 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002147
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002148 public void setPackageScreenCompatMode(String packageName, int mode) {
2149 synchronized (this) {
2150 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002151 }
2152 }
2153
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002154 public boolean getPackageAskScreenCompat(String packageName) {
2155 synchronized (this) {
2156 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2157 }
2158 }
2159
2160 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2161 synchronized (this) {
2162 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2163 }
2164 }
2165
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002166 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002167 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002168
2169 final int identHash = System.identityHashCode(r);
2170 updateUsageStats(r, true);
2171
2172 int i = mWatchers.beginBroadcast();
2173 while (i > 0) {
2174 i--;
2175 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2176 if (w != null) {
2177 try {
2178 w.activityResuming(identHash);
2179 } catch (RemoteException e) {
2180 }
2181 }
2182 }
2183 mWatchers.finishBroadcast();
2184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185
Jeff Sharkeya4620792011-05-20 15:29:23 -07002186 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2187 int i = mProcessObservers.beginBroadcast();
2188 while (i > 0) {
2189 i--;
2190 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2191 if (observer != null) {
2192 try {
2193 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2194 } catch (RemoteException e) {
2195 }
2196 }
2197 }
2198 mProcessObservers.finishBroadcast();
2199 }
2200
2201 private void dispatchProcessDied(int pid, int uid) {
2202 int i = mProcessObservers.beginBroadcast();
2203 while (i > 0) {
2204 i--;
2205 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2206 if (observer != null) {
2207 try {
2208 observer.onProcessDied(pid, uid);
2209 } catch (RemoteException e) {
2210 }
2211 }
2212 }
2213 mProcessObservers.finishBroadcast();
2214 }
2215
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002216 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002217 final int N = mPendingActivityLaunches.size();
2218 if (N <= 0) {
2219 return;
2220 }
2221 for (int i=0; i<N; i++) {
2222 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002223 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002224 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2225 doResume && i == (N-1));
2226 }
2227 mPendingActivityLaunches.clear();
2228 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002229
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002230 public final int startActivity(IApplicationThread caller,
2231 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2232 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002233 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2234 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002235 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002236 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002237 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2238 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002239 }
2240
2241 public final WaitResult startActivityAndWait(IApplicationThread caller,
2242 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2243 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002244 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2245 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002246 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002247 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002248 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002249 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2250 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002251 return res;
2252 }
2253
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002254 public final int startActivityWithConfig(IApplicationThread caller,
2255 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2256 int grantedMode, IBinder resultTo,
2257 String resultWho, int requestCode, boolean onlyIfNeeded,
2258 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002259 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002260 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002261 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002262 }
2263
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002264 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002265 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002266 IBinder resultTo, String resultWho, int requestCode,
2267 int flagsMask, int flagsValues) {
2268 // Refuse possible leaked file descriptors
2269 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2270 throw new IllegalArgumentException("File descriptors passed in Intent");
2271 }
2272
2273 IIntentSender sender = intent.getTarget();
2274 if (!(sender instanceof PendingIntentRecord)) {
2275 throw new IllegalArgumentException("Bad PendingIntent object");
2276 }
2277
2278 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002279
2280 synchronized (this) {
2281 // If this is coming from the currently resumed activity, it is
2282 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002283 if (mMainStack.mResumedActivity != null
2284 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002285 Binder.getCallingUid()) {
2286 mAppSwitchesAllowedTime = 0;
2287 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002288 }
2289
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002290 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002291 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2292 }
2293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 public boolean startNextMatchingActivity(IBinder callingActivity,
2295 Intent intent) {
2296 // Refuse possible leaked file descriptors
2297 if (intent != null && intent.hasFileDescriptors() == true) {
2298 throw new IllegalArgumentException("File descriptors passed in Intent");
2299 }
2300
2301 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002302 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2303 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304 return false;
2305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 if (r.app == null || r.app.thread == null) {
2307 // The caller is not running... d'oh!
2308 return false;
2309 }
2310 intent = new Intent(intent);
2311 // The caller is not allowed to change the data.
2312 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2313 // And we are resetting to find the next component...
2314 intent.setComponent(null);
2315
2316 ActivityInfo aInfo = null;
2317 try {
2318 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002319 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002321 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322
2323 // Look for the original activity in the list...
2324 final int N = resolves != null ? resolves.size() : 0;
2325 for (int i=0; i<N; i++) {
2326 ResolveInfo rInfo = resolves.get(i);
2327 if (rInfo.activityInfo.packageName.equals(r.packageName)
2328 && rInfo.activityInfo.name.equals(r.info.name)) {
2329 // We found the current one... the next matching is
2330 // after it.
2331 i++;
2332 if (i<N) {
2333 aInfo = resolves.get(i).activityInfo;
2334 }
2335 break;
2336 }
2337 }
2338 } catch (RemoteException e) {
2339 }
2340
2341 if (aInfo == null) {
2342 // Nobody who is next!
2343 return false;
2344 }
2345
2346 intent.setComponent(new ComponentName(
2347 aInfo.applicationInfo.packageName, aInfo.name));
2348 intent.setFlags(intent.getFlags()&~(
2349 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2350 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2351 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2352 Intent.FLAG_ACTIVITY_NEW_TASK));
2353
2354 // Okay now we need to start the new activity, replacing the
2355 // currently running activity. This is a little tricky because
2356 // we want to start the new one as if the current one is finished,
2357 // but not finish the current one first so that there is no flicker.
2358 // And thus...
2359 final boolean wasFinishing = r.finishing;
2360 r.finishing = true;
2361
2362 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002363 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 final String resultWho = r.resultWho;
2365 final int requestCode = r.requestCode;
2366 r.resultTo = null;
2367 if (resultTo != null) {
2368 resultTo.removeResultsLocked(r, resultWho, requestCode);
2369 }
2370
2371 final long origId = Binder.clearCallingIdentity();
2372 // XXX we are not dealing with propagating grantedUriPermissions...
2373 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002374 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002375 r.resolvedType, null, 0, aInfo,
2376 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002377 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002378 Binder.restoreCallingIdentity(origId);
2379
2380 r.finishing = wasFinishing;
2381 if (res != START_SUCCESS) {
2382 return false;
2383 }
2384 return true;
2385 }
2386 }
2387
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002388 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 Intent intent, String resolvedType, IBinder resultTo,
2390 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002391
2392 // This is so super not safe, that only the system (or okay root)
2393 // can do it.
2394 final int callingUid = Binder.getCallingUid();
2395 if (callingUid != 0 && callingUid != Process.myUid()) {
2396 throw new SecurityException(
2397 "startActivityInPackage only available to the system");
2398 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002400 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002401 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2402 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002403 }
2404
2405 public final int startActivities(IApplicationThread caller,
2406 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2407 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2408 }
2409
2410 public final int startActivitiesInPackage(int uid,
2411 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2412
2413 // This is so super not safe, that only the system (or okay root)
2414 // can do it.
2415 final int callingUid = Binder.getCallingUid();
2416 if (callingUid != 0 && callingUid != Process.myUid()) {
2417 throw new SecurityException(
2418 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 }
2420
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002421 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 }
2423
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002424 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002426 // Quick case: check if the top-most recent task is the same.
2427 if (N > 0 && mRecentTasks.get(0) == task) {
2428 return;
2429 }
2430 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 for (int i=0; i<N; i++) {
2432 TaskRecord tr = mRecentTasks.get(i);
2433 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2434 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2435 mRecentTasks.remove(i);
2436 i--;
2437 N--;
2438 if (task.intent == null) {
2439 // If the new recent task we are adding is not fully
2440 // specified, then replace it with the existing recent task.
2441 task = tr;
2442 }
2443 }
2444 }
2445 if (N >= MAX_RECENT_TASKS) {
2446 mRecentTasks.remove(N-1);
2447 }
2448 mRecentTasks.add(0, task);
2449 }
2450
2451 public void setRequestedOrientation(IBinder token,
2452 int requestedOrientation) {
2453 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002454 ActivityRecord r = mMainStack.isInStackLocked(token);
2455 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 return;
2457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002458 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002459 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002461 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002462 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463 if (config != null) {
2464 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002465 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002466 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002467 }
2468 }
2469 Binder.restoreCallingIdentity(origId);
2470 }
2471 }
2472
2473 public int getRequestedOrientation(IBinder token) {
2474 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002475 ActivityRecord r = mMainStack.isInStackLocked(token);
2476 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2478 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002479 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002480 }
2481 }
2482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 /**
2484 * This is the internal entry point for handling Activity.finish().
2485 *
2486 * @param token The Binder token referencing the Activity we want to finish.
2487 * @param resultCode Result code, if any, from this Activity.
2488 * @param resultData Result data (Intent), if any, from this Activity.
2489 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002490 * @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 -08002491 */
2492 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2493 // Refuse possible leaked file descriptors
2494 if (resultData != null && resultData.hasFileDescriptors() == true) {
2495 throw new IllegalArgumentException("File descriptors passed in Intent");
2496 }
2497
2498 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002499 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002500 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002501 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 if (next != null) {
2503 // ask watcher if this is allowed
2504 boolean resumeOK = true;
2505 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002506 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002508 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 }
2510
2511 if (!resumeOK) {
2512 return false;
2513 }
2514 }
2515 }
2516 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002517 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 resultData, "app-request");
2519 Binder.restoreCallingIdentity(origId);
2520 return res;
2521 }
2522 }
2523
Dianne Hackborn860755f2010-06-03 18:47:52 -07002524 public final void finishHeavyWeightApp() {
2525 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2526 != PackageManager.PERMISSION_GRANTED) {
2527 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2528 + Binder.getCallingPid()
2529 + ", uid=" + Binder.getCallingUid()
2530 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2531 Slog.w(TAG, msg);
2532 throw new SecurityException(msg);
2533 }
2534
2535 synchronized(this) {
2536 if (mHeavyWeightProcess == null) {
2537 return;
2538 }
2539
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002540 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002541 mHeavyWeightProcess.activities);
2542 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002543 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002544 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002545 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002546 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002547 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002548 null, "finish-heavy");
2549 }
2550 }
2551 }
2552
2553 mHeavyWeightProcess = null;
2554 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2555 }
2556 }
2557
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002558 public void crashApplication(int uid, int initialPid, String packageName,
2559 String message) {
2560 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2561 != PackageManager.PERMISSION_GRANTED) {
2562 String msg = "Permission Denial: crashApplication() from pid="
2563 + Binder.getCallingPid()
2564 + ", uid=" + Binder.getCallingUid()
2565 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2566 Slog.w(TAG, msg);
2567 throw new SecurityException(msg);
2568 }
2569
2570 synchronized(this) {
2571 ProcessRecord proc = null;
2572
2573 // Figure out which process to kill. We don't trust that initialPid
2574 // still has any relation to current pids, so must scan through the
2575 // list.
2576 synchronized (mPidsSelfLocked) {
2577 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2578 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2579 if (p.info.uid != uid) {
2580 continue;
2581 }
2582 if (p.pid == initialPid) {
2583 proc = p;
2584 break;
2585 }
2586 for (String str : p.pkgList) {
2587 if (str.equals(packageName)) {
2588 proc = p;
2589 }
2590 }
2591 }
2592 }
2593
2594 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002595 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002596 + " initialPid=" + initialPid
2597 + " packageName=" + packageName);
2598 return;
2599 }
2600
2601 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002602 if (proc.pid == Process.myPid()) {
2603 Log.w(TAG, "crashApplication: trying to crash self!");
2604 return;
2605 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002606 long ident = Binder.clearCallingIdentity();
2607 try {
2608 proc.thread.scheduleCrash(message);
2609 } catch (RemoteException e) {
2610 }
2611 Binder.restoreCallingIdentity(ident);
2612 }
2613 }
2614 }
2615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 public final void finishSubActivity(IBinder token, String resultWho,
2617 int requestCode) {
2618 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002619 ActivityRecord self = mMainStack.isInStackLocked(token);
2620 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 return;
2622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002623
2624 final long origId = Binder.clearCallingIdentity();
2625
2626 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002627 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2628 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002629 if (r.resultTo == self && r.requestCode == requestCode) {
2630 if ((r.resultWho == null && resultWho == null) ||
2631 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002632 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 Activity.RESULT_CANCELED, null, "request-sub");
2634 }
2635 }
2636 }
2637
2638 Binder.restoreCallingIdentity(origId);
2639 }
2640 }
2641
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002642 public boolean willActivityBeVisible(IBinder token) {
2643 synchronized(this) {
2644 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002645 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2646 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002647 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002648 return true;
2649 }
2650 if (r.fullscreen && !r.finishing) {
2651 return false;
2652 }
2653 }
2654 return true;
2655 }
2656 }
2657
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002658 public void overridePendingTransition(IBinder token, String packageName,
2659 int enterAnim, int exitAnim) {
2660 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002661 ActivityRecord self = mMainStack.isInStackLocked(token);
2662 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002663 return;
2664 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002665
2666 final long origId = Binder.clearCallingIdentity();
2667
2668 if (self.state == ActivityState.RESUMED
2669 || self.state == ActivityState.PAUSING) {
2670 mWindowManager.overridePendingAppTransition(packageName,
2671 enterAnim, exitAnim);
2672 }
2673
2674 Binder.restoreCallingIdentity(origId);
2675 }
2676 }
2677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 * Main function for removing an existing process from the activity manager
2680 * as a result of that process going away. Clears out all connections
2681 * to the process.
2682 */
2683 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002684 boolean restarting, boolean allowRestart) {
2685 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002687 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688 }
2689
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002690 if (mProfileProc == app) {
2691 clearProfilerLocked();
2692 }
2693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002695 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2696 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2697 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002699 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2700 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 }
2702
2703 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002704 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705
2706 boolean atTop = true;
2707 boolean hasVisibleActivities = false;
2708
2709 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002710 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002711 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 TAG, "Removing app " + app + " from history with " + i + " entries");
2713 while (i > 0) {
2714 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002715 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002716 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002717 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2718 if (r.app == app) {
2719 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002720 if (ActivityStack.DEBUG_ADD_REMOVE) {
2721 RuntimeException here = new RuntimeException("here");
2722 here.fillInStackTrace();
2723 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2724 + ": haveState=" + r.haveState
2725 + " stateNotNeeded=" + r.stateNotNeeded
2726 + " finishing=" + r.finishing
2727 + " state=" + r.state, here);
2728 }
2729 if (!r.finishing) {
2730 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08002731 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2732 System.identityHashCode(r),
2733 r.task.taskId, r.shortComponentName,
2734 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002735 }
Dianne Hackborn5c607432012-02-28 14:44:19 -08002736 mMainStack.removeActivityFromHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737
2738 } else {
2739 // We have the current state for this activity, so
2740 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002741 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 TAG, "Keeping entry, setting app to null");
2743 if (r.visible) {
2744 hasVisibleActivities = true;
2745 }
2746 r.app = null;
2747 r.nowVisible = false;
2748 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002749 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2750 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 r.icicle = null;
2752 }
2753 }
2754
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002755 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 }
2757 atTop = false;
2758 }
2759
2760 app.activities.clear();
2761
2762 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 + " running instrumentation " + app.instrumentationClass);
2765 Bundle info = new Bundle();
2766 info.putString("shortMsg", "Process crashed.");
2767 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2768 }
2769
2770 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002771 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 // If there was nothing to resume, and we are not already
2773 // restarting this process, but there is a visible activity that
2774 // is hosted by the process... then make sure all visible
2775 // activities are running, taking care of restarting this
2776 // process.
2777 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002778 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002779 }
2780 }
2781 }
2782 }
2783
2784 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2785 IBinder threadBinder = thread.asBinder();
2786
2787 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002788 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2789 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002790 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2791 return i;
2792 }
2793 }
2794 return -1;
2795 }
2796
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002797 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 IApplicationThread thread) {
2799 if (thread == null) {
2800 return null;
2801 }
2802
2803 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002804 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002805 }
2806
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002807 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 IApplicationThread thread) {
2809
2810 mProcDeaths[0]++;
2811
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002812 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2813 synchronized (stats) {
2814 stats.noteProcessDiedLocked(app.info.uid, pid);
2815 }
2816
Magnus Edlund7bb25812010-02-24 15:45:06 +01002817 // Clean up already done if the process has been re-started.
2818 if (app.pid == pid && app.thread != null &&
2819 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002820 if (!app.killedBackground) {
2821 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2822 + ") has died.");
2823 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002824 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002825 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 TAG, "Dying app: " + app + ", pid: " + pid
2827 + ", thread: " + thread.asBinder());
2828 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002829 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830
2831 if (doLowMem) {
2832 // If there are no longer any background processes running,
2833 // and the app that died was not running instrumentation,
2834 // then tell everyone we are now low on memory.
2835 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002836 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2837 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002838 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 haveBg = true;
2840 break;
2841 }
2842 }
2843
2844 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002845 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002846 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002847 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2848 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002849 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002850 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2851 // The low memory report is overriding any current
2852 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002853 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002854 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002855 rec.lastRequestedGc = 0;
2856 } else {
2857 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002859 rec.reportLowMemory = true;
2860 rec.lastLowMemory = now;
2861 mProcessesToGc.remove(rec);
2862 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002863 }
2864 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002865 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002866 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002867 }
2868 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002869 } else if (app.pid != pid) {
2870 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002871 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002872 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002873 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002874 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002875 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 + thread.asBinder());
2877 }
2878 }
2879
Dan Egnor42471dd2010-01-07 17:25:22 -08002880 /**
2881 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002882 * @param clearTraces causes the dump file to be erased prior to the new
2883 * traces being written, if true; when false, the new traces will be
2884 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002885 * @param firstPids of dalvik VM processes to dump stack traces for first
2886 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002887 * @return file containing stack traces, or null if no dump file is configured
2888 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002889 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2890 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002891 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2892 if (tracesPath == null || tracesPath.length() == 0) {
2893 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002894 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002895
2896 File tracesFile = new File(tracesPath);
2897 try {
2898 File tracesDir = tracesFile.getParentFile();
2899 if (!tracesDir.exists()) tracesFile.mkdirs();
2900 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2901
Christopher Tate6ee412d2010-05-28 12:01:56 -07002902 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002903 tracesFile.createNewFile();
2904 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2905 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002906 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002907 return null;
2908 }
2909
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002910 dumpStackTraces(tracesPath, firstPids, processStats, lastPids);
2911 return tracesFile;
2912 }
2913
2914 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
2915 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002916 // Use a FileObserver to detect when traces finish writing.
2917 // The order of traces is considered important to maintain for legibility.
2918 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2919 public synchronized void onEvent(int event, String path) { notify(); }
2920 };
2921
2922 try {
2923 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002924
2925 // First collect all of the stacks of the most important pids.
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002926 if (firstPids != null) {
2927 try {
2928 int num = firstPids.size();
2929 for (int i = 0; i < num; i++) {
2930 synchronized (observer) {
2931 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2932 observer.wait(200); // Wait for write-close, give up after 200msec
2933 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002935 } catch (InterruptedException e) {
2936 Log.wtf(TAG, e);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002937 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 }
2939
2940 // Next measure CPU usage.
2941 if (processStats != null) {
2942 processStats.init();
2943 System.gc();
2944 processStats.update();
2945 try {
2946 synchronized (processStats) {
2947 processStats.wait(500); // measure over 1/2 second.
2948 }
2949 } catch (InterruptedException e) {
2950 }
2951 processStats.update();
2952
2953 // We'll take the stack crawls of just the top apps using CPU.
2954 final int N = processStats.countWorkingStats();
2955 int numProcs = 0;
2956 for (int i=0; i<N && numProcs<5; i++) {
2957 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2958 if (lastPids.indexOfKey(stats.pid) >= 0) {
2959 numProcs++;
2960 try {
2961 synchronized (observer) {
2962 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2963 observer.wait(200); // Wait for write-close, give up after 200msec
2964 }
2965 } catch (InterruptedException e) {
2966 Log.wtf(TAG, e);
2967 }
2968
2969 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002970 }
2971 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002972
Dan Egnor42471dd2010-01-07 17:25:22 -08002973 } finally {
2974 observer.stopWatching();
2975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 }
2977
Jeff Brown4d94a762010-09-23 11:33:28 -07002978 private final class AppNotResponding implements Runnable {
2979 private final ProcessRecord mApp;
2980 private final String mAnnotation;
2981
2982 public AppNotResponding(ProcessRecord app, String annotation) {
2983 mApp = app;
2984 mAnnotation = annotation;
2985 }
2986
2987 @Override
2988 public void run() {
2989 appNotResponding(mApp, null, null, mAnnotation);
2990 }
2991 }
2992
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002993 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
2994 if (IS_USER_BUILD) {
2995 return;
2996 }
2997 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2998 if (tracesPath == null || tracesPath.length() == 0) {
2999 return;
3000 }
3001
3002 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3003 StrictMode.allowThreadDiskWrites();
3004 try {
3005 final File tracesFile = new File(tracesPath);
3006 final File tracesDir = tracesFile.getParentFile();
3007 final File tracesTmp = new File(tracesDir, "__tmp__");
3008 try {
3009 if (!tracesDir.exists()) tracesFile.mkdirs();
3010 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3011
3012 if (tracesFile.exists()) {
3013 tracesTmp.delete();
3014 tracesFile.renameTo(tracesTmp);
3015 }
3016 StringBuilder sb = new StringBuilder();
3017 Time tobj = new Time();
3018 tobj.set(System.currentTimeMillis());
3019 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3020 sb.append(": ");
3021 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3022 sb.append(" since ");
3023 sb.append(msg);
3024 FileOutputStream fos = new FileOutputStream(tracesFile);
3025 fos.write(sb.toString().getBytes());
3026 if (app == null) {
3027 fos.write("\n*** No application process!".getBytes());
3028 }
3029 fos.close();
3030 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3031 } catch (IOException e) {
3032 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3033 return;
3034 }
3035
3036 if (app != null) {
3037 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3038 firstPids.add(app.pid);
3039 dumpStackTraces(tracesPath, firstPids, null, null);
3040 }
3041
3042 File lastTracesFile = null;
3043 File curTracesFile = null;
3044 for (int i=9; i>=0; i--) {
3045 String name = String.format("slow%02d.txt", i);
3046 curTracesFile = new File(tracesDir, name);
3047 if (curTracesFile.exists()) {
3048 if (lastTracesFile != null) {
3049 curTracesFile.renameTo(lastTracesFile);
3050 } else {
3051 curTracesFile.delete();
3052 }
3053 }
3054 lastTracesFile = curTracesFile;
3055 }
3056 tracesFile.renameTo(curTracesFile);
3057 if (tracesTmp.exists()) {
3058 tracesTmp.renameTo(tracesFile);
3059 }
3060 } finally {
3061 StrictMode.setThreadPolicy(oldPolicy);
3062 }
3063 }
3064
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003065 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3066 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003067 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3068 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3069
Dianne Hackborn287952c2010-09-22 22:34:31 -07003070 if (mController != null) {
3071 try {
3072 // 0 == continue, -1 = kill process immediately
3073 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3074 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3075 } catch (RemoteException e) {
3076 mController = null;
3077 }
3078 }
3079
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003080 long anrTime = SystemClock.uptimeMillis();
3081 if (MONITOR_CPU_USAGE) {
3082 updateCpuStatsNow();
3083 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003084
3085 synchronized (this) {
3086 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3087 if (mShuttingDown) {
3088 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3089 return;
3090 } else if (app.notResponding) {
3091 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3092 return;
3093 } else if (app.crashing) {
3094 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3095 return;
3096 }
3097
3098 // In case we come through here for the same app before completing
3099 // this one, mark as anring now so we will bail out.
3100 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003101
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003102 // Log the ANR to the event log.
3103 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3104 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003105
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003106 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003107 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003108
3109 int parentPid = app.pid;
3110 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003111 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003112
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003113 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003114
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003115 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3116 ProcessRecord r = mLruProcesses.get(i);
3117 if (r != null && r.thread != null) {
3118 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003119 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3120 if (r.persistent) {
3121 firstPids.add(pid);
3122 } else {
3123 lastPids.put(pid, Boolean.TRUE);
3124 }
3125 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 }
3128 }
3129
Dan Egnor42471dd2010-01-07 17:25:22 -08003130 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003131 StringBuilder info = mStringBuilder;
3132 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003133 info.append("ANR in ").append(app.processName);
3134 if (activity != null && activity.shortComponentName != null) {
3135 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003136 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003137 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003139 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003140 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003141 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003142 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003144
Dianne Hackborn287952c2010-09-22 22:34:31 -07003145 final ProcessStats processStats = new ProcessStats(true);
3146
3147 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3148
Dan Egnor42471dd2010-01-07 17:25:22 -08003149 String cpuInfo = null;
3150 if (MONITOR_CPU_USAGE) {
3151 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003152 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003153 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003154 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003155 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003156 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 }
3158
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003159 info.append(processStats.printCurrentState(anrTime));
3160
Joe Onorato8a9b2202010-02-26 18:56:32 -08003161 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003162 if (tracesFile == null) {
3163 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3164 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3165 }
3166
Jeff Sharkeya353d262011-10-28 11:12:06 -07003167 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3168 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003169
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003170 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003171 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003172 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3173 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003174 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003175 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3176 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 }
3178 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003179 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003180 }
3181 }
3182
Dan Egnor42471dd2010-01-07 17:25:22 -08003183 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3184 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3185 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003186
3187 synchronized (this) {
3188 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003189 Slog.w(TAG, "Killing " + app + ": background ANR");
3190 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3191 app.processName, app.setAdj, "background ANR");
3192 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003193 return;
3194 }
3195
3196 // Set the app's notResponding state, and look up the errorReportReceiver
3197 makeAppNotRespondingLocked(app,
3198 activity != null ? activity.shortComponentName : null,
3199 annotation != null ? "ANR " + annotation : "ANR",
3200 info.toString());
3201
3202 // Bring up the infamous App Not Responding dialog
3203 Message msg = Message.obtain();
3204 HashMap map = new HashMap();
3205 msg.what = SHOW_NOT_RESPONDING_MSG;
3206 msg.obj = map;
3207 map.put("app", app);
3208 if (activity != null) {
3209 map.put("activity", activity);
3210 }
3211
3212 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 }
3215
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003216 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3217 if (!mLaunchWarningShown) {
3218 mLaunchWarningShown = true;
3219 mHandler.post(new Runnable() {
3220 @Override
3221 public void run() {
3222 synchronized (ActivityManagerService.this) {
3223 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3224 d.show();
3225 mHandler.postDelayed(new Runnable() {
3226 @Override
3227 public void run() {
3228 synchronized (ActivityManagerService.this) {
3229 d.dismiss();
3230 mLaunchWarningShown = false;
3231 }
3232 }
3233 }, 4000);
3234 }
3235 }
3236 });
3237 }
3238 }
3239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003240 public boolean clearApplicationUserData(final String packageName,
3241 final IPackageDataObserver observer) {
3242 int uid = Binder.getCallingUid();
3243 int pid = Binder.getCallingPid();
3244 long callingId = Binder.clearCallingIdentity();
3245 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003246 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003247 int pkgUid = -1;
3248 synchronized(this) {
3249 try {
3250 pkgUid = pm.getPackageUid(packageName);
3251 } catch (RemoteException e) {
3252 }
3253 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003254 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003255 return false;
3256 }
3257 if (uid == pkgUid || checkComponentPermission(
3258 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003259 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003261 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003262 } else {
3263 throw new SecurityException(pid+" does not have permission:"+
3264 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3265 "for process:"+packageName);
3266 }
3267 }
3268
3269 try {
3270 //clear application user data
3271 pm.clearApplicationUserData(packageName, observer);
3272 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3273 Uri.fromParts("package", packageName, null));
3274 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003275 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3276 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003277 } catch (RemoteException e) {
3278 }
3279 } finally {
3280 Binder.restoreCallingIdentity(callingId);
3281 }
3282 return true;
3283 }
3284
Dianne Hackborn03abb812010-01-04 18:43:19 -08003285 public void killBackgroundProcesses(final String packageName) {
3286 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3287 != PackageManager.PERMISSION_GRANTED &&
3288 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3289 != PackageManager.PERMISSION_GRANTED) {
3290 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003291 + Binder.getCallingPid()
3292 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003293 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003294 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003295 throw new SecurityException(msg);
3296 }
3297
3298 long callingId = Binder.clearCallingIdentity();
3299 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003300 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003301 int pkgUid = -1;
3302 synchronized(this) {
3303 try {
3304 pkgUid = pm.getPackageUid(packageName);
3305 } catch (RemoteException e) {
3306 }
3307 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003308 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 return;
3310 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003311 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003312 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3313 }
3314 } finally {
3315 Binder.restoreCallingIdentity(callingId);
3316 }
3317 }
3318
3319 public void killAllBackgroundProcesses() {
3320 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3321 != PackageManager.PERMISSION_GRANTED) {
3322 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3323 + Binder.getCallingPid()
3324 + ", uid=" + Binder.getCallingUid()
3325 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3326 Slog.w(TAG, msg);
3327 throw new SecurityException(msg);
3328 }
3329
3330 long callingId = Binder.clearCallingIdentity();
3331 try {
3332 synchronized(this) {
3333 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3334 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3335 final int NA = apps.size();
3336 for (int ia=0; ia<NA; ia++) {
3337 ProcessRecord app = apps.valueAt(ia);
3338 if (app.persistent) {
3339 // we don't kill persistent processes
3340 continue;
3341 }
3342 if (app.removed) {
3343 procs.add(app);
3344 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3345 app.removed = true;
3346 procs.add(app);
3347 }
3348 }
3349 }
3350
3351 int N = procs.size();
3352 for (int i=0; i<N; i++) {
3353 removeProcessLocked(procs.get(i), false, true, "kill all background");
3354 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003355 }
3356 } finally {
3357 Binder.restoreCallingIdentity(callingId);
3358 }
3359 }
3360
3361 public void forceStopPackage(final String packageName) {
3362 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3363 != PackageManager.PERMISSION_GRANTED) {
3364 String msg = "Permission Denial: forceStopPackage() from pid="
3365 + Binder.getCallingPid()
3366 + ", uid=" + Binder.getCallingUid()
3367 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003368 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003369 throw new SecurityException(msg);
3370 }
3371
3372 long callingId = Binder.clearCallingIdentity();
3373 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003374 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003375 int pkgUid = -1;
3376 synchronized(this) {
3377 try {
3378 pkgUid = pm.getPackageUid(packageName);
3379 } catch (RemoteException e) {
3380 }
3381 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003382 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003383 return;
3384 }
3385 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003386 try {
3387 pm.setPackageStoppedState(packageName, true);
3388 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003389 } catch (IllegalArgumentException e) {
3390 Slog.w(TAG, "Failed trying to unstop package "
3391 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 }
3394 } finally {
3395 Binder.restoreCallingIdentity(callingId);
3396 }
3397 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003398
3399 /*
3400 * The pkg name and uid have to be specified.
3401 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3402 */
3403 public void killApplicationWithUid(String pkg, int uid) {
3404 if (pkg == null) {
3405 return;
3406 }
3407 // Make sure the uid is valid.
3408 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003409 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003410 return;
3411 }
3412 int callerUid = Binder.getCallingUid();
3413 // Only the system server can kill an application
3414 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003415 // Post an aysnc message to kill the application
3416 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3417 msg.arg1 = uid;
3418 msg.arg2 = 0;
3419 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003420 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003421 } else {
3422 throw new SecurityException(callerUid + " cannot kill pkg: " +
3423 pkg);
3424 }
3425 }
3426
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003427 public void closeSystemDialogs(String reason) {
3428 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003430 if (reason != null) {
3431 intent.putExtra("reason", reason);
3432 }
3433
3434 final int uid = Binder.getCallingUid();
3435 final long origId = Binder.clearCallingIdentity();
3436 synchronized (this) {
3437 int i = mWatchers.beginBroadcast();
3438 while (i > 0) {
3439 i--;
3440 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3441 if (w != null) {
3442 try {
3443 w.closingSystemDialogs(reason);
3444 } catch (RemoteException e) {
3445 }
3446 }
3447 }
3448 mWatchers.finishBroadcast();
3449
Dianne Hackbornffa42482009-09-23 22:20:11 -07003450 mWindowManager.closeSystemDialogs(reason);
3451
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003452 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3453 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003454 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003455 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003456 Activity.RESULT_CANCELED, null, "close-sys");
3457 }
3458 }
3459
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003460 broadcastIntentLocked(null, null, intent, null,
3461 null, 0, null, null, null, false, false, -1, uid);
3462 }
3463 Binder.restoreCallingIdentity(origId);
3464 }
3465
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003466 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003467 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003468 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3469 for (int i=pids.length-1; i>=0; i--) {
3470 infos[i] = new Debug.MemoryInfo();
3471 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003472 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003473 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003474 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003475
Dianne Hackbornb437e092011-08-05 17:50:29 -07003476 public long[] getProcessPss(int[] pids) throws RemoteException {
3477 long[] pss = new long[pids.length];
3478 for (int i=pids.length-1; i>=0; i--) {
3479 pss[i] = Debug.getPss(pids[i]);
3480 }
3481 return pss;
3482 }
3483
Christopher Tate5e1ab332009-09-01 20:32:49 -07003484 public void killApplicationProcess(String processName, int uid) {
3485 if (processName == null) {
3486 return;
3487 }
3488
3489 int callerUid = Binder.getCallingUid();
3490 // Only the system server can kill an application
3491 if (callerUid == Process.SYSTEM_UID) {
3492 synchronized (this) {
3493 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003494 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003495 try {
3496 app.thread.scheduleSuicide();
3497 } catch (RemoteException e) {
3498 // If the other end already died, then our work here is done.
3499 }
3500 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003501 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003502 + processName + " / " + uid);
3503 }
3504 }
3505 } else {
3506 throw new SecurityException(callerUid + " cannot kill app process: " +
3507 processName);
3508 }
3509 }
3510
Dianne Hackborn03abb812010-01-04 18:43:19 -08003511 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003512 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3514 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003515 if (!mProcessesReady) {
3516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 intent.putExtra(Intent.EXTRA_UID, uid);
3519 broadcastIntentLocked(null, null, intent,
3520 null, null, 0, null, null, null,
3521 false, false, MY_PID, Process.SYSTEM_UID);
3522 }
3523
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003524 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003525 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003526 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003527 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528
Dianne Hackborn03abb812010-01-04 18:43:19 -08003529 // Remove all processes this package may have touched: all with the
3530 // same UID (except for the system or root user), and all whose name
3531 // matches the package name.
3532 final String procNamePrefix = packageName + ":";
3533 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3534 final int NA = apps.size();
3535 for (int ia=0; ia<NA; ia++) {
3536 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003537 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003538 // we don't kill persistent processes
3539 continue;
3540 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003541 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003542 if (doit) {
3543 procs.add(app);
3544 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003545 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3546 || app.processName.equals(packageName)
3547 || app.processName.startsWith(procNamePrefix)) {
3548 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003549 if (!doit) {
3550 return true;
3551 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003552 app.removed = true;
3553 procs.add(app);
3554 }
3555 }
3556 }
3557 }
3558
3559 int N = procs.size();
3560 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003561 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003562 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003563 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003564 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003565
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003566 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003567 boolean callerWillRestart, boolean purgeCache, boolean doit,
3568 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003569 int i;
3570 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 if (uid < 0) {
3573 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003574 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 } catch (RemoteException e) {
3576 }
3577 }
3578
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003579 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003580 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003581
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003582 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3583 while (badApps.hasNext()) {
3584 SparseArray<Long> ba = badApps.next();
3585 if (ba.get(uid) != null) {
3586 badApps.remove();
3587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588 }
3589 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003590
3591 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003592 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003594 TaskRecord lastTask = null;
3595 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003596 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003597 final boolean samePackage = r.packageName.equals(name);
3598 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003599 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003600 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003601 if (r.finishing) {
3602 // If this activity is just finishing, then it is not
3603 // interesting as far as something to stop.
3604 continue;
3605 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003606 return true;
3607 }
3608 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003609 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003610 if (samePackage) {
3611 if (r.app != null) {
3612 r.app.removed = true;
3613 }
3614 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003616 lastTask = r.task;
3617 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3618 null, "force-stop")) {
3619 i--;
3620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 }
3622 }
3623
3624 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3625 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003626 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003627 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003628 if (!doit) {
3629 return true;
3630 }
3631 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003632 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003633 if (service.app != null) {
3634 service.app.removed = true;
3635 }
3636 service.app = null;
3637 services.add(service);
3638 }
3639 }
3640
3641 N = services.size();
3642 for (i=0; i<N; i++) {
3643 bringDownServiceLocked(services.get(i), true);
3644 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003645
3646 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3647 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3648 if (provider.info.packageName.equals(name)
3649 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3650 if (!doit) {
3651 return true;
3652 }
3653 didSomething = true;
3654 providers.add(provider);
3655 }
3656 }
3657
3658 N = providers.size();
3659 for (i=0; i<N; i++) {
3660 removeDyingProviderLocked(null, providers.get(i));
3661 }
3662
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003663 if (doit) {
3664 if (purgeCache) {
3665 AttributeCache ac = AttributeCache.instance();
3666 if (ac != null) {
3667 ac.removePackage(name);
3668 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003669 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003670 if (mBooted) {
3671 mMainStack.resumeTopActivityLocked(null);
3672 mMainStack.scheduleIdleLocked();
3673 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003674 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003675
3676 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 }
3678
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003679 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003680 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 final String name = app.processName;
3682 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003683 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003684 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 + "/" + uid + ")");
3686
3687 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003688 if (mHeavyWeightProcess == app) {
3689 mHeavyWeightProcess = null;
3690 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3691 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 boolean needRestart = false;
3693 if (app.pid > 0 && app.pid != MY_PID) {
3694 int pid = app.pid;
3695 synchronized (mPidsSelfLocked) {
3696 mPidsSelfLocked.remove(pid);
3697 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3698 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003699 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003700 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003701 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003702 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703
3704 if (app.persistent) {
3705 if (!callerWillRestart) {
3706 addAppLocked(app.info);
3707 } else {
3708 needRestart = true;
3709 }
3710 }
3711 } else {
3712 mRemovedProcesses.add(app);
3713 }
3714
3715 return needRestart;
3716 }
3717
3718 private final void processStartTimedOutLocked(ProcessRecord app) {
3719 final int pid = app.pid;
3720 boolean gone = false;
3721 synchronized (mPidsSelfLocked) {
3722 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3723 if (knownApp != null && knownApp.thread == null) {
3724 mPidsSelfLocked.remove(pid);
3725 gone = true;
3726 }
3727 }
3728
3729 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003730 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003731 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003732 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003734 if (mHeavyWeightProcess == app) {
3735 mHeavyWeightProcess = null;
3736 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3737 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003738 // Take care of any launching providers waiting for this process.
3739 checkAppInLaunchingProvidersLocked(app, true);
3740 // Take care of any services that are waiting for the process.
3741 for (int i=0; i<mPendingServices.size(); i++) {
3742 ServiceRecord sr = mPendingServices.get(i);
3743 if (app.info.uid == sr.appInfo.uid
3744 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003745 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003746 mPendingServices.remove(i);
3747 i--;
3748 bringDownServiceLocked(sr, true);
3749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003751 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3752 app.processName, app.setAdj, "start timeout");
3753 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003754 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003755 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003756 try {
3757 IBackupManager bm = IBackupManager.Stub.asInterface(
3758 ServiceManager.getService(Context.BACKUP_SERVICE));
3759 bm.agentDisconnected(app.info.packageName);
3760 } catch (RemoteException e) {
3761 // Can't happen; the backup manager is local
3762 }
3763 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003764 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003765 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003766 mPendingBroadcast.state = BroadcastRecord.IDLE;
3767 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003768 mPendingBroadcast = null;
3769 scheduleBroadcastsLocked();
3770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003772 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 }
3774 }
3775
3776 private final boolean attachApplicationLocked(IApplicationThread thread,
3777 int pid) {
3778
3779 // Find the application record that is being attached... either via
3780 // the pid if we are running in multiple processes, or just pull the
3781 // next app record if we are emulating process with anonymous threads.
3782 ProcessRecord app;
3783 if (pid != MY_PID && pid >= 0) {
3784 synchronized (mPidsSelfLocked) {
3785 app = mPidsSelfLocked.get(pid);
3786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003787 } else {
3788 app = null;
3789 }
3790
3791 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003792 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003793 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003794 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003796 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 } else {
3798 try {
3799 thread.scheduleExit();
3800 } catch (Exception e) {
3801 // Ignore exceptions.
3802 }
3803 }
3804 return false;
3805 }
3806
3807 // If this application record is still attached to a previous
3808 // process, clean it up now.
3809 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003810 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003811 }
3812
3813 // Tell the process all about itself.
3814
Joe Onorato8a9b2202010-02-26 18:56:32 -08003815 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003816 TAG, "Binding process pid " + pid + " to record " + app);
3817
3818 String processName = app.processName;
3819 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003820 AppDeathRecipient adr = new AppDeathRecipient(
3821 app, pid, thread);
3822 thread.asBinder().linkToDeath(adr, 0);
3823 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003824 } catch (RemoteException e) {
3825 app.resetPackageList();
3826 startProcessLocked(app, "link fail", processName);
3827 return false;
3828 }
3829
Doug Zongker2bec3d42009-12-04 12:52:44 -08003830 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831
3832 app.thread = thread;
3833 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003834 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3835 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 app.forcingToForeground = null;
3837 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003838 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 app.debugging = false;
3840
3841 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3842
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003843 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003844 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003846 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003847 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003848 }
3849
Joe Onorato8a9b2202010-02-26 18:56:32 -08003850 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 TAG, "New app record " + app
3852 + " thread=" + thread.asBinder() + " pid=" + pid);
3853 try {
3854 int testMode = IApplicationThread.DEBUG_OFF;
3855 if (mDebugApp != null && mDebugApp.equals(processName)) {
3856 testMode = mWaitForDebugger
3857 ? IApplicationThread.DEBUG_WAIT
3858 : IApplicationThread.DEBUG_ON;
3859 app.debugging = true;
3860 if (mDebugTransient) {
3861 mDebugApp = mOrigDebugApp;
3862 mWaitForDebugger = mOrigWaitForDebugger;
3863 }
3864 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003865 String profileFile = app.instrumentationProfileFile;
3866 ParcelFileDescriptor profileFd = null;
3867 boolean profileAutoStop = false;
3868 if (mProfileApp != null && mProfileApp.equals(processName)) {
3869 mProfileProc = app;
3870 profileFile = mProfileFile;
3871 profileFd = mProfileFd;
3872 profileAutoStop = mAutoStopProfiler;
3873 }
3874
Christopher Tate181fafa2009-05-14 11:12:14 -07003875 // If the app is being launched for restore or full backup, set it up specially
3876 boolean isRestrictedBackupMode = false;
3877 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3878 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003879 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003880 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3881 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003882
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003883 ensurePackageDexOpt(app.instrumentationInfo != null
3884 ? app.instrumentationInfo.packageName
3885 : app.info.packageName);
3886 if (app.instrumentationClass != null) {
3887 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003888 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003889 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003890 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003891 ApplicationInfo appInfo = app.instrumentationInfo != null
3892 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003893 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003894 if (profileFd != null) {
3895 profileFd = profileFd.dup();
3896 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003897 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003898 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003900 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003901 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003902 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003903 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003904 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 } catch (Exception e) {
3906 // todo: Yikes! What should we do? For now we will try to
3907 // start another process, but that could easily get us in
3908 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003909 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910
3911 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003912 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 startProcessLocked(app, "bind fail", processName);
3914 return false;
3915 }
3916
3917 // Remove this record from the list of starting applications.
3918 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003919 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3920 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 mProcessesOnHold.remove(app);
3922
3923 boolean badApp = false;
3924 boolean didSomething = false;
3925
3926 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003927 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003928 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3930 && processName.equals(hr.processName)) {
3931 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003932 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 didSomething = true;
3934 }
3935 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003936 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 + hr.intent.getComponent().flattenToShortString(), e);
3938 badApp = true;
3939 }
3940 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003941 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 }
3943 }
3944
3945 // Find any services that should be running in this process...
3946 if (!badApp && mPendingServices.size() > 0) {
3947 ServiceRecord sr = null;
3948 try {
3949 for (int i=0; i<mPendingServices.size(); i++) {
3950 sr = mPendingServices.get(i);
3951 if (app.info.uid != sr.appInfo.uid
3952 || !processName.equals(sr.processName)) {
3953 continue;
3954 }
3955
3956 mPendingServices.remove(i);
3957 i--;
3958 realStartServiceLocked(sr, app);
3959 didSomething = true;
3960 }
3961 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003962 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 + sr.shortName, e);
3964 badApp = true;
3965 }
3966 }
3967
3968 // Check if the next broadcast receiver is in this process...
3969 BroadcastRecord br = mPendingBroadcast;
3970 if (!badApp && br != null && br.curApp == app) {
3971 try {
3972 mPendingBroadcast = null;
3973 processCurBroadcastLocked(br, app);
3974 didSomething = true;
3975 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003976 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 + br.curComponent.flattenToShortString(), e);
3978 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003979 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3981 br.resultExtras, br.resultAbort, true);
3982 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003983 // We need to reset the state if we fails to start the receiver.
3984 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 }
3986 }
3987
Christopher Tate181fafa2009-05-14 11:12:14 -07003988 // Check whether the next backup agent is in this process...
3989 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003990 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003991 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003992 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003993 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3994 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3995 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003996 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003997 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003998 e.printStackTrace();
3999 }
4000 }
4001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 if (badApp) {
4003 // todo: Also need to kill application to deal with all
4004 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004005 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004006 return false;
4007 }
4008
4009 if (!didSomething) {
4010 updateOomAdjLocked();
4011 }
4012
4013 return true;
4014 }
4015
4016 public final void attachApplication(IApplicationThread thread) {
4017 synchronized (this) {
4018 int callingPid = Binder.getCallingPid();
4019 final long origId = Binder.clearCallingIdentity();
4020 attachApplicationLocked(thread, callingPid);
4021 Binder.restoreCallingIdentity(origId);
4022 }
4023 }
4024
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004025 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004026 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004027 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4028 if (stopProfiling) {
4029 synchronized (this) {
4030 if (mProfileProc == r.app) {
4031 if (mProfileFd != null) {
4032 try {
4033 mProfileFd.close();
4034 } catch (IOException e) {
4035 }
4036 clearProfilerLocked();
4037 }
4038 }
4039 }
4040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 Binder.restoreCallingIdentity(origId);
4042 }
4043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004044 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004045 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004046 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004047 mWindowManager.enableScreenAfterBoot();
4048 }
4049
Dianne Hackborn661cd522011-08-22 00:26:20 -07004050 public void showBootMessage(final CharSequence msg, final boolean always) {
4051 mWindowManager.showBootMessage(msg, always);
4052 }
4053
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004054 public void dismissKeyguardOnNextActivity() {
4055 synchronized (this) {
4056 mMainStack.dismissKeyguardOnNextActivityLocked();
4057 }
4058 }
4059
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004060 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004061 IntentFilter pkgFilter = new IntentFilter();
4062 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4063 pkgFilter.addDataScheme("package");
4064 mContext.registerReceiver(new BroadcastReceiver() {
4065 @Override
4066 public void onReceive(Context context, Intent intent) {
4067 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4068 if (pkgs != null) {
4069 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004070 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004071 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004072 setResultCode(Activity.RESULT_OK);
4073 return;
4074 }
4075 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004076 }
4077 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004078 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004079 }, pkgFilter);
4080
4081 synchronized (this) {
4082 // Ensure that any processes we had put on hold are now started
4083 // up.
4084 final int NP = mProcessesOnHold.size();
4085 if (NP > 0) {
4086 ArrayList<ProcessRecord> procs =
4087 new ArrayList<ProcessRecord>(mProcessesOnHold);
4088 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004089 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4090 + procs.get(ip));
4091 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004092 }
4093 }
4094
4095 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004096 // Start looking for apps that are abusing wake locks.
4097 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004098 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004099 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004100 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004101 broadcastIntentLocked(null, null,
4102 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4103 null, null, 0, null, null,
4104 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4105 false, false, MY_PID, Process.SYSTEM_UID);
4106 }
4107 }
4108 }
4109
4110 final void ensureBootCompleted() {
4111 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004112 boolean enableScreen;
4113 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004114 booting = mBooting;
4115 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004116 enableScreen = !mBooted;
4117 mBooted = true;
4118 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004119
4120 if (booting) {
4121 finishBooting();
4122 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004123
4124 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004125 enableScreenAfterBoot();
4126 }
4127 }
4128
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004129 public final void activityPaused(IBinder token) {
4130 final long origId = Binder.clearCallingIdentity();
4131 mMainStack.activityPaused(token, false);
4132 Binder.restoreCallingIdentity(origId);
4133 }
4134
4135 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4136 CharSequence description) {
4137 if (localLOGV) Slog.v(
4138 TAG, "Activity stopped: token=" + token);
4139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 // Refuse possible leaked file descriptors
4141 if (icicle != null && icicle.hasFileDescriptors()) {
4142 throw new IllegalArgumentException("File descriptors passed in Bundle");
4143 }
4144
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004145 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004146
4147 final long origId = Binder.clearCallingIdentity();
4148
4149 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004150 r = mMainStack.isInStackLocked(token);
4151 if (r != null) {
4152 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004153 }
4154 }
4155
4156 if (r != null) {
4157 sendPendingThumbnail(r, null, null, null, false);
4158 }
4159
4160 trimApplications();
4161
4162 Binder.restoreCallingIdentity(origId);
4163 }
4164
4165 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004166 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004167 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 }
4169
4170 public String getCallingPackage(IBinder token) {
4171 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004172 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004173 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 }
4175 }
4176
4177 public ComponentName getCallingActivity(IBinder token) {
4178 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004179 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 return r != null ? r.intent.getComponent() : null;
4181 }
4182 }
4183
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004184 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004185 ActivityRecord r = mMainStack.isInStackLocked(token);
4186 if (r == null) {
4187 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004188 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004189 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 }
4191
4192 public ComponentName getActivityClassForToken(IBinder token) {
4193 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004194 ActivityRecord r = mMainStack.isInStackLocked(token);
4195 if (r == null) {
4196 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004198 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 }
4200 }
4201
4202 public String getPackageForToken(IBinder token) {
4203 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004204 ActivityRecord r = mMainStack.isInStackLocked(token);
4205 if (r == null) {
4206 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004208 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004209 }
4210 }
4211
4212 public IIntentSender getIntentSender(int type,
4213 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004214 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004215 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004216 if (intents != null) {
4217 if (intents.length < 1) {
4218 throw new IllegalArgumentException("Intents array length must be >= 1");
4219 }
4220 for (int i=0; i<intents.length; i++) {
4221 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004222 if (intent != null) {
4223 if (intent.hasFileDescriptors()) {
4224 throw new IllegalArgumentException("File descriptors passed in Intent");
4225 }
4226 if (type == INTENT_SENDER_BROADCAST &&
4227 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4228 throw new IllegalArgumentException(
4229 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4230 }
4231 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004232 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004233 }
4234 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004235 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004236 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004237 }
4238 }
4239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 synchronized(this) {
4241 int callingUid = Binder.getCallingUid();
4242 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004243 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004244 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004245 .getPackageUid(packageName);
4246 if (uid != Binder.getCallingUid()) {
4247 String msg = "Permission Denial: getIntentSender() from pid="
4248 + Binder.getCallingPid()
4249 + ", uid=" + Binder.getCallingUid()
4250 + ", (need uid=" + uid + ")"
4251 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004252 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 throw new SecurityException(msg);
4254 }
4255 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004256
4257 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004258 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 } catch (RemoteException e) {
4261 throw new SecurityException(e);
4262 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004263 }
4264 }
4265
4266 IIntentSender getIntentSenderLocked(int type,
4267 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004268 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004269 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004270 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004271 activity = mMainStack.isInStackLocked(token);
4272 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004273 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004275 if (activity.finishing) {
4276 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004278 }
4279
4280 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4281 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4282 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4283 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4284 |PendingIntent.FLAG_UPDATE_CURRENT);
4285
4286 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4287 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004288 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004289 WeakReference<PendingIntentRecord> ref;
4290 ref = mIntentSenderRecords.get(key);
4291 PendingIntentRecord rec = ref != null ? ref.get() : null;
4292 if (rec != null) {
4293 if (!cancelCurrent) {
4294 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004295 if (rec.key.requestIntent != null) {
4296 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4297 }
4298 if (intents != null) {
4299 intents[intents.length-1] = rec.key.requestIntent;
4300 rec.key.allIntents = intents;
4301 rec.key.allResolvedTypes = resolvedTypes;
4302 } else {
4303 rec.key.allIntents = null;
4304 rec.key.allResolvedTypes = null;
4305 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 return rec;
4308 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004309 rec.canceled = true;
4310 mIntentSenderRecords.remove(key);
4311 }
4312 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 return rec;
4314 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004315 rec = new PendingIntentRecord(this, key, callingUid);
4316 mIntentSenderRecords.put(key, rec.ref);
4317 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4318 if (activity.pendingResults == null) {
4319 activity.pendingResults
4320 = new HashSet<WeakReference<PendingIntentRecord>>();
4321 }
4322 activity.pendingResults.add(rec.ref);
4323 }
4324 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 }
4326
4327 public void cancelIntentSender(IIntentSender sender) {
4328 if (!(sender instanceof PendingIntentRecord)) {
4329 return;
4330 }
4331 synchronized(this) {
4332 PendingIntentRecord rec = (PendingIntentRecord)sender;
4333 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004334 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 .getPackageUid(rec.key.packageName);
4336 if (uid != Binder.getCallingUid()) {
4337 String msg = "Permission Denial: cancelIntentSender() from pid="
4338 + Binder.getCallingPid()
4339 + ", uid=" + Binder.getCallingUid()
4340 + " is not allowed to cancel packges "
4341 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004342 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 throw new SecurityException(msg);
4344 }
4345 } catch (RemoteException e) {
4346 throw new SecurityException(e);
4347 }
4348 cancelIntentSenderLocked(rec, true);
4349 }
4350 }
4351
4352 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4353 rec.canceled = true;
4354 mIntentSenderRecords.remove(rec.key);
4355 if (cleanActivity && rec.key.activity != null) {
4356 rec.key.activity.pendingResults.remove(rec.ref);
4357 }
4358 }
4359
4360 public String getPackageForIntentSender(IIntentSender pendingResult) {
4361 if (!(pendingResult instanceof PendingIntentRecord)) {
4362 return null;
4363 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004364 try {
4365 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4366 return res.key.packageName;
4367 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004368 }
4369 return null;
4370 }
4371
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004372 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4373 if (!(pendingResult instanceof PendingIntentRecord)) {
4374 return false;
4375 }
4376 try {
4377 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4378 if (res.key.allIntents == null) {
4379 return false;
4380 }
4381 for (int i=0; i<res.key.allIntents.length; i++) {
4382 Intent intent = res.key.allIntents[i];
4383 if (intent.getPackage() != null && intent.getComponent() != null) {
4384 return false;
4385 }
4386 }
4387 return true;
4388 } catch (ClassCastException e) {
4389 }
4390 return false;
4391 }
4392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 public void setProcessLimit(int max) {
4394 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4395 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004396 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004397 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004398 mProcessLimitOverride = max;
4399 }
4400 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 }
4402
4403 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004404 synchronized (this) {
4405 return mProcessLimitOverride;
4406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 }
4408
4409 void foregroundTokenDied(ForegroundToken token) {
4410 synchronized (ActivityManagerService.this) {
4411 synchronized (mPidsSelfLocked) {
4412 ForegroundToken cur
4413 = mForegroundProcesses.get(token.pid);
4414 if (cur != token) {
4415 return;
4416 }
4417 mForegroundProcesses.remove(token.pid);
4418 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4419 if (pr == null) {
4420 return;
4421 }
4422 pr.forcingToForeground = null;
4423 pr.foregroundServices = false;
4424 }
4425 updateOomAdjLocked();
4426 }
4427 }
4428
4429 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4430 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4431 "setProcessForeground()");
4432 synchronized(this) {
4433 boolean changed = false;
4434
4435 synchronized (mPidsSelfLocked) {
4436 ProcessRecord pr = mPidsSelfLocked.get(pid);
4437 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004438 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 return;
4440 }
4441 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4442 if (oldToken != null) {
4443 oldToken.token.unlinkToDeath(oldToken, 0);
4444 mForegroundProcesses.remove(pid);
4445 pr.forcingToForeground = null;
4446 changed = true;
4447 }
4448 if (isForeground && token != null) {
4449 ForegroundToken newToken = new ForegroundToken() {
4450 public void binderDied() {
4451 foregroundTokenDied(this);
4452 }
4453 };
4454 newToken.pid = pid;
4455 newToken.token = token;
4456 try {
4457 token.linkToDeath(newToken, 0);
4458 mForegroundProcesses.put(pid, newToken);
4459 pr.forcingToForeground = token;
4460 changed = true;
4461 } catch (RemoteException e) {
4462 // If the process died while doing this, we will later
4463 // do the cleanup with the process death link.
4464 }
4465 }
4466 }
4467
4468 if (changed) {
4469 updateOomAdjLocked();
4470 }
4471 }
4472 }
4473
4474 // =========================================================
4475 // PERMISSIONS
4476 // =========================================================
4477
4478 static class PermissionController extends IPermissionController.Stub {
4479 ActivityManagerService mActivityManagerService;
4480 PermissionController(ActivityManagerService activityManagerService) {
4481 mActivityManagerService = activityManagerService;
4482 }
4483
4484 public boolean checkPermission(String permission, int pid, int uid) {
4485 return mActivityManagerService.checkPermission(permission, pid,
4486 uid) == PackageManager.PERMISSION_GRANTED;
4487 }
4488 }
4489
4490 /**
4491 * This can be called with or without the global lock held.
4492 */
4493 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004494 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 // We might be performing an operation on behalf of an indirect binder
4496 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4497 // client identity accordingly before proceeding.
4498 Identity tlsIdentity = sCallerIdentity.get();
4499 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004500 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004501 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4502 uid = tlsIdentity.uid;
4503 pid = tlsIdentity.pid;
4504 }
4505
4506 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004507 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 return PackageManager.PERMISSION_GRANTED;
4509 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004510 // If there is a uid that owns whatever is being accessed, it has
4511 // blanket access to it regardless of the permissions it requires.
4512 if (owningUid >= 0 && uid == owningUid) {
4513 return PackageManager.PERMISSION_GRANTED;
4514 }
4515 // If the target is not exported, then nobody else can get to it.
4516 if (!exported) {
4517 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004518 return PackageManager.PERMISSION_DENIED;
4519 }
4520 if (permission == null) {
4521 return PackageManager.PERMISSION_GRANTED;
4522 }
4523 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004524 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 .checkUidPermission(permission, uid);
4526 } catch (RemoteException e) {
4527 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004528 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 }
4530 return PackageManager.PERMISSION_DENIED;
4531 }
4532
4533 /**
4534 * As the only public entry point for permissions checking, this method
4535 * can enforce the semantic that requesting a check on a null global
4536 * permission is automatically denied. (Internally a null permission
4537 * string is used when calling {@link #checkComponentPermission} in cases
4538 * when only uid-based security is needed.)
4539 *
4540 * This can be called with or without the global lock held.
4541 */
4542 public int checkPermission(String permission, int pid, int uid) {
4543 if (permission == null) {
4544 return PackageManager.PERMISSION_DENIED;
4545 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004546 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004547 }
4548
4549 /**
4550 * Binder IPC calls go through the public entry point.
4551 * This can be called with or without the global lock held.
4552 */
4553 int checkCallingPermission(String permission) {
4554 return checkPermission(permission,
4555 Binder.getCallingPid(),
4556 Binder.getCallingUid());
4557 }
4558
4559 /**
4560 * This can be called with or without the global lock held.
4561 */
4562 void enforceCallingPermission(String permission, String func) {
4563 if (checkCallingPermission(permission)
4564 == PackageManager.PERMISSION_GRANTED) {
4565 return;
4566 }
4567
4568 String msg = "Permission Denial: " + func + " from pid="
4569 + Binder.getCallingPid()
4570 + ", uid=" + Binder.getCallingUid()
4571 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004572 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 throw new SecurityException(msg);
4574 }
4575
4576 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004577 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4578 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4579 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4580 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4581 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004583 // Is the component private from the target uid?
4584 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4585
4586 // Acceptable if the there is no read permission needed from the
4587 // target or the target is holding the read permission.
4588 if (!readPerm) {
4589 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004591 == PackageManager.PERMISSION_GRANTED)) {
4592 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 }
4594 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004595
4596 // Acceptable if the there is no write permission needed from the
4597 // target or the target is holding the read permission.
4598 if (!writePerm) {
4599 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004601 == PackageManager.PERMISSION_GRANTED)) {
4602 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 }
4604 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004605
4606 // Acceptable if there is a path permission matching the URI that
4607 // the target holds the permission on.
4608 PathPermission[] pps = pi.pathPermissions;
4609 if (pps != null && (!readPerm || !writePerm)) {
4610 final String path = uri.getPath();
4611 int i = pps.length;
4612 while (i > 0 && (!readPerm || !writePerm)) {
4613 i--;
4614 PathPermission pp = pps[i];
4615 if (!readPerm) {
4616 final String pprperm = pp.getReadPermission();
4617 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4618 + pprperm + " for " + pp.getPath()
4619 + ": match=" + pp.match(path)
4620 + " check=" + pm.checkUidPermission(pprperm, uid));
4621 if (pprperm != null && pp.match(path) &&
4622 (pm.checkUidPermission(pprperm, uid)
4623 == PackageManager.PERMISSION_GRANTED)) {
4624 readPerm = true;
4625 }
4626 }
4627 if (!writePerm) {
4628 final String ppwperm = pp.getWritePermission();
4629 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4630 + ppwperm + " for " + pp.getPath()
4631 + ": match=" + pp.match(path)
4632 + " check=" + pm.checkUidPermission(ppwperm, uid));
4633 if (ppwperm != null && pp.match(path) &&
4634 (pm.checkUidPermission(ppwperm, uid)
4635 == PackageManager.PERMISSION_GRANTED)) {
4636 writePerm = true;
4637 }
4638 }
4639 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 } catch (RemoteException e) {
4642 return false;
4643 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004644
4645 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 }
4647
4648 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4649 int modeFlags) {
4650 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004651 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 return true;
4653 }
4654 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4655 if (perms == null) return false;
4656 UriPermission perm = perms.get(uri);
4657 if (perm == null) return false;
4658 return (modeFlags&perm.modeFlags) == modeFlags;
4659 }
4660
4661 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4662 // Another redirected-binder-call permissions check as in
4663 // {@link checkComponentPermission}.
4664 Identity tlsIdentity = sCallerIdentity.get();
4665 if (tlsIdentity != null) {
4666 uid = tlsIdentity.uid;
4667 pid = tlsIdentity.pid;
4668 }
4669
4670 // Our own process gets to do everything.
4671 if (pid == MY_PID) {
4672 return PackageManager.PERMISSION_GRANTED;
4673 }
4674 synchronized(this) {
4675 return checkUriPermissionLocked(uri, uid, modeFlags)
4676 ? PackageManager.PERMISSION_GRANTED
4677 : PackageManager.PERMISSION_DENIED;
4678 }
4679 }
4680
Dianne Hackborn39792d22010-08-19 18:01:52 -07004681 /**
4682 * Check if the targetPkg can be granted permission to access uri by
4683 * the callingUid using the given modeFlags. Throws a security exception
4684 * if callingUid is not allowed to do this. Returns the uid of the target
4685 * if the URI permission grant should be performed; returns -1 if it is not
4686 * needed (for example targetPkg already has permission to access the URI).
4687 */
4688 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4689 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4691 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4692 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004693 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 }
4695
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004696 if (targetPkg != null) {
4697 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4698 "Checking grant " + targetPkg + " permission to " + uri);
4699 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004700
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004701 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004702
4703 // If this is not a content: uri, we can't do anything with it.
4704 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004705 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004706 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004707 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 }
4709
4710 String name = uri.getAuthority();
4711 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004712 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 if (cpr != null) {
4714 pi = cpr.info;
4715 } else {
4716 try {
4717 pi = pm.resolveContentProvider(name,
4718 PackageManager.GET_URI_PERMISSION_PATTERNS);
4719 } catch (RemoteException ex) {
4720 }
4721 }
4722 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004723 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004724 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725 }
4726
4727 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004728 if (targetPkg != null) {
4729 try {
4730 targetUid = pm.getPackageUid(targetPkg);
4731 if (targetUid < 0) {
4732 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4733 "Can't grant URI permission no uid for: " + targetPkg);
4734 return -1;
4735 }
4736 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004737 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004739 } else {
4740 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 }
4742
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004743 if (targetUid >= 0) {
4744 // First... does the target actually need this permission?
4745 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4746 // No need to grant the target this permission.
4747 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4748 "Target " + targetPkg + " already has full permission to " + uri);
4749 return -1;
4750 }
4751 } else {
4752 // First... there is no target package, so can anyone access it?
4753 boolean allowed = pi.exported;
4754 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4755 if (pi.readPermission != null) {
4756 allowed = false;
4757 }
4758 }
4759 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4760 if (pi.writePermission != null) {
4761 allowed = false;
4762 }
4763 }
4764 if (allowed) {
4765 return -1;
4766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 }
4768
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004769 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 if (!pi.grantUriPermissions) {
4771 throw new SecurityException("Provider " + pi.packageName
4772 + "/" + pi.name
4773 + " does not allow granting of Uri permissions (uri "
4774 + uri + ")");
4775 }
4776 if (pi.uriPermissionPatterns != null) {
4777 final int N = pi.uriPermissionPatterns.length;
4778 boolean allowed = false;
4779 for (int i=0; i<N; i++) {
4780 if (pi.uriPermissionPatterns[i] != null
4781 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4782 allowed = true;
4783 break;
4784 }
4785 }
4786 if (!allowed) {
4787 throw new SecurityException("Provider " + pi.packageName
4788 + "/" + pi.name
4789 + " does not allow granting of permission to path of Uri "
4790 + uri);
4791 }
4792 }
4793
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004794 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004796 if (callingUid != Process.myUid()) {
4797 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4798 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4799 throw new SecurityException("Uid " + callingUid
4800 + " does not have permission to uri " + uri);
4801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 }
4803 }
4804
Dianne Hackborn39792d22010-08-19 18:01:52 -07004805 return targetUid;
4806 }
4807
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004808 public int checkGrantUriPermission(int callingUid, String targetPkg,
4809 Uri uri, int modeFlags) {
4810 synchronized(this) {
4811 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4812 }
4813 }
4814
Dianne Hackborn39792d22010-08-19 18:01:52 -07004815 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4816 Uri uri, int modeFlags, UriPermissionOwner owner) {
4817 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4818 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4819 if (modeFlags == 0) {
4820 return;
4821 }
4822
4823 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 // to the uri, and the target doesn't. Let's now give this to
4825 // the target.
4826
Joe Onorato8a9b2202010-02-26 18:56:32 -08004827 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004828 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 HashMap<Uri, UriPermission> targetUris
4831 = mGrantedUriPermissions.get(targetUid);
4832 if (targetUris == null) {
4833 targetUris = new HashMap<Uri, UriPermission>();
4834 mGrantedUriPermissions.put(targetUid, targetUris);
4835 }
4836
4837 UriPermission perm = targetUris.get(uri);
4838 if (perm == null) {
4839 perm = new UriPermission(targetUid, uri);
4840 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004841 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004844 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004845 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004846 } else {
4847 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4848 perm.readOwners.add(owner);
4849 owner.addReadPermission(perm);
4850 }
4851 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4852 perm.writeOwners.add(owner);
4853 owner.addWritePermission(perm);
4854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004855 }
4856 }
4857
Dianne Hackborn39792d22010-08-19 18:01:52 -07004858 void grantUriPermissionLocked(int callingUid,
4859 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004860 if (targetPkg == null) {
4861 throw new NullPointerException("targetPkg");
4862 }
4863
Dianne Hackborn39792d22010-08-19 18:01:52 -07004864 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4865 if (targetUid < 0) {
4866 return;
4867 }
4868
4869 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4870 }
4871
4872 /**
4873 * Like checkGrantUriPermissionLocked, but takes an Intent.
4874 */
4875 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4876 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004877 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004878 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004879 + " from " + intent + "; flags=0x"
4880 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4881
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004882 if (targetPkg == null) {
4883 throw new NullPointerException("targetPkg");
4884 }
4885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004887 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 }
4889 Uri data = intent.getData();
4890 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004891 return -1;
4892 }
4893 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4894 intent.getFlags());
4895 }
4896
4897 /**
4898 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4899 */
4900 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4901 String targetPkg, Intent intent, UriPermissionOwner owner) {
4902 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4903 intent.getFlags(), owner);
4904 }
4905
4906 void grantUriPermissionFromIntentLocked(int callingUid,
4907 String targetPkg, Intent intent, UriPermissionOwner owner) {
4908 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4909 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 return;
4911 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004912
4913 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 }
4915
4916 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4917 Uri uri, int modeFlags) {
4918 synchronized(this) {
4919 final ProcessRecord r = getRecordForAppLocked(caller);
4920 if (r == null) {
4921 throw new SecurityException("Unable to find app for caller "
4922 + caller
4923 + " when granting permission to uri " + uri);
4924 }
4925 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004926 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927 }
4928 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004929 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930 }
4931
4932 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4933 null);
4934 }
4935 }
4936
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004937 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4939 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4940 HashMap<Uri, UriPermission> perms
4941 = mGrantedUriPermissions.get(perm.uid);
4942 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004943 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004944 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 perms.remove(perm.uri);
4946 if (perms.size() == 0) {
4947 mGrantedUriPermissions.remove(perm.uid);
4948 }
4949 }
4950 }
4951 }
4952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4954 int modeFlags) {
4955 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4956 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4957 if (modeFlags == 0) {
4958 return;
4959 }
4960
Joe Onorato8a9b2202010-02-26 18:56:32 -08004961 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004962 "Revoking all granted permissions to " + uri);
4963
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004964 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965
4966 final String authority = uri.getAuthority();
4967 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004968 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 if (cpr != null) {
4970 pi = cpr.info;
4971 } else {
4972 try {
4973 pi = pm.resolveContentProvider(authority,
4974 PackageManager.GET_URI_PERMISSION_PATTERNS);
4975 } catch (RemoteException ex) {
4976 }
4977 }
4978 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004979 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 return;
4981 }
4982
4983 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004984 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 // Right now, if you are not the original owner of the permission,
4986 // you are not allowed to revoke it.
4987 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4988 throw new SecurityException("Uid " + callingUid
4989 + " does not have permission to uri " + uri);
4990 //}
4991 }
4992
4993 // Go through all of the permissions and remove any that match.
4994 final List<String> SEGMENTS = uri.getPathSegments();
4995 if (SEGMENTS != null) {
4996 final int NS = SEGMENTS.size();
4997 int N = mGrantedUriPermissions.size();
4998 for (int i=0; i<N; i++) {
4999 HashMap<Uri, UriPermission> perms
5000 = mGrantedUriPermissions.valueAt(i);
5001 Iterator<UriPermission> it = perms.values().iterator();
5002 toploop:
5003 while (it.hasNext()) {
5004 UriPermission perm = it.next();
5005 Uri targetUri = perm.uri;
5006 if (!authority.equals(targetUri.getAuthority())) {
5007 continue;
5008 }
5009 List<String> targetSegments = targetUri.getPathSegments();
5010 if (targetSegments == null) {
5011 continue;
5012 }
5013 if (targetSegments.size() < NS) {
5014 continue;
5015 }
5016 for (int j=0; j<NS; j++) {
5017 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5018 continue toploop;
5019 }
5020 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005021 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005022 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005023 perm.clearModes(modeFlags);
5024 if (perm.modeFlags == 0) {
5025 it.remove();
5026 }
5027 }
5028 if (perms.size() == 0) {
5029 mGrantedUriPermissions.remove(
5030 mGrantedUriPermissions.keyAt(i));
5031 N--;
5032 i--;
5033 }
5034 }
5035 }
5036 }
5037
5038 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5039 int modeFlags) {
5040 synchronized(this) {
5041 final ProcessRecord r = getRecordForAppLocked(caller);
5042 if (r == null) {
5043 throw new SecurityException("Unable to find app for caller "
5044 + caller
5045 + " when revoking permission to uri " + uri);
5046 }
5047 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005048 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005049 return;
5050 }
5051
5052 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5053 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5054 if (modeFlags == 0) {
5055 return;
5056 }
5057
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005058 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059
5060 final String authority = uri.getAuthority();
5061 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07005062 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005063 if (cpr != null) {
5064 pi = cpr.info;
5065 } else {
5066 try {
5067 pi = pm.resolveContentProvider(authority,
5068 PackageManager.GET_URI_PERMISSION_PATTERNS);
5069 } catch (RemoteException ex) {
5070 }
5071 }
5072 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005073 Slog.w(TAG, "No content provider found for permission revoke: "
5074 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005075 return;
5076 }
5077
5078 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5079 }
5080 }
5081
Dianne Hackborn7e269642010-08-25 19:50:20 -07005082 @Override
5083 public IBinder newUriPermissionOwner(String name) {
5084 synchronized(this) {
5085 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5086 return owner.getExternalTokenLocked();
5087 }
5088 }
5089
5090 @Override
5091 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5092 Uri uri, int modeFlags) {
5093 synchronized(this) {
5094 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5095 if (owner == null) {
5096 throw new IllegalArgumentException("Unknown owner: " + token);
5097 }
5098 if (fromUid != Binder.getCallingUid()) {
5099 if (Binder.getCallingUid() != Process.myUid()) {
5100 // Only system code can grant URI permissions on behalf
5101 // of other users.
5102 throw new SecurityException("nice try");
5103 }
5104 }
5105 if (targetPkg == null) {
5106 throw new IllegalArgumentException("null target");
5107 }
5108 if (uri == null) {
5109 throw new IllegalArgumentException("null uri");
5110 }
5111
5112 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5113 }
5114 }
5115
5116 @Override
5117 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5118 synchronized(this) {
5119 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5120 if (owner == null) {
5121 throw new IllegalArgumentException("Unknown owner: " + token);
5122 }
5123
5124 if (uri == null) {
5125 owner.removeUriPermissionsLocked(mode);
5126 } else {
5127 owner.removeUriPermissionLocked(uri, mode);
5128 }
5129 }
5130 }
5131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005132 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5133 synchronized (this) {
5134 ProcessRecord app =
5135 who != null ? getRecordForAppLocked(who) : null;
5136 if (app == null) return;
5137
5138 Message msg = Message.obtain();
5139 msg.what = WAIT_FOR_DEBUGGER_MSG;
5140 msg.obj = app;
5141 msg.arg1 = waiting ? 1 : 0;
5142 mHandler.sendMessage(msg);
5143 }
5144 }
5145
5146 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005147 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5148 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005149 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005150 outInfo.threshold = homeAppMem;
5151 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5152 outInfo.hiddenAppThreshold = hiddenAppMem;
5153 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005154 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005155 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5156 ProcessList.VISIBLE_APP_ADJ);
5157 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5158 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 }
5160
5161 // =========================================================
5162 // TASK MANAGEMENT
5163 // =========================================================
5164
5165 public List getTasks(int maxNum, int flags,
5166 IThumbnailReceiver receiver) {
5167 ArrayList list = new ArrayList();
5168
5169 PendingThumbnailsRecord pending = null;
5170 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005171 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005172
5173 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005174 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5176 + ", receiver=" + receiver);
5177
5178 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5179 != PackageManager.PERMISSION_GRANTED) {
5180 if (receiver != null) {
5181 // If the caller wants to wait for pending thumbnails,
5182 // it ain't gonna get them.
5183 try {
5184 receiver.finished();
5185 } catch (RemoteException ex) {
5186 }
5187 }
5188 String msg = "Permission Denial: getTasks() from pid="
5189 + Binder.getCallingPid()
5190 + ", uid=" + Binder.getCallingUid()
5191 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005192 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 throw new SecurityException(msg);
5194 }
5195
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005196 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005197 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005198 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005199 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 TaskRecord curTask = null;
5201 int numActivities = 0;
5202 int numRunning = 0;
5203 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005204 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005205 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005206 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207
5208 // Initialize state for next task if needed.
5209 if (top == null ||
5210 (top.state == ActivityState.INITIALIZING
5211 && top.task == r.task)) {
5212 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 curTask = r.task;
5214 numActivities = numRunning = 0;
5215 }
5216
5217 // Add 'r' into the current task.
5218 numActivities++;
5219 if (r.app != null && r.app.thread != null) {
5220 numRunning++;
5221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005222
Joe Onorato8a9b2202010-02-26 18:56:32 -08005223 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 TAG, r.intent.getComponent().flattenToShortString()
5225 + ": task=" + r.task);
5226
5227 // If the next one is a different task, generate a new
5228 // TaskInfo entry for what we have.
5229 if (next == null || next.task != curTask) {
5230 ActivityManager.RunningTaskInfo ci
5231 = new ActivityManager.RunningTaskInfo();
5232 ci.id = curTask.taskId;
5233 ci.baseActivity = r.intent.getComponent();
5234 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005235 if (top.thumbHolder != null) {
5236 ci.description = top.thumbHolder.lastDescription;
5237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005238 ci.numActivities = numActivities;
5239 ci.numRunning = numRunning;
5240 //System.out.println(
5241 // "#" + maxNum + ": " + " descr=" + ci.description);
5242 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005243 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 TAG, "State=" + top.state + "Idle=" + top.idle
5245 + " app=" + top.app
5246 + " thr=" + (top.app != null ? top.app.thread : null));
5247 if (top.state == ActivityState.RESUMED
5248 || top.state == ActivityState.PAUSING) {
5249 if (top.idle && top.app != null
5250 && top.app.thread != null) {
5251 topRecord = top;
5252 topThumbnail = top.app.thread;
5253 } else {
5254 top.thumbnailNeeded = true;
5255 }
5256 }
5257 if (pending == null) {
5258 pending = new PendingThumbnailsRecord(receiver);
5259 }
5260 pending.pendingRecords.add(top);
5261 }
5262 list.add(ci);
5263 maxNum--;
5264 top = null;
5265 }
5266 }
5267
5268 if (pending != null) {
5269 mPendingThumbnails.add(pending);
5270 }
5271 }
5272
Joe Onorato8a9b2202010-02-26 18:56:32 -08005273 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005274
5275 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005276 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005277 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005278 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005280 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005281 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 }
5283 }
5284
5285 if (pending == null && receiver != null) {
5286 // In this case all thumbnails were available and the client
5287 // is being asked to be told when the remaining ones come in...
5288 // which is unusually, since the top-most currently running
5289 // activity should never have a canned thumbnail! Oh well.
5290 try {
5291 receiver.finished();
5292 } catch (RemoteException ex) {
5293 }
5294 }
5295
5296 return list;
5297 }
5298
5299 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5300 int flags) {
5301 synchronized (this) {
5302 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5303 "getRecentTasks()");
5304
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005305 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 final int N = mRecentTasks.size();
5308 ArrayList<ActivityManager.RecentTaskInfo> res
5309 = new ArrayList<ActivityManager.RecentTaskInfo>(
5310 maxNum < N ? maxNum : N);
5311 for (int i=0; i<N && maxNum > 0; i++) {
5312 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005313 // Return the entry if desired by the caller. We always return
5314 // the first entry, because callers always expect this to be the
5315 // forground app. We may filter others if the caller has
5316 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5317 // we should exclude the entry.
5318 if (i == 0
5319 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005320 || (tr.intent == null)
5321 || ((tr.intent.getFlags()
5322 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5323 ActivityManager.RecentTaskInfo rti
5324 = new ActivityManager.RecentTaskInfo();
5325 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005326 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005327 rti.baseIntent = new Intent(
5328 tr.intent != null ? tr.intent : tr.affinityIntent);
5329 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005330 rti.description = tr.lastDescription;
5331
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005332 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5333 // Check whether this activity is currently available.
5334 try {
5335 if (rti.origActivity != null) {
5336 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5337 continue;
5338 }
5339 } else if (rti.baseIntent != null) {
5340 if (pm.queryIntentActivities(rti.baseIntent,
5341 null, 0) == null) {
5342 continue;
5343 }
5344 }
5345 } catch (RemoteException e) {
5346 // Will never happen.
5347 }
5348 }
5349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 res.add(rti);
5351 maxNum--;
5352 }
5353 }
5354 return res;
5355 }
5356 }
5357
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005358 private TaskRecord taskForIdLocked(int id) {
5359 final int N = mRecentTasks.size();
5360 for (int i=0; i<N; i++) {
5361 TaskRecord tr = mRecentTasks.get(i);
5362 if (tr.taskId == id) {
5363 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005364 }
5365 }
5366 return null;
5367 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005368
5369 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5370 synchronized (this) {
5371 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5372 "getTaskThumbnails()");
5373 TaskRecord tr = taskForIdLocked(id);
5374 if (tr != null) {
5375 return mMainStack.getTaskThumbnailsLocked(tr);
5376 }
5377 }
5378 return null;
5379 }
5380
5381 public boolean removeSubTask(int taskId, int subTaskIndex) {
5382 synchronized (this) {
5383 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5384 "removeSubTask()");
5385 long ident = Binder.clearCallingIdentity();
5386 try {
5387 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5388 } finally {
5389 Binder.restoreCallingIdentity(ident);
5390 }
5391 }
5392 }
5393
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005394 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005395 TaskRecord tr = root.task;
5396 Intent baseIntent = new Intent(
5397 tr.intent != null ? tr.intent : tr.affinityIntent);
5398 ComponentName component = baseIntent.getComponent();
5399 if (component == null) {
5400 Slog.w(TAG, "Now component for base intent of task: " + tr);
5401 return;
5402 }
5403
5404 // Find any running services associated with this app.
5405 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5406 for (ServiceRecord sr : mServices.values()) {
5407 if (sr.packageName.equals(component.getPackageName())) {
5408 services.add(sr);
5409 }
5410 }
5411
5412 // Take care of any running services associated with the app.
5413 for (int i=0; i<services.size(); i++) {
5414 ServiceRecord sr = services.get(i);
5415 if (sr.startRequested) {
5416 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005417 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005418 stopServiceLocked(sr);
5419 } else {
5420 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5421 sr.makeNextStartId(), baseIntent, -1));
5422 if (sr.app != null && sr.app.thread != null) {
5423 sendServiceArgsLocked(sr, false);
5424 }
5425 }
5426 }
5427 }
5428
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005429 if (killProcesses) {
5430 // Find any running processes associated with this app.
5431 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5432 SparseArray<ProcessRecord> appProcs
5433 = mProcessNames.getMap().get(component.getPackageName());
5434 if (appProcs != null) {
5435 for (int i=0; i<appProcs.size(); i++) {
5436 procs.add(appProcs.valueAt(i));
5437 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005438 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005439
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005440 // Kill the running processes.
5441 for (int i=0; i<procs.size(); i++) {
5442 ProcessRecord pr = procs.get(i);
5443 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5444 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5445 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5446 pr.processName, pr.setAdj, "remove task");
5447 Process.killProcessQuiet(pr.pid);
5448 } else {
5449 pr.waitingToKill = "remove task";
5450 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005451 }
5452 }
5453 }
5454
5455 public boolean removeTask(int taskId, int flags) {
5456 synchronized (this) {
5457 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5458 "removeTask()");
5459 long ident = Binder.clearCallingIdentity();
5460 try {
5461 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5462 if (r != null) {
5463 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005464 cleanUpRemovedTaskLocked(r,
5465 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005466 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005467 } else {
5468 TaskRecord tr = null;
5469 int i=0;
5470 while (i < mRecentTasks.size()) {
5471 TaskRecord t = mRecentTasks.get(i);
5472 if (t.taskId == taskId) {
5473 tr = t;
5474 break;
5475 }
5476 i++;
5477 }
5478 if (tr != null) {
5479 if (tr.numActivities <= 0) {
5480 // Caller is just removing a recent task that is
5481 // not actively running. That is easy!
5482 mRecentTasks.remove(i);
5483 } else {
5484 Slog.w(TAG, "removeTask: task " + taskId
5485 + " does not have activities to remove, "
5486 + " but numActivities=" + tr.numActivities
5487 + ": " + tr);
5488 }
5489 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005490 }
5491 } finally {
5492 Binder.restoreCallingIdentity(ident);
5493 }
5494 }
5495 return false;
5496 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005498 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5499 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005500 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005501 TaskRecord jt = startTask;
5502
5503 // First look backwards
5504 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005505 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506 if (r.task != jt) {
5507 jt = r.task;
5508 if (affinity.equals(jt.affinity)) {
5509 return j;
5510 }
5511 }
5512 }
5513
5514 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005515 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005516 jt = startTask;
5517 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005518 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005519 if (r.task != jt) {
5520 if (affinity.equals(jt.affinity)) {
5521 return j;
5522 }
5523 jt = r.task;
5524 }
5525 }
5526
5527 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005528 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 return N-1;
5530 }
5531
5532 return -1;
5533 }
5534
5535 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005536 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005537 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005538 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005539 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5540 "moveTaskToFront()");
5541
5542 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005543 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5544 Binder.getCallingUid(), "Task to front")) {
5545 return;
5546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005547 final long origId = Binder.clearCallingIdentity();
5548 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005549 TaskRecord tr = taskForIdLocked(task);
5550 if (tr != null) {
5551 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5552 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005553 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005554 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5555 // Caller wants the home activity moved with it. To accomplish this,
5556 // we'll just move the home task to the top first.
5557 mMainStack.moveHomeToFrontLocked();
5558 }
5559 mMainStack.moveTaskToFrontLocked(tr, null);
5560 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005562 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5563 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005565 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5566 mMainStack.mUserLeaving = true;
5567 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005568 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5569 // Caller wants the home activity moved with it. To accomplish this,
5570 // we'll just move the home task to the top first.
5571 mMainStack.moveHomeToFrontLocked();
5572 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005573 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 return;
5575 }
5576 }
5577 } finally {
5578 Binder.restoreCallingIdentity(origId);
5579 }
5580 }
5581 }
5582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005583 public void moveTaskToBack(int task) {
5584 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5585 "moveTaskToBack()");
5586
5587 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005588 if (mMainStack.mResumedActivity != null
5589 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005590 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5591 Binder.getCallingUid(), "Task to back")) {
5592 return;
5593 }
5594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005596 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005597 Binder.restoreCallingIdentity(origId);
5598 }
5599 }
5600
5601 /**
5602 * Moves an activity, and all of the other activities within the same task, to the bottom
5603 * of the history stack. The activity's order within the task is unchanged.
5604 *
5605 * @param token A reference to the activity we wish to move
5606 * @param nonRoot If false then this only works if the activity is the root
5607 * of a task; if true it will work for any activity in a task.
5608 * @return Returns true if the move completed, false if not.
5609 */
5610 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5611 synchronized(this) {
5612 final long origId = Binder.clearCallingIdentity();
5613 int taskId = getTaskForActivityLocked(token, !nonRoot);
5614 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005615 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005616 }
5617 Binder.restoreCallingIdentity(origId);
5618 }
5619 return false;
5620 }
5621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 public void moveTaskBackwards(int task) {
5623 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5624 "moveTaskBackwards()");
5625
5626 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005627 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5628 Binder.getCallingUid(), "Task backwards")) {
5629 return;
5630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 final long origId = Binder.clearCallingIdentity();
5632 moveTaskBackwardsLocked(task);
5633 Binder.restoreCallingIdentity(origId);
5634 }
5635 }
5636
5637 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005638 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 }
5640
5641 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5642 synchronized(this) {
5643 return getTaskForActivityLocked(token, onlyRoot);
5644 }
5645 }
5646
5647 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005648 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005649 TaskRecord lastTask = null;
5650 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005651 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005652 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653 if (!onlyRoot || lastTask != r.task) {
5654 return r.task.taskId;
5655 }
5656 return -1;
5657 }
5658 lastTask = r.task;
5659 }
5660
5661 return -1;
5662 }
5663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005664 public void finishOtherInstances(IBinder token, ComponentName className) {
5665 synchronized(this) {
5666 final long origId = Binder.clearCallingIdentity();
5667
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005668 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005669 TaskRecord lastTask = null;
5670 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005671 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005673 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005674 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 null, "others")) {
5676 i--;
5677 N--;
5678 }
5679 }
5680 lastTask = r.task;
5681 }
5682
5683 Binder.restoreCallingIdentity(origId);
5684 }
5685 }
5686
5687 // =========================================================
5688 // THUMBNAILS
5689 // =========================================================
5690
5691 public void reportThumbnail(IBinder token,
5692 Bitmap thumbnail, CharSequence description) {
5693 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5694 final long origId = Binder.clearCallingIdentity();
5695 sendPendingThumbnail(null, token, thumbnail, description, true);
5696 Binder.restoreCallingIdentity(origId);
5697 }
5698
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005699 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005700 Bitmap thumbnail, CharSequence description, boolean always) {
5701 TaskRecord task = null;
5702 ArrayList receivers = null;
5703
5704 //System.out.println("Send pending thumbnail: " + r);
5705
5706 synchronized(this) {
5707 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005708 r = mMainStack.isInStackLocked(token);
5709 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 return;
5711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005713 if (thumbnail == null && r.thumbHolder != null) {
5714 thumbnail = r.thumbHolder.lastThumbnail;
5715 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 }
5717 if (thumbnail == null && !always) {
5718 // If there is no thumbnail, and this entry is not actually
5719 // going away, then abort for now and pick up the next
5720 // thumbnail we get.
5721 return;
5722 }
5723 task = r.task;
5724
5725 int N = mPendingThumbnails.size();
5726 int i=0;
5727 while (i<N) {
5728 PendingThumbnailsRecord pr =
5729 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5730 //System.out.println("Looking in " + pr.pendingRecords);
5731 if (pr.pendingRecords.remove(r)) {
5732 if (receivers == null) {
5733 receivers = new ArrayList();
5734 }
5735 receivers.add(pr);
5736 if (pr.pendingRecords.size() == 0) {
5737 pr.finished = true;
5738 mPendingThumbnails.remove(i);
5739 N--;
5740 continue;
5741 }
5742 }
5743 i++;
5744 }
5745 }
5746
5747 if (receivers != null) {
5748 final int N = receivers.size();
5749 for (int i=0; i<N; i++) {
5750 try {
5751 PendingThumbnailsRecord pr =
5752 (PendingThumbnailsRecord)receivers.get(i);
5753 pr.receiver.newThumbnail(
5754 task != null ? task.taskId : -1, thumbnail, description);
5755 if (pr.finished) {
5756 pr.receiver.finished();
5757 }
5758 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005759 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 }
5761 }
5762 }
5763 }
5764
5765 // =========================================================
5766 // CONTENT PROVIDERS
5767 // =========================================================
5768
Jeff Brown10e89712011-07-08 18:52:57 -07005769 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5770 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005771 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005772 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005773 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005774 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005775 } catch (RemoteException ex) {
5776 }
5777 if (providers != null) {
5778 final int N = providers.size();
5779 for (int i=0; i<N; i++) {
5780 ProviderInfo cpi =
5781 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005782 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5783 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005784 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005785 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005786 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005787 }
5788 app.pubProviders.put(cpi.name, cpr);
5789 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005790 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 }
5792 }
5793 return providers;
5794 }
5795
5796 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005797 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005798 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5799 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5800 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005801 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005802 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 return null;
5804 }
5805 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005806 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005807 == PackageManager.PERMISSION_GRANTED) {
5808 return null;
5809 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005810
5811 PathPermission[] pps = cpi.pathPermissions;
5812 if (pps != null) {
5813 int i = pps.length;
5814 while (i > 0) {
5815 i--;
5816 PathPermission pp = pps[i];
5817 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005818 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005819 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005820 return null;
5821 }
5822 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005823 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005824 == PackageManager.PERMISSION_GRANTED) {
5825 return null;
5826 }
5827 }
5828 }
5829
Dianne Hackbornb424b632010-08-18 15:59:05 -07005830 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5831 if (perms != null) {
5832 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5833 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5834 return null;
5835 }
5836 }
5837 }
5838
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005839 String msg;
5840 if (!cpi.exported) {
5841 msg = "Permission Denial: opening provider " + cpi.name
5842 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5843 + ", uid=" + callingUid + ") that is not exported from uid "
5844 + cpi.applicationInfo.uid;
5845 } else {
5846 msg = "Permission Denial: opening provider " + cpi.name
5847 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5848 + ", uid=" + callingUid + ") requires "
5849 + cpi.readPermission + " or " + cpi.writePermission;
5850 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005851 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 return msg;
5853 }
5854
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005855 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5856 if (r != null) {
5857 Integer cnt = r.conProviders.get(cpr);
5858 if (DEBUG_PROVIDER) Slog.v(TAG,
5859 "Adding provider requested by "
5860 + r.processName + " from process "
5861 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5862 + " cnt=" + (cnt == null ? 1 : cnt));
5863 if (cnt == null) {
5864 cpr.clients.add(r);
5865 r.conProviders.put(cpr, new Integer(1));
5866 return true;
5867 } else {
5868 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5869 }
5870 } else {
5871 cpr.externals++;
5872 }
5873 return false;
5874 }
5875
5876 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5877 if (r != null) {
5878 Integer cnt = r.conProviders.get(cpr);
5879 if (DEBUG_PROVIDER) Slog.v(TAG,
5880 "Removing provider requested by "
5881 + r.processName + " from process "
5882 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5883 + " cnt=" + cnt);
5884 if (cnt == null || cnt.intValue() <= 1) {
5885 cpr.clients.remove(r);
5886 r.conProviders.remove(cpr);
5887 return true;
5888 } else {
5889 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5890 }
5891 } else {
5892 cpr.externals++;
5893 }
5894 return false;
5895 }
5896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 private final ContentProviderHolder getContentProviderImpl(
5898 IApplicationThread caller, String name) {
5899 ContentProviderRecord cpr;
5900 ProviderInfo cpi = null;
5901
5902 synchronized(this) {
5903 ProcessRecord r = null;
5904 if (caller != null) {
5905 r = getRecordForAppLocked(caller);
5906 if (r == null) {
5907 throw new SecurityException(
5908 "Unable to find app for caller " + caller
5909 + " (pid=" + Binder.getCallingPid()
5910 + ") when getting content provider " + name);
5911 }
5912 }
5913
5914 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005915 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005916 boolean providerRunning = cpr != null;
5917 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005918 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005919 String msg;
5920 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5921 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005922 }
5923
5924 if (r != null && cpr.canRunHere(r)) {
5925 // This provider has been published or is in the process
5926 // of being published... but it is also allowed to run
5927 // in the caller's process, so don't make a connection
5928 // and just let the caller instantiate its own instance.
5929 if (cpr.provider != null) {
5930 // don't give caller the provider object, it needs
5931 // to make its own.
5932 cpr = new ContentProviderRecord(cpr);
5933 }
5934 return cpr;
5935 }
5936
5937 final long origId = Binder.clearCallingIdentity();
5938
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005939 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005940 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005941 final boolean countChanged = incProviderCount(r, cpr);
5942 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005943 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005944 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005945 // make sure to count it as being accessed and thus
5946 // back up on the LRU list. This is good because
5947 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005948 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005949 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005950 }
5951
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005952 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005953 if (false) {
5954 if (cpr.name.flattenToShortString().equals(
5955 "com.android.providers.calendar/.CalendarProvider2")) {
5956 Slog.v(TAG, "****************** KILLING "
5957 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005958 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005959 }
5960 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005961 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005962 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5963 // NOTE: there is still a race here where a signal could be
5964 // pending on the process even though we managed to update its
5965 // adj level. Not sure what to do about this, but at least
5966 // the race is now smaller.
5967 if (!success) {
5968 // Uh oh... it looks like the provider's process
5969 // has been killed on us. We need to wait for a new
5970 // process to be started, and make sure its death
5971 // doesn't kill our process.
5972 Slog.i(TAG,
5973 "Existing provider " + cpr.name.flattenToShortString()
5974 + " is crashing; detaching " + r);
5975 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005976 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005977 if (!lastRef) {
5978 // This wasn't the last ref our process had on
5979 // the provider... we have now been killed, bail.
5980 return null;
5981 }
5982 providerRunning = false;
5983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005984 }
5985
5986 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005988
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005989 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005990 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005991 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005992 resolveContentProvider(name,
5993 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 } catch (RemoteException ex) {
5995 }
5996 if (cpi == null) {
5997 return null;
5998 }
5999
Dianne Hackbornb424b632010-08-18 15:59:05 -07006000 String msg;
6001 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6002 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 }
6004
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006005 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006006 && !cpi.processName.equals("system")) {
6007 // If this content provider does not run in the system
6008 // process, and the system is not yet ready to run other
6009 // processes, then fail fast instead of hanging.
6010 throw new IllegalArgumentException(
6011 "Attempt to launch content provider before system ready");
6012 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006013
6014 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6015 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 final boolean firstClass = cpr == null;
6017 if (firstClass) {
6018 try {
6019 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006020 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006021 getApplicationInfo(
6022 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006023 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006024 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006025 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 + cpi.name);
6027 return null;
6028 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006029 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006030 } catch (RemoteException ex) {
6031 // pm is in same process, this will never happen.
6032 }
6033 }
6034
6035 if (r != null && cpr.canRunHere(r)) {
6036 // If this is a multiprocess provider, then just return its
6037 // info and allow the caller to instantiate it. Only do
6038 // this if the provider is the same user as the caller's
6039 // process, or can run as root (so can be in any process).
6040 return cpr;
6041 }
6042
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006043 if (DEBUG_PROVIDER) {
6044 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08006045 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006046 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006047 }
6048
6049 // This is single process, and our app is now connecting to it.
6050 // See if we are already in the process of launching this
6051 // provider.
6052 final int N = mLaunchingProviders.size();
6053 int i;
6054 for (i=0; i<N; i++) {
6055 if (mLaunchingProviders.get(i) == cpr) {
6056 break;
6057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 }
6059
6060 // If the provider is not already being launched, then get it
6061 // started.
6062 if (i >= N) {
6063 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006064
6065 try {
6066 // Content provider is now in use, its package can't be stopped.
6067 try {
6068 AppGlobals.getPackageManager().setPackageStoppedState(
6069 cpr.appInfo.packageName, false);
6070 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006071 } catch (IllegalArgumentException e) {
6072 Slog.w(TAG, "Failed trying to unstop package "
6073 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006074 }
6075
6076 ProcessRecord proc = startProcessLocked(cpi.processName,
6077 cpr.appInfo, false, 0, "content provider",
6078 new ComponentName(cpi.applicationInfo.packageName,
6079 cpi.name), false);
6080 if (proc == null) {
6081 Slog.w(TAG, "Unable to launch app "
6082 + cpi.applicationInfo.packageName + "/"
6083 + cpi.applicationInfo.uid + " for provider "
6084 + name + ": process is bad");
6085 return null;
6086 }
6087 cpr.launchingApp = proc;
6088 mLaunchingProviders.add(cpr);
6089 } finally {
6090 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 }
6093
6094 // Make sure the provider is published (the same provider class
6095 // may be published under multiple names).
6096 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006097 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 }
6099 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006100 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 }
6102 }
6103
6104 // Wait for the provider to be published...
6105 synchronized (cpr) {
6106 while (cpr.provider == null) {
6107 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006108 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 + cpi.applicationInfo.packageName + "/"
6110 + cpi.applicationInfo.uid + " for provider "
6111 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006112 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 cpi.applicationInfo.packageName,
6114 cpi.applicationInfo.uid, name);
6115 return null;
6116 }
6117 try {
6118 cpr.wait();
6119 } catch (InterruptedException ex) {
6120 }
6121 }
6122 }
6123 return cpr;
6124 }
6125
6126 public final ContentProviderHolder getContentProvider(
6127 IApplicationThread caller, String name) {
6128 if (caller == null) {
6129 String msg = "null IApplicationThread when getting content provider "
6130 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006131 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006132 throw new SecurityException(msg);
6133 }
6134
6135 return getContentProviderImpl(caller, name);
6136 }
6137
6138 private ContentProviderHolder getContentProviderExternal(String name) {
6139 return getContentProviderImpl(null, name);
6140 }
6141
6142 /**
6143 * Drop a content provider from a ProcessRecord's bookkeeping
6144 * @param cpr
6145 */
6146 public void removeContentProvider(IApplicationThread caller, String name) {
6147 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006148 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006149 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006150 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006151 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006152 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006153 return;
6154 }
6155 final ProcessRecord r = getRecordForAppLocked(caller);
6156 if (r == null) {
6157 throw new SecurityException(
6158 "Unable to find app for caller " + caller +
6159 " when removing content provider " + name);
6160 }
6161 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006162 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6163 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006164 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006165 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006166 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006167 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006168 return;
6169 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006170 if (decProviderCount(r, localCpr)) {
6171 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006174 }
6175 }
6176
6177 private void removeContentProviderExternal(String name) {
6178 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006179 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006180 if(cpr == null) {
6181 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006182 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 return;
6184 }
6185
6186 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006187 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6188 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006189 localCpr.externals--;
6190 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006191 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006192 }
6193 updateOomAdjLocked();
6194 }
6195 }
6196
6197 public final void publishContentProviders(IApplicationThread caller,
6198 List<ContentProviderHolder> providers) {
6199 if (providers == null) {
6200 return;
6201 }
6202
6203 synchronized(this) {
6204 final ProcessRecord r = getRecordForAppLocked(caller);
6205 if (r == null) {
6206 throw new SecurityException(
6207 "Unable to find app for caller " + caller
6208 + " (pid=" + Binder.getCallingPid()
6209 + ") when publishing content providers");
6210 }
6211
6212 final long origId = Binder.clearCallingIdentity();
6213
6214 final int N = providers.size();
6215 for (int i=0; i<N; i++) {
6216 ContentProviderHolder src = providers.get(i);
6217 if (src == null || src.info == null || src.provider == null) {
6218 continue;
6219 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006220 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006221 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006222 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6223 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006224 String names[] = dst.info.authority.split(";");
6225 for (int j = 0; j < names.length; j++) {
6226 mProvidersByName.put(names[j], dst);
6227 }
6228
6229 int NL = mLaunchingProviders.size();
6230 int j;
6231 for (j=0; j<NL; j++) {
6232 if (mLaunchingProviders.get(j) == dst) {
6233 mLaunchingProviders.remove(j);
6234 j--;
6235 NL--;
6236 }
6237 }
6238 synchronized (dst) {
6239 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006240 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 dst.notifyAll();
6242 }
6243 updateOomAdjLocked(r);
6244 }
6245 }
6246
6247 Binder.restoreCallingIdentity(origId);
6248 }
6249 }
6250
6251 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006252 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006253 synchronized (mSelf) {
6254 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6255 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006256 if (providers != null) {
6257 for (int i=providers.size()-1; i>=0; i--) {
6258 ProviderInfo pi = (ProviderInfo)providers.get(i);
6259 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6260 Slog.w(TAG, "Not installing system proc provider " + pi.name
6261 + ": not system .apk");
6262 providers.remove(i);
6263 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006264 }
6265 }
6266 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006267 if (providers != null) {
6268 mSystemThread.installSystemProviders(providers);
6269 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006270
6271 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006272
6273 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006274 }
6275
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006276 /**
6277 * Allows app to retrieve the MIME type of a URI without having permission
6278 * to access its content provider.
6279 *
6280 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6281 *
6282 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6283 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6284 */
6285 public String getProviderMimeType(Uri uri) {
6286 final String name = uri.getAuthority();
6287 final long ident = Binder.clearCallingIdentity();
6288 ContentProviderHolder holder = null;
6289
6290 try {
6291 holder = getContentProviderExternal(name);
6292 if (holder != null) {
6293 return holder.provider.getType(uri);
6294 }
6295 } catch (RemoteException e) {
6296 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6297 return null;
6298 } finally {
6299 if (holder != null) {
6300 removeContentProviderExternal(name);
6301 }
6302 Binder.restoreCallingIdentity(ident);
6303 }
6304
6305 return null;
6306 }
6307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 // =========================================================
6309 // GLOBAL MANAGEMENT
6310 // =========================================================
6311
6312 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6313 ApplicationInfo info, String customProcess) {
6314 String proc = customProcess != null ? customProcess : info.processName;
6315 BatteryStatsImpl.Uid.Proc ps = null;
6316 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6317 synchronized (stats) {
6318 ps = stats.getProcessStatsLocked(info.uid, proc);
6319 }
6320 return new ProcessRecord(ps, thread, info, proc);
6321 }
6322
6323 final ProcessRecord addAppLocked(ApplicationInfo info) {
6324 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6325
6326 if (app == null) {
6327 app = newProcessRecordLocked(null, info, null);
6328 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006329 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006330 }
6331
Dianne Hackborne7f97212011-02-24 14:40:20 -08006332 // This package really, really can not be stopped.
6333 try {
6334 AppGlobals.getPackageManager().setPackageStoppedState(
6335 info.packageName, false);
6336 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006337 } catch (IllegalArgumentException e) {
6338 Slog.w(TAG, "Failed trying to unstop package "
6339 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006340 }
6341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6343 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6344 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006345 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 }
6347 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6348 mPersistentStartingProcesses.add(app);
6349 startProcessLocked(app, "added application", app.processName);
6350 }
6351
6352 return app;
6353 }
6354
6355 public void unhandledBack() {
6356 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6357 "unhandledBack()");
6358
6359 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006360 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006361 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 TAG, "Performing unhandledBack(): stack size = " + count);
6363 if (count > 1) {
6364 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006365 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006366 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6367 Binder.restoreCallingIdentity(origId);
6368 }
6369 }
6370 }
6371
6372 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6373 String name = uri.getAuthority();
6374 ContentProviderHolder cph = getContentProviderExternal(name);
6375 ParcelFileDescriptor pfd = null;
6376 if (cph != null) {
6377 // We record the binder invoker's uid in thread-local storage before
6378 // going to the content provider to open the file. Later, in the code
6379 // that handles all permissions checks, we look for this uid and use
6380 // that rather than the Activity Manager's own uid. The effect is that
6381 // we do the check against the caller's permissions even though it looks
6382 // to the content provider like the Activity Manager itself is making
6383 // the request.
6384 sCallerIdentity.set(new Identity(
6385 Binder.getCallingPid(), Binder.getCallingUid()));
6386 try {
6387 pfd = cph.provider.openFile(uri, "r");
6388 } catch (FileNotFoundException e) {
6389 // do nothing; pfd will be returned null
6390 } finally {
6391 // Ensure that whatever happens, we clean up the identity state
6392 sCallerIdentity.remove();
6393 }
6394
6395 // We've got the fd now, so we're done with the provider.
6396 removeContentProviderExternal(name);
6397 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006398 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 }
6400 return pfd;
6401 }
6402
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006403 // Actually is sleeping or shutting down or whatever else in the future
6404 // is an inactive state.
6405 public boolean isSleeping() {
6406 return mSleeping || mShuttingDown;
6407 }
6408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006409 public void goingToSleep() {
6410 synchronized(this) {
6411 mSleeping = true;
6412 mWindowManager.setEventDispatching(false);
6413
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006414 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006415
6416 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006417 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006418 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6419 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006420 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006421 }
6422 }
6423
Dianne Hackborn55280a92009-05-07 15:53:46 -07006424 public boolean shutdown(int timeout) {
6425 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6426 != PackageManager.PERMISSION_GRANTED) {
6427 throw new SecurityException("Requires permission "
6428 + android.Manifest.permission.SHUTDOWN);
6429 }
6430
6431 boolean timedout = false;
6432
6433 synchronized(this) {
6434 mShuttingDown = true;
6435 mWindowManager.setEventDispatching(false);
6436
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006437 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006438 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006439 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006440 while (mMainStack.mResumedActivity != null
6441 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006442 long delay = endTime - System.currentTimeMillis();
6443 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006444 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006445 timedout = true;
6446 break;
6447 }
6448 try {
6449 this.wait();
6450 } catch (InterruptedException e) {
6451 }
6452 }
6453 }
6454 }
6455
6456 mUsageStatsService.shutdown();
6457 mBatteryStatsService.shutdown();
6458
6459 return timedout;
6460 }
6461
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006462 public final void activitySlept(IBinder token) {
6463 if (localLOGV) Slog.v(
6464 TAG, "Activity slept: token=" + token);
6465
6466 ActivityRecord r = null;
6467
6468 final long origId = Binder.clearCallingIdentity();
6469
6470 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006471 r = mMainStack.isInStackLocked(token);
6472 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006473 mMainStack.activitySleptLocked(r);
6474 }
6475 }
6476
6477 Binder.restoreCallingIdentity(origId);
6478 }
6479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006480 public void wakingUp() {
6481 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006482 mWindowManager.setEventDispatching(true);
6483 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006484 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006485 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 }
6487 }
6488
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006489 public void stopAppSwitches() {
6490 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6491 != PackageManager.PERMISSION_GRANTED) {
6492 throw new SecurityException("Requires permission "
6493 + android.Manifest.permission.STOP_APP_SWITCHES);
6494 }
6495
6496 synchronized(this) {
6497 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6498 + APP_SWITCH_DELAY_TIME;
6499 mDidAppSwitch = false;
6500 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6501 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6502 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6503 }
6504 }
6505
6506 public void resumeAppSwitches() {
6507 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6508 != PackageManager.PERMISSION_GRANTED) {
6509 throw new SecurityException("Requires permission "
6510 + android.Manifest.permission.STOP_APP_SWITCHES);
6511 }
6512
6513 synchronized(this) {
6514 // Note that we don't execute any pending app switches... we will
6515 // let those wait until either the timeout, or the next start
6516 // activity request.
6517 mAppSwitchesAllowedTime = 0;
6518 }
6519 }
6520
6521 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6522 String name) {
6523 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6524 return true;
6525 }
6526
6527 final int perm = checkComponentPermission(
6528 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006529 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006530 if (perm == PackageManager.PERMISSION_GRANTED) {
6531 return true;
6532 }
6533
Joe Onorato8a9b2202010-02-26 18:56:32 -08006534 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006535 return false;
6536 }
6537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 public void setDebugApp(String packageName, boolean waitForDebugger,
6539 boolean persistent) {
6540 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6541 "setDebugApp()");
6542
6543 // Note that this is not really thread safe if there are multiple
6544 // callers into it at the same time, but that's not a situation we
6545 // care about.
6546 if (persistent) {
6547 final ContentResolver resolver = mContext.getContentResolver();
6548 Settings.System.putString(
6549 resolver, Settings.System.DEBUG_APP,
6550 packageName);
6551 Settings.System.putInt(
6552 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6553 waitForDebugger ? 1 : 0);
6554 }
6555
6556 synchronized (this) {
6557 if (!persistent) {
6558 mOrigDebugApp = mDebugApp;
6559 mOrigWaitForDebugger = mWaitForDebugger;
6560 }
6561 mDebugApp = packageName;
6562 mWaitForDebugger = waitForDebugger;
6563 mDebugTransient = !persistent;
6564 if (packageName != null) {
6565 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006566 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 Binder.restoreCallingIdentity(origId);
6568 }
6569 }
6570 }
6571
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006572 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6573 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6574 synchronized (this) {
6575 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6576 if (!isDebuggable) {
6577 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6578 throw new SecurityException("Process not debuggable: " + app.packageName);
6579 }
6580 }
6581 mProfileApp = processName;
6582 mProfileFile = profileFile;
6583 if (mProfileFd != null) {
6584 try {
6585 mProfileFd.close();
6586 } catch (IOException e) {
6587 }
6588 mProfileFd = null;
6589 }
6590 mProfileFd = profileFd;
6591 mProfileType = 0;
6592 mAutoStopProfiler = autoStopProfiler;
6593 }
6594 }
6595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006596 public void setAlwaysFinish(boolean enabled) {
6597 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6598 "setAlwaysFinish()");
6599
6600 Settings.System.putInt(
6601 mContext.getContentResolver(),
6602 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6603
6604 synchronized (this) {
6605 mAlwaysFinishActivities = enabled;
6606 }
6607 }
6608
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006609 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006610 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006611 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006612 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006613 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006614 }
6615 }
6616
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006617 public boolean isUserAMonkey() {
6618 // For now the fact that there is a controller implies
6619 // we have a monkey.
6620 synchronized (this) {
6621 return mController != null;
6622 }
6623 }
6624
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006625 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006626 synchronized (this) {
6627 mWatchers.register(watcher);
6628 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006629 }
6630
6631 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006632 synchronized (this) {
6633 mWatchers.unregister(watcher);
6634 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006635 }
6636
Jeff Sharkeya4620792011-05-20 15:29:23 -07006637 public void registerProcessObserver(IProcessObserver observer) {
6638 mProcessObservers.register(observer);
6639 }
6640
6641 public void unregisterProcessObserver(IProcessObserver observer) {
6642 mProcessObservers.unregister(observer);
6643 }
6644
Daniel Sandler69a48172010-06-23 16:29:36 -04006645 public void setImmersive(IBinder token, boolean immersive) {
6646 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006647 ActivityRecord r = mMainStack.isInStackLocked(token);
6648 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006649 throw new IllegalArgumentException();
6650 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006651 r.immersive = immersive;
6652 }
6653 }
6654
6655 public boolean isImmersive(IBinder token) {
6656 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006657 ActivityRecord r = mMainStack.isInStackLocked(token);
6658 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006659 throw new IllegalArgumentException();
6660 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006661 return r.immersive;
6662 }
6663 }
6664
6665 public boolean isTopActivityImmersive() {
6666 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006667 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006668 return (r != null) ? r.immersive : false;
6669 }
6670 }
6671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 public final void enterSafeMode() {
6673 synchronized(this) {
6674 // It only makes sense to do this before the system is ready
6675 // and started launching other packages.
6676 if (!mSystemReady) {
6677 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006678 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 } catch (RemoteException e) {
6680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 }
6682 }
6683 }
6684
Jeff Brownb09abc12011-01-13 21:08:27 -08006685 public final void showSafeModeOverlay() {
6686 View v = LayoutInflater.from(mContext).inflate(
6687 com.android.internal.R.layout.safe_mode, null);
6688 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6689 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6690 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6691 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6692 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6693 lp.format = v.getBackground().getOpacity();
6694 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6695 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6696 ((WindowManager)mContext.getSystemService(
6697 Context.WINDOW_SERVICE)).addView(v, lp);
6698 }
6699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 public void noteWakeupAlarm(IIntentSender sender) {
6701 if (!(sender instanceof PendingIntentRecord)) {
6702 return;
6703 }
6704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6705 synchronized (stats) {
6706 if (mBatteryStatsService.isOnBattery()) {
6707 mBatteryStatsService.enforceCallingPermission();
6708 PendingIntentRecord rec = (PendingIntentRecord)sender;
6709 int MY_UID = Binder.getCallingUid();
6710 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6711 BatteryStatsImpl.Uid.Pkg pkg =
6712 stats.getPackageStatsLocked(uid, rec.key.packageName);
6713 pkg.incWakeupsLocked();
6714 }
6715 }
6716 }
6717
Dianne Hackborn64825172011-03-02 21:32:58 -08006718 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006719 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006720 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006722 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 // XXX Note: don't acquire main activity lock here, because the window
6724 // manager calls in with its locks held.
6725
6726 boolean killed = false;
6727 synchronized (mPidsSelfLocked) {
6728 int[] types = new int[pids.length];
6729 int worstType = 0;
6730 for (int i=0; i<pids.length; i++) {
6731 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6732 if (proc != null) {
6733 int type = proc.setAdj;
6734 types[i] = type;
6735 if (type > worstType) {
6736 worstType = type;
6737 }
6738 }
6739 }
6740
Dianne Hackborn64825172011-03-02 21:32:58 -08006741 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006743 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6744 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006745 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006746 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006747
6748 // If this is not a secure call, don't let it kill processes that
6749 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006750 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6751 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006752 }
6753
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006754 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 for (int i=0; i<pids.length; i++) {
6756 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6757 if (proc == null) {
6758 continue;
6759 }
6760 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006761 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006762 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006763 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6764 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006766 proc.killedBackground = true;
6767 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006768 }
6769 }
6770 }
6771 return killed;
6772 }
6773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006774 public final void startRunning(String pkg, String cls, String action,
6775 String data) {
6776 synchronized(this) {
6777 if (mStartRunning) {
6778 return;
6779 }
6780 mStartRunning = true;
6781 mTopComponent = pkg != null && cls != null
6782 ? new ComponentName(pkg, cls) : null;
6783 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6784 mTopData = data;
6785 if (!mSystemReady) {
6786 return;
6787 }
6788 }
6789
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006790 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 }
6792
6793 private void retrieveSettings() {
6794 final ContentResolver resolver = mContext.getContentResolver();
6795 String debugApp = Settings.System.getString(
6796 resolver, Settings.System.DEBUG_APP);
6797 boolean waitForDebugger = Settings.System.getInt(
6798 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6799 boolean alwaysFinishActivities = Settings.System.getInt(
6800 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6801
6802 Configuration configuration = new Configuration();
6803 Settings.System.getConfiguration(resolver, configuration);
6804
6805 synchronized (this) {
6806 mDebugApp = mOrigDebugApp = debugApp;
6807 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6808 mAlwaysFinishActivities = alwaysFinishActivities;
6809 // This happens before any activities are started, so we can
6810 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006811 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006812 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 }
6814 }
6815
6816 public boolean testIsSystemReady() {
6817 // no need to synchronize(this) just to read & return the value
6818 return mSystemReady;
6819 }
6820
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006821 private static File getCalledPreBootReceiversFile() {
6822 File dataDir = Environment.getDataDirectory();
6823 File systemDir = new File(dataDir, "system");
6824 File fname = new File(systemDir, "called_pre_boots.dat");
6825 return fname;
6826 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006827
6828 static final int LAST_DONE_VERSION = 10000;
6829
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006830 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6831 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6832 File file = getCalledPreBootReceiversFile();
6833 FileInputStream fis = null;
6834 try {
6835 fis = new FileInputStream(file);
6836 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006837 int fvers = dis.readInt();
6838 if (fvers == LAST_DONE_VERSION) {
6839 String vers = dis.readUTF();
6840 String codename = dis.readUTF();
6841 String build = dis.readUTF();
6842 if (android.os.Build.VERSION.RELEASE.equals(vers)
6843 && android.os.Build.VERSION.CODENAME.equals(codename)
6844 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6845 int num = dis.readInt();
6846 while (num > 0) {
6847 num--;
6848 String pkg = dis.readUTF();
6849 String cls = dis.readUTF();
6850 lastDoneReceivers.add(new ComponentName(pkg, cls));
6851 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006852 }
6853 }
6854 } catch (FileNotFoundException e) {
6855 } catch (IOException e) {
6856 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6857 } finally {
6858 if (fis != null) {
6859 try {
6860 fis.close();
6861 } catch (IOException e) {
6862 }
6863 }
6864 }
6865 return lastDoneReceivers;
6866 }
6867
6868 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6869 File file = getCalledPreBootReceiversFile();
6870 FileOutputStream fos = null;
6871 DataOutputStream dos = null;
6872 try {
6873 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6874 fos = new FileOutputStream(file);
6875 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006876 dos.writeInt(LAST_DONE_VERSION);
6877 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006878 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006879 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006880 dos.writeInt(list.size());
6881 for (int i=0; i<list.size(); i++) {
6882 dos.writeUTF(list.get(i).getPackageName());
6883 dos.writeUTF(list.get(i).getClassName());
6884 }
6885 } catch (IOException e) {
6886 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6887 file.delete();
6888 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006889 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006890 if (dos != null) {
6891 try {
6892 dos.close();
6893 } catch (IOException e) {
6894 // TODO Auto-generated catch block
6895 e.printStackTrace();
6896 }
6897 }
6898 }
6899 }
6900
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006901 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 synchronized(this) {
6903 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006904 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006905 return;
6906 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006907
6908 // Check to see if there are any update receivers to run.
6909 if (!mDidUpdate) {
6910 if (mWaitingUpdate) {
6911 return;
6912 }
6913 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6914 List<ResolveInfo> ris = null;
6915 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006916 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006917 intent, null, 0);
6918 } catch (RemoteException e) {
6919 }
6920 if (ris != null) {
6921 for (int i=ris.size()-1; i>=0; i--) {
6922 if ((ris.get(i).activityInfo.applicationInfo.flags
6923 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6924 ris.remove(i);
6925 }
6926 }
6927 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006928
6929 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6930
6931 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006932 for (int i=0; i<ris.size(); i++) {
6933 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006934 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6935 if (lastDoneReceivers.contains(comp)) {
6936 ris.remove(i);
6937 i--;
6938 }
6939 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006940
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006941 for (int i=0; i<ris.size(); i++) {
6942 ActivityInfo ai = ris.get(i).activityInfo;
6943 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6944 doneReceivers.add(comp);
6945 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006946 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006947 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006948 finisher = new IIntentReceiver.Stub() {
6949 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006950 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006951 boolean sticky) {
6952 // The raw IIntentReceiver interface is called
6953 // with the AM lock held, so redispatch to
6954 // execute our code without the lock.
6955 mHandler.post(new Runnable() {
6956 public void run() {
6957 synchronized (ActivityManagerService.this) {
6958 mDidUpdate = true;
6959 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006960 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006961 showBootMessage(mContext.getText(
6962 R.string.android_upgrading_complete),
6963 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006964 systemReady(goingCallback);
6965 }
6966 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006967 }
6968 };
6969 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006970 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006971 broadcastIntentLocked(null, null, intent, null, finisher,
6972 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006973 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006974 mWaitingUpdate = true;
6975 }
6976 }
6977 }
6978 if (mWaitingUpdate) {
6979 return;
6980 }
6981 mDidUpdate = true;
6982 }
6983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984 mSystemReady = true;
6985 if (!mStartRunning) {
6986 return;
6987 }
6988 }
6989
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006990 ArrayList<ProcessRecord> procsToKill = null;
6991 synchronized(mPidsSelfLocked) {
6992 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6993 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6994 if (!isAllowedWhileBooting(proc.info)){
6995 if (procsToKill == null) {
6996 procsToKill = new ArrayList<ProcessRecord>();
6997 }
6998 procsToKill.add(proc);
6999 }
7000 }
7001 }
7002
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007003 synchronized(this) {
7004 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007005 for (int i=procsToKill.size()-1; i>=0; i--) {
7006 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007007 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007008 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007009 }
7010 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007011
7012 // Now that we have cleaned up any update processes, we
7013 // are ready to start launching real processes and know that
7014 // we won't trample on them any more.
7015 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007016 }
7017
Joe Onorato8a9b2202010-02-26 18:56:32 -08007018 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007019 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007020 SystemClock.uptimeMillis());
7021
7022 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007023 // Make sure we have no pre-ready processes sitting around.
7024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7026 ResolveInfo ri = mContext.getPackageManager()
7027 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007028 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 CharSequence errorMsg = null;
7030 if (ri != null) {
7031 ActivityInfo ai = ri.activityInfo;
7032 ApplicationInfo app = ai.applicationInfo;
7033 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7034 mTopAction = Intent.ACTION_FACTORY_TEST;
7035 mTopData = null;
7036 mTopComponent = new ComponentName(app.packageName,
7037 ai.name);
7038 } else {
7039 errorMsg = mContext.getResources().getText(
7040 com.android.internal.R.string.factorytest_not_system);
7041 }
7042 } else {
7043 errorMsg = mContext.getResources().getText(
7044 com.android.internal.R.string.factorytest_no_action);
7045 }
7046 if (errorMsg != null) {
7047 mTopAction = null;
7048 mTopData = null;
7049 mTopComponent = null;
7050 Message msg = Message.obtain();
7051 msg.what = SHOW_FACTORY_ERROR_MSG;
7052 msg.getData().putCharSequence("msg", errorMsg);
7053 mHandler.sendMessage(msg);
7054 }
7055 }
7056 }
7057
7058 retrieveSettings();
7059
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007060 if (goingCallback != null) goingCallback.run();
7061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007062 synchronized (this) {
7063 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7064 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007065 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007066 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 if (apps != null) {
7068 int N = apps.size();
7069 int i;
7070 for (i=0; i<N; i++) {
7071 ApplicationInfo info
7072 = (ApplicationInfo)apps.get(i);
7073 if (info != null &&
7074 !info.packageName.equals("android")) {
7075 addAppLocked(info);
7076 }
7077 }
7078 }
7079 } catch (RemoteException ex) {
7080 // pm is in same process, this will never happen.
7081 }
7082 }
7083
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007084 // Start up initial activity.
7085 mBooting = true;
7086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007087 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007088 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007089 Message msg = Message.obtain();
7090 msg.what = SHOW_UID_ERROR_MSG;
7091 mHandler.sendMessage(msg);
7092 }
7093 } catch (RemoteException e) {
7094 }
7095
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007096 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007097 }
7098 }
7099
Dan Egnorb7f03672009-12-09 16:22:32 -08007100 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007101 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007102 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007103 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007104 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007105 startAppProblemLocked(app);
7106 app.stopFreezingAllLocked();
7107 return handleAppCrashLocked(app);
7108 }
7109
Dan Egnorb7f03672009-12-09 16:22:32 -08007110 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007111 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007112 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007113 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007114 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7115 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 startAppProblemLocked(app);
7117 app.stopFreezingAllLocked();
7118 }
7119
7120 /**
7121 * Generate a process error record, suitable for attachment to a ProcessRecord.
7122 *
7123 * @param app The ProcessRecord in which the error occurred.
7124 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7125 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007126 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007127 * @param shortMsg Short message describing the crash.
7128 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007129 * @param stackTrace Full crash stack trace, may be null.
7130 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007131 * @return Returns a fully-formed AppErrorStateInfo record.
7132 */
7133 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007134 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007135 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007137 report.condition = condition;
7138 report.processName = app.processName;
7139 report.pid = app.pid;
7140 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007141 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007142 report.shortMsg = shortMsg;
7143 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007144 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145
7146 return report;
7147 }
7148
Dan Egnor42471dd2010-01-07 17:25:22 -08007149 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007150 synchronized (this) {
7151 app.crashing = false;
7152 app.crashingReport = null;
7153 app.notResponding = false;
7154 app.notRespondingReport = null;
7155 if (app.anrDialog == fromDialog) {
7156 app.anrDialog = null;
7157 }
7158 if (app.waitDialog == fromDialog) {
7159 app.waitDialog = null;
7160 }
7161 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007162 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007163 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007164 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7165 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007166 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007168 }
7169 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007170
Dan Egnorb7f03672009-12-09 16:22:32 -08007171 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007172 long now = SystemClock.uptimeMillis();
7173
7174 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7175 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007176 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007177 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007178 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007179 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007180 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007181 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007182 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7183 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007185 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007186 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007187 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 }
7189 }
7190 if (!app.persistent) {
7191 // We don't want to start this process again until the user
7192 // explicitly does so... but for persistent process, we really
7193 // need to keep it running. If a persistent process is actually
7194 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007195 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007196 app.info.processName);
7197 mBadProcesses.put(app.info.processName, app.info.uid, now);
7198 app.bad = true;
7199 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7200 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007201 // Don't let services in this process be restarted and potentially
7202 // annoy the user repeatedly. Unless it is persistent, since those
7203 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007204 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007205 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007206 return false;
7207 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007208 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007209 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007210 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007211 if (r.app == app) {
7212 // If the top running activity is from this crashing
7213 // process, then terminate it to avoid getting in a loop.
7214 Slog.w(TAG, " Force finishing activity "
7215 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007216 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007217 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007218 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007219 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007220 // stopped, to avoid a situation where one will get
7221 // re-start our crashing activity once it gets resumed again.
7222 index--;
7223 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007224 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007225 if (r.state == ActivityState.RESUMED
7226 || r.state == ActivityState.PAUSING
7227 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007228 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007229 Slog.w(TAG, " Force finishing activity "
7230 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007231 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007232 Activity.RESULT_CANCELED, null, "crashed");
7233 }
7234 }
7235 }
7236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 }
7238
7239 // Bump up the crash count of any services currently running in the proc.
7240 if (app.services.size() != 0) {
7241 // Any services running in the application need to be placed
7242 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007243 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007244 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007245 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007246 sr.crashCount++;
7247 }
7248 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007249
7250 // If the crashing process is what we consider to be the "home process" and it has been
7251 // replaced by a third-party app, clear the package preferred activities from packages
7252 // with a home activity running in the process to prevent a repeatedly crashing app
7253 // from blocking the user to manually clear the list.
7254 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7255 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7256 Iterator it = mHomeProcess.activities.iterator();
7257 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007258 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007259 if (r.isHomeActivity) {
7260 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7261 try {
7262 ActivityThread.getPackageManager()
7263 .clearPackagePreferredActivities(r.packageName);
7264 } catch (RemoteException c) {
7265 // pm is in same process, this will never happen.
7266 }
7267 }
7268 }
7269 }
7270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007271 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7272 return true;
7273 }
7274
7275 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007276 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7277 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007278 skipCurrentReceiverLocked(app);
7279 }
7280
7281 void skipCurrentReceiverLocked(ProcessRecord app) {
7282 boolean reschedule = false;
7283 BroadcastRecord r = app.curReceiver;
7284 if (r != null) {
7285 // The current broadcast is waiting for this app's receiver
7286 // to be finished. Looks like that's not going to happen, so
7287 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007288 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007289 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7290 r.resultExtras, r.resultAbort, true);
7291 reschedule = true;
7292 }
7293 r = mPendingBroadcast;
7294 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007295 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007296 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007297 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007298 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7299 r.resultExtras, r.resultAbort, true);
7300 reschedule = true;
7301 }
7302 if (reschedule) {
7303 scheduleBroadcastsLocked();
7304 }
7305 }
7306
Dan Egnor60d87622009-12-16 16:32:58 -08007307 /**
7308 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7309 * The application process will exit immediately after this call returns.
7310 * @param app object of the crashing app, null for the system server
7311 * @param crashInfo describing the exception
7312 */
7313 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007314 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007315 final String processName = app == null ? "system_server"
7316 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007317
7318 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007319 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007320 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007321 crashInfo.exceptionClassName,
7322 crashInfo.exceptionMessage,
7323 crashInfo.throwFileName,
7324 crashInfo.throwLineNumber);
7325
Jeff Sharkeya353d262011-10-28 11:12:06 -07007326 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007327
7328 crashApplication(r, crashInfo);
7329 }
7330
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007331 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007332 IBinder app,
7333 int violationMask,
7334 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007335 ProcessRecord r = findAppProcess(app, "StrictMode");
7336 if (r == null) {
7337 return;
7338 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007339
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007340 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007341 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007342 boolean logIt = true;
7343 synchronized (mAlreadyLoggedViolatedStacks) {
7344 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7345 logIt = false;
7346 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007347 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007348 // the relative pain numbers, without logging all
7349 // the stack traces repeatedly. We'd want to do
7350 // likewise in the client code, which also does
7351 // dup suppression, before the Binder call.
7352 } else {
7353 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7354 mAlreadyLoggedViolatedStacks.clear();
7355 }
7356 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7357 }
7358 }
7359 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007360 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007361 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007362 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007363
7364 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7365 AppErrorResult result = new AppErrorResult();
7366 synchronized (this) {
7367 final long origId = Binder.clearCallingIdentity();
7368
7369 Message msg = Message.obtain();
7370 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7371 HashMap<String, Object> data = new HashMap<String, Object>();
7372 data.put("result", result);
7373 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007374 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007375 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007376 msg.obj = data;
7377 mHandler.sendMessage(msg);
7378
7379 Binder.restoreCallingIdentity(origId);
7380 }
7381 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007382 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007383 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007384 }
7385
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007386 // Depending on the policy in effect, there could be a bunch of
7387 // these in quick succession so we try to batch these together to
7388 // minimize disk writes, number of dropbox entries, and maximize
7389 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007390 private void logStrictModeViolationToDropBox(
7391 ProcessRecord process,
7392 StrictMode.ViolationInfo info) {
7393 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007394 return;
7395 }
7396 final boolean isSystemApp = process == null ||
7397 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7398 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007399 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007400 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7401 final DropBoxManager dbox = (DropBoxManager)
7402 mContext.getSystemService(Context.DROPBOX_SERVICE);
7403
7404 // Exit early if the dropbox isn't configured to accept this report type.
7405 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7406
7407 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007408 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007409 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7410 synchronized (sb) {
7411 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007412 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007413 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7414 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007415 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7416 if (info.violationNumThisLoop != 0) {
7417 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7418 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007419 if (info.numAnimationsRunning != 0) {
7420 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7421 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007422 if (info.broadcastIntentAction != null) {
7423 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7424 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007425 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007426 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007427 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007428 if (info.numInstances != -1) {
7429 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7430 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007431 if (info.tags != null) {
7432 for (String tag : info.tags) {
7433 sb.append("Span-Tag: ").append(tag).append("\n");
7434 }
7435 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007436 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007437 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7438 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007439 }
7440 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007441
7442 // Only buffer up to ~64k. Various logging bits truncate
7443 // things at 128k.
7444 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007445 }
7446
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007447 // Flush immediately if the buffer's grown too large, or this
7448 // is a non-system app. Non-system apps are isolated with a
7449 // different tag & policy and not batched.
7450 //
7451 // Batching is useful during internal testing with
7452 // StrictMode settings turned up high. Without batching,
7453 // thousands of separate files could be created on boot.
7454 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007455 new Thread("Error dump: " + dropboxTag) {
7456 @Override
7457 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007458 String report;
7459 synchronized (sb) {
7460 report = sb.toString();
7461 sb.delete(0, sb.length());
7462 sb.trimToSize();
7463 }
7464 if (report.length() != 0) {
7465 dbox.addText(dropboxTag, report);
7466 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007467 }
7468 }.start();
7469 return;
7470 }
7471
7472 // System app batching:
7473 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007474 // An existing dropbox-writing thread is outstanding, so
7475 // we don't need to start it up. The existing thread will
7476 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007477 return;
7478 }
7479
7480 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7481 // (After this point, we shouldn't access AMS internal data structures.)
7482 new Thread("Error dump: " + dropboxTag) {
7483 @Override
7484 public void run() {
7485 // 5 second sleep to let stacks arrive and be batched together
7486 try {
7487 Thread.sleep(5000); // 5 seconds
7488 } catch (InterruptedException e) {}
7489
7490 String errorReport;
7491 synchronized (mStrictModeBuffer) {
7492 errorReport = mStrictModeBuffer.toString();
7493 if (errorReport.length() == 0) {
7494 return;
7495 }
7496 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7497 mStrictModeBuffer.trimToSize();
7498 }
7499 dbox.addText(dropboxTag, errorReport);
7500 }
7501 }.start();
7502 }
7503
Dan Egnor60d87622009-12-16 16:32:58 -08007504 /**
7505 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7506 * @param app object of the crashing app, null for the system server
7507 * @param tag reported by the caller
7508 * @param crashInfo describing the context of the error
7509 * @return true if the process should exit immediately (WTF is fatal)
7510 */
7511 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007512 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007513 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007514 final String processName = app == null ? "system_server"
7515 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007516
7517 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007518 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007519 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007520 tag, crashInfo.exceptionMessage);
7521
Jeff Sharkeya353d262011-10-28 11:12:06 -07007522 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007523
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007524 if (r != null && r.pid != Process.myPid() &&
7525 Settings.Secure.getInt(mContext.getContentResolver(),
7526 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007527 crashApplication(r, crashInfo);
7528 return true;
7529 } else {
7530 return false;
7531 }
7532 }
7533
7534 /**
7535 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7536 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7537 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007538 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007539 if (app == null) {
7540 return null;
7541 }
7542
7543 synchronized (this) {
7544 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7545 final int NA = apps.size();
7546 for (int ia=0; ia<NA; ia++) {
7547 ProcessRecord p = apps.valueAt(ia);
7548 if (p.thread != null && p.thread.asBinder() == app) {
7549 return p;
7550 }
7551 }
7552 }
7553
Dianne Hackborncb44d962011-03-10 17:02:27 -08007554 Slog.w(TAG, "Can't find mystery application for " + reason
7555 + " from pid=" + Binder.getCallingPid()
7556 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007557 return null;
7558 }
7559 }
7560
7561 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007562 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7563 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007564 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007565 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7566 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007567 // Watchdog thread ends up invoking this function (with
7568 // a null ProcessRecord) to add the stack file to dropbox.
7569 // Do not acquire a lock on this (am) in such cases, as it
7570 // could cause a potential deadlock, if and when watchdog
7571 // is invoked due to unavailability of lock on am and it
7572 // would prevent watchdog from killing system_server.
7573 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007574 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007575 return;
7576 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007577 // Note: ProcessRecord 'process' is guarded by the service
7578 // instance. (notably process.pkgList, which could otherwise change
7579 // concurrently during execution of this method)
7580 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007581 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007582 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007583 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007584 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7585 for (String pkg : process.pkgList) {
7586 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007587 try {
Dan Egnora455d192010-03-12 08:52:28 -08007588 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7589 if (pi != null) {
7590 sb.append(" v").append(pi.versionCode);
7591 if (pi.versionName != null) {
7592 sb.append(" (").append(pi.versionName).append(")");
7593 }
7594 }
7595 } catch (RemoteException e) {
7596 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007597 }
Dan Egnora455d192010-03-12 08:52:28 -08007598 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007599 }
Dan Egnora455d192010-03-12 08:52:28 -08007600 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007601 }
7602
7603 private static String processClass(ProcessRecord process) {
7604 if (process == null || process.pid == MY_PID) {
7605 return "system_server";
7606 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7607 return "system_app";
7608 } else {
7609 return "data_app";
7610 }
7611 }
7612
7613 /**
7614 * Write a description of an error (crash, WTF, ANR) to the drop box.
7615 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7616 * @param process which caused the error, null means the system server
7617 * @param activity which triggered the error, null if unknown
7618 * @param parent activity related to the error, null if unknown
7619 * @param subject line related to the error, null if absent
7620 * @param report in long form describing the error, null if absent
7621 * @param logFile to include in the report, null if none
7622 * @param crashInfo giving an application stack trace, null if absent
7623 */
7624 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007625 ProcessRecord process, String processName, ActivityRecord activity,
7626 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007627 final String report, final File logFile,
7628 final ApplicationErrorReport.CrashInfo crashInfo) {
7629 // NOTE -- this must never acquire the ActivityManagerService lock,
7630 // otherwise the watchdog may be prevented from resetting the system.
7631
7632 final String dropboxTag = processClass(process) + "_" + eventType;
7633 final DropBoxManager dbox = (DropBoxManager)
7634 mContext.getSystemService(Context.DROPBOX_SERVICE);
7635
7636 // Exit early if the dropbox isn't configured to accept this report type.
7637 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7638
7639 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007640 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007641 if (activity != null) {
7642 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7643 }
7644 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7645 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7646 }
7647 if (parent != null && parent != activity) {
7648 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7649 }
7650 if (subject != null) {
7651 sb.append("Subject: ").append(subject).append("\n");
7652 }
7653 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007654 if (Debug.isDebuggerConnected()) {
7655 sb.append("Debugger: Connected\n");
7656 }
Dan Egnora455d192010-03-12 08:52:28 -08007657 sb.append("\n");
7658
7659 // Do the rest in a worker thread to avoid blocking the caller on I/O
7660 // (After this point, we shouldn't access AMS internal data structures.)
7661 Thread worker = new Thread("Error dump: " + dropboxTag) {
7662 @Override
7663 public void run() {
7664 if (report != null) {
7665 sb.append(report);
7666 }
7667 if (logFile != null) {
7668 try {
7669 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7670 } catch (IOException e) {
7671 Slog.e(TAG, "Error reading " + logFile, e);
7672 }
7673 }
7674 if (crashInfo != null && crashInfo.stackTrace != null) {
7675 sb.append(crashInfo.stackTrace);
7676 }
7677
7678 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7679 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7680 if (lines > 0) {
7681 sb.append("\n");
7682
7683 // Merge several logcat streams, and take the last N lines
7684 InputStreamReader input = null;
7685 try {
7686 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7687 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7688 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7689
7690 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7691 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7692 input = new InputStreamReader(logcat.getInputStream());
7693
7694 int num;
7695 char[] buf = new char[8192];
7696 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7697 } catch (IOException e) {
7698 Slog.e(TAG, "Error running logcat", e);
7699 } finally {
7700 if (input != null) try { input.close(); } catch (IOException e) {}
7701 }
7702 }
7703
7704 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007705 }
Dan Egnora455d192010-03-12 08:52:28 -08007706 };
7707
7708 if (process == null || process.pid == MY_PID) {
7709 worker.run(); // We may be about to die -- need to run this synchronously
7710 } else {
7711 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007712 }
7713 }
7714
7715 /**
7716 * Bring up the "unexpected error" dialog box for a crashing app.
7717 * Deal with edge cases (intercepts from instrumented applications,
7718 * ActivityController, error intent receivers, that sort of thing).
7719 * @param r the application crashing
7720 * @param crashInfo describing the failure
7721 */
7722 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007723 long timeMillis = System.currentTimeMillis();
7724 String shortMsg = crashInfo.exceptionClassName;
7725 String longMsg = crashInfo.exceptionMessage;
7726 String stackTrace = crashInfo.stackTrace;
7727 if (shortMsg != null && longMsg != null) {
7728 longMsg = shortMsg + ": " + longMsg;
7729 } else if (shortMsg != null) {
7730 longMsg = shortMsg;
7731 }
7732
Dan Egnor60d87622009-12-16 16:32:58 -08007733 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007734 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007735 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 try {
7737 String name = r != null ? r.processName : null;
7738 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007739 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007740 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007741 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742 + " at watcher's request");
7743 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007744 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 }
7746 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007747 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007748 }
7749 }
7750
7751 final long origId = Binder.clearCallingIdentity();
7752
7753 // If this process is running instrumentation, finish it.
7754 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007755 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007756 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007757 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7758 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007759 Bundle info = new Bundle();
7760 info.putString("shortMsg", shortMsg);
7761 info.putString("longMsg", longMsg);
7762 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7763 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007764 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007765 }
7766
Dan Egnor60d87622009-12-16 16:32:58 -08007767 // If we can't identify the process or it's already exceeded its crash quota,
7768 // quit right away without showing a crash dialog.
7769 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007771 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772 }
7773
7774 Message msg = Message.obtain();
7775 msg.what = SHOW_ERROR_MSG;
7776 HashMap data = new HashMap();
7777 data.put("result", result);
7778 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007779 msg.obj = data;
7780 mHandler.sendMessage(msg);
7781
7782 Binder.restoreCallingIdentity(origId);
7783 }
7784
7785 int res = result.get();
7786
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007787 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007788 synchronized (this) {
7789 if (r != null) {
7790 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7791 SystemClock.uptimeMillis());
7792 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007793 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007794 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007795 }
7796 }
7797
7798 if (appErrorIntent != null) {
7799 try {
7800 mContext.startActivity(appErrorIntent);
7801 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007802 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007803 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007805 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007806
7807 Intent createAppErrorIntentLocked(ProcessRecord r,
7808 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7809 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007810 if (report == null) {
7811 return null;
7812 }
7813 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7814 result.setComponent(r.errorReportReceiver);
7815 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7816 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7817 return result;
7818 }
7819
Dan Egnorb7f03672009-12-09 16:22:32 -08007820 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7821 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007822 if (r.errorReportReceiver == null) {
7823 return null;
7824 }
7825
7826 if (!r.crashing && !r.notResponding) {
7827 return null;
7828 }
7829
Dan Egnorb7f03672009-12-09 16:22:32 -08007830 ApplicationErrorReport report = new ApplicationErrorReport();
7831 report.packageName = r.info.packageName;
7832 report.installerPackageName = r.errorReportReceiver.getPackageName();
7833 report.processName = r.processName;
7834 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007835 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007836
Dan Egnorb7f03672009-12-09 16:22:32 -08007837 if (r.crashing) {
7838 report.type = ApplicationErrorReport.TYPE_CRASH;
7839 report.crashInfo = crashInfo;
7840 } else if (r.notResponding) {
7841 report.type = ApplicationErrorReport.TYPE_ANR;
7842 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007843
Dan Egnorb7f03672009-12-09 16:22:32 -08007844 report.anrInfo.activity = r.notRespondingReport.tag;
7845 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7846 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007847 }
7848
Dan Egnorb7f03672009-12-09 16:22:32 -08007849 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007850 }
7851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007852 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7853 // assume our apps are happy - lazy create the list
7854 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7855
7856 synchronized (this) {
7857
7858 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007859 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7860 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007861 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7862 // This one's in trouble, so we'll generate a report for it
7863 // crashes are higher priority (in case there's a crash *and* an anr)
7864 ActivityManager.ProcessErrorStateInfo report = null;
7865 if (app.crashing) {
7866 report = app.crashingReport;
7867 } else if (app.notResponding) {
7868 report = app.notRespondingReport;
7869 }
7870
7871 if (report != null) {
7872 if (errList == null) {
7873 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7874 }
7875 errList.add(report);
7876 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007877 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007878 " crashing = " + app.crashing +
7879 " notResponding = " + app.notResponding);
7880 }
7881 }
7882 }
7883 }
7884
7885 return errList;
7886 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007887
7888 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007889 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007890 if (currApp != null) {
7891 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7892 }
7893 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007894 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7895 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007896 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7897 if (currApp != null) {
7898 currApp.lru = 0;
7899 }
7900 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007901 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007902 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7903 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7904 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7905 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7906 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7907 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7908 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7909 } else {
7910 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7911 }
7912 }
7913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007914 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7915 // Lazy instantiation of list
7916 List<ActivityManager.RunningAppProcessInfo> runList = null;
7917 synchronized (this) {
7918 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007919 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7920 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7922 // Generate process state info for running application
7923 ActivityManager.RunningAppProcessInfo currApp =
7924 new ActivityManager.RunningAppProcessInfo(app.processName,
7925 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007926 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007927 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007928 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007929 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007930 if (app.persistent) {
7931 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007934 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007935 currApp.importanceReasonCode = app.adjTypeCode;
7936 if (app.adjSource instanceof ProcessRecord) {
7937 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007938 currApp.importanceReasonImportance = oomAdjToImportance(
7939 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007940 } else if (app.adjSource instanceof ActivityRecord) {
7941 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007942 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7943 }
7944 if (app.adjTarget instanceof ComponentName) {
7945 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7946 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007947 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948 // + " lru=" + currApp.lru);
7949 if (runList == null) {
7950 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7951 }
7952 runList.add(currApp);
7953 }
7954 }
7955 }
7956 return runList;
7957 }
7958
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007959 public List<ApplicationInfo> getRunningExternalApplications() {
7960 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7961 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7962 if (runningApps != null && runningApps.size() > 0) {
7963 Set<String> extList = new HashSet<String>();
7964 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7965 if (app.pkgList != null) {
7966 for (String pkg : app.pkgList) {
7967 extList.add(pkg);
7968 }
7969 }
7970 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007971 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007972 for (String pkg : extList) {
7973 try {
7974 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7975 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7976 retList.add(info);
7977 }
7978 } catch (RemoteException e) {
7979 }
7980 }
7981 }
7982 return retList;
7983 }
7984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985 @Override
7986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007987 if (checkCallingPermission(android.Manifest.permission.DUMP)
7988 != PackageManager.PERMISSION_GRANTED) {
7989 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7990 + Binder.getCallingPid()
7991 + ", uid=" + Binder.getCallingUid()
7992 + " without permission "
7993 + android.Manifest.permission.DUMP);
7994 return;
7995 }
7996
7997 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007998 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007999 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008000
8001 int opti = 0;
8002 while (opti < args.length) {
8003 String opt = args[opti];
8004 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8005 break;
8006 }
8007 opti++;
8008 if ("-a".equals(opt)) {
8009 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008010 } else if ("-c".equals(opt)) {
8011 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008012 } else if ("-h".equals(opt)) {
8013 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008014 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008015 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008016 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008017 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8018 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8019 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008020 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008021 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
8022 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008023 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008024 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008025 pw.println(" all: dump all activities");
8026 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008027 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008028 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8029 pw.println(" a partial substring in a component name, a");
8030 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008031 pw.println(" -a: include all available server state.");
8032 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008033 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008034 } else {
8035 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008037 }
8038
8039 // Is the caller requesting to dump a particular piece of data?
8040 if (opti < args.length) {
8041 String cmd = args[opti];
8042 opti++;
8043 if ("activities".equals(cmd) || "a".equals(cmd)) {
8044 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008045 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008046 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008047 return;
8048 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008049 String[] newArgs;
8050 String name;
8051 if (opti >= args.length) {
8052 name = null;
8053 newArgs = EMPTY_STRING_ARRAY;
8054 } else {
8055 name = args[opti];
8056 opti++;
8057 newArgs = new String[args.length - opti];
8058 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8059 args.length - opti);
8060 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008061 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008062 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008063 }
8064 return;
8065 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008066 String[] newArgs;
8067 String name;
8068 if (opti >= args.length) {
8069 name = null;
8070 newArgs = EMPTY_STRING_ARRAY;
8071 } else {
8072 name = args[opti];
8073 opti++;
8074 newArgs = new String[args.length - opti];
8075 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8076 args.length - opti);
8077 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008078 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008079 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008080 }
8081 return;
8082 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008083 String[] newArgs;
8084 String name;
8085 if (opti >= args.length) {
8086 name = null;
8087 newArgs = EMPTY_STRING_ARRAY;
8088 } else {
8089 name = args[opti];
8090 opti++;
8091 newArgs = new String[args.length - opti];
8092 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8093 args.length - opti);
8094 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008095 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008096 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008097 }
8098 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008099 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8100 synchronized (this) {
8101 dumpOomLocked(fd, pw, args, opti, true);
8102 }
8103 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008104 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8105 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008106 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008107 }
8108 return;
8109 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008110 String[] newArgs;
8111 String name;
8112 if (opti >= args.length) {
8113 name = null;
8114 newArgs = EMPTY_STRING_ARRAY;
8115 } else {
8116 name = args[opti];
8117 opti++;
8118 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008119 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8120 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008121 }
8122 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8123 pw.println("No services match: " + name);
8124 pw.println("Use -h for help.");
8125 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008126 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008127 } else if ("package".equals(cmd)) {
8128 String[] newArgs;
8129 if (opti >= args.length) {
8130 pw.println("package: no package name specified");
8131 pw.println("Use -h for help.");
8132 return;
8133 } else {
8134 dumpPackage = args[opti];
8135 opti++;
8136 newArgs = new String[args.length - opti];
8137 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8138 args.length - opti);
8139 args = newArgs;
8140 opti = 0;
8141 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008142 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8143 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008144 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008145 }
8146 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008147 } else {
8148 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008149 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8150 pw.println("Bad activity command, or no activities match: " + cmd);
8151 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008152 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008153 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008155 }
8156
8157 // No piece of data specified, dump everything.
8158 synchronized (this) {
8159 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008160 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008161 if (needSep) {
8162 pw.println(" ");
8163 }
8164 if (dumpAll) {
8165 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008166 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008167 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008168 if (needSep) {
8169 pw.println(" ");
8170 }
8171 if (dumpAll) {
8172 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008173 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008174 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008175 if (needSep) {
8176 pw.println(" ");
8177 }
8178 if (dumpAll) {
8179 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008180 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008181 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008182 if (needSep) {
8183 pw.println(" ");
8184 }
8185 if (dumpAll) {
8186 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008187 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008188 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008189 if (needSep) {
8190 pw.println(" ");
8191 }
8192 if (dumpAll) {
8193 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008194 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008195 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008196 }
8197 }
8198
8199 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008200 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008201 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8202 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008203 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8204 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008205 pw.println(" ");
8206 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008207 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8208 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008209 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008210 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008211 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008212 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008213 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008214 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008215 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008217 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008218 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008219 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008220 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008221 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8222 pw.println(" ");
8223 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008224 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008225 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008226 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008227 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008228 pw.println(" ");
8229 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008230 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008231 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008233
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008234 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008235 if (mMainStack.mPausingActivity != null) {
8236 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8237 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008238 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008239 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008240 if (dumpAll) {
8241 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8242 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008243 pw.println(" mDismissKeyguardOnNextActivity: "
8244 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008246
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008247 if (mRecentTasks.size() > 0) {
8248 pw.println();
8249 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008250
8251 final int N = mRecentTasks.size();
8252 for (int i=0; i<N; i++) {
8253 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008254 if (dumpPackage != null) {
8255 if (tr.realActivity == null ||
8256 !dumpPackage.equals(tr.realActivity)) {
8257 continue;
8258 }
8259 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008260 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8261 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008262 if (dumpAll) {
8263 mRecentTasks.get(i).dump(pw, " ");
8264 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008265 }
8266 }
8267
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008268 if (dumpAll) {
8269 pw.println(" ");
8270 pw.println(" mCurTask: " + mCurTask);
8271 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008272
8273 return true;
8274 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008275
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008276 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008277 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008278 boolean needSep = false;
8279 int numPers = 0;
8280
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008281 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8282
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008283 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008284 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8285 final int NA = procs.size();
8286 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008287 ProcessRecord r = procs.valueAt(ia);
8288 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8289 continue;
8290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008291 if (!needSep) {
8292 pw.println(" All known processes:");
8293 needSep = true;
8294 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008295 pw.print(r.persistent ? " *PERS*" : " *APP*");
8296 pw.print(" UID "); pw.print(procs.keyAt(ia));
8297 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 r.dump(pw, " ");
8299 if (r.persistent) {
8300 numPers++;
8301 }
8302 }
8303 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008304 }
8305
8306 if (mLruProcesses.size() > 0) {
8307 if (needSep) pw.println(" ");
8308 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008309 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008310 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008311 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008312 needSep = true;
8313 }
8314
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008315 if (dumpAll) {
8316 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008317 boolean printed = false;
8318 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8319 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8320 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8321 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008322 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008323 if (!printed) {
8324 if (needSep) pw.println(" ");
8325 needSep = true;
8326 pw.println(" PID mappings:");
8327 printed = true;
8328 }
8329 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8330 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008331 }
8332 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008333 }
8334
8335 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008336 synchronized (mPidsSelfLocked) {
8337 boolean printed = false;
8338 for (int i=0; i<mForegroundProcesses.size(); i++) {
8339 ProcessRecord r = mPidsSelfLocked.get(
8340 mForegroundProcesses.valueAt(i).pid);
8341 if (dumpPackage != null && (r == null
8342 || !dumpPackage.equals(r.info.packageName))) {
8343 continue;
8344 }
8345 if (!printed) {
8346 if (needSep) pw.println(" ");
8347 needSep = true;
8348 pw.println(" Foreground Processes:");
8349 printed = true;
8350 }
8351 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8352 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008354 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008355 }
8356
8357 if (mPersistentStartingProcesses.size() > 0) {
8358 if (needSep) pw.println(" ");
8359 needSep = true;
8360 pw.println(" Persisent processes that are starting:");
8361 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008362 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008363 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008364
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008365 if (mRemovedProcesses.size() > 0) {
8366 if (needSep) pw.println(" ");
8367 needSep = true;
8368 pw.println(" Processes that are being removed:");
8369 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008370 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008371 }
8372
8373 if (mProcessesOnHold.size() > 0) {
8374 if (needSep) pw.println(" ");
8375 needSep = true;
8376 pw.println(" Processes that are on old until the system is ready:");
8377 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008378 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008379 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008380
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008381 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008382
8383 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008384 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008385 long now = SystemClock.uptimeMillis();
8386 for (Map.Entry<String, SparseArray<Long>> procs
8387 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008388 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008389 SparseArray<Long> uids = procs.getValue();
8390 final int N = uids.size();
8391 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008392 int puid = uids.keyAt(i);
8393 ProcessRecord r = mProcessNames.get(pname, puid);
8394 if (dumpPackage != null && (r == null
8395 || !dumpPackage.equals(r.info.packageName))) {
8396 continue;
8397 }
8398 if (!printed) {
8399 if (needSep) pw.println(" ");
8400 needSep = true;
8401 pw.println(" Time since processes crashed:");
8402 printed = true;
8403 }
8404 pw.print(" Process "); pw.print(pname);
8405 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008406 pw.print(": last crashed ");
8407 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008408 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008409 }
8410 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008413 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008414 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008415 for (Map.Entry<String, SparseArray<Long>> procs
8416 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008417 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008418 SparseArray<Long> uids = procs.getValue();
8419 final int N = uids.size();
8420 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008421 int puid = uids.keyAt(i);
8422 ProcessRecord r = mProcessNames.get(pname, puid);
8423 if (dumpPackage != null && (r == null
8424 || !dumpPackage.equals(r.info.packageName))) {
8425 continue;
8426 }
8427 if (!printed) {
8428 if (needSep) pw.println(" ");
8429 needSep = true;
8430 pw.println(" Bad processes:");
8431 }
8432 pw.print(" Bad process "); pw.print(pname);
8433 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008434 pw.print(": crashed at time ");
8435 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008436 }
8437 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008439
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008440 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008441 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008442 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08008443 if (dumpAll) {
8444 StringBuilder sb = new StringBuilder(128);
8445 sb.append(" mPreviousProcessVisibleTime: ");
8446 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8447 pw.println(sb);
8448 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07008449 if (mHeavyWeightProcess != null) {
8450 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8451 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008452 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008453 if (dumpAll) {
8454 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008455 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008456 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008457 for (Map.Entry<String, Integer> entry
8458 : mCompatModePackages.getPackages().entrySet()) {
8459 String pkg = entry.getKey();
8460 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008461 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8462 continue;
8463 }
8464 if (!printed) {
8465 pw.println(" mScreenCompatPackages:");
8466 printed = true;
8467 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008468 pw.print(" "); pw.print(pkg); pw.print(": ");
8469 pw.print(mode); pw.println();
8470 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008471 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008472 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008473 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8474 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8475 || mOrigWaitForDebugger) {
8476 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8477 + " mDebugTransient=" + mDebugTransient
8478 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8479 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008480 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8481 || mProfileFd != null) {
8482 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8483 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8484 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8485 + mAutoStopProfiler);
8486 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008487 if (mAlwaysFinishActivities || mController != null) {
8488 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8489 + " mController=" + mController);
8490 }
8491 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008492 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008493 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008494 + " mProcessesReady=" + mProcessesReady
8495 + " mSystemReady=" + mSystemReady);
8496 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008497 + " mBooted=" + mBooted
8498 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008499 pw.print(" mLastPowerCheckRealtime=");
8500 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8501 pw.println("");
8502 pw.print(" mLastPowerCheckUptime=");
8503 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8504 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008505 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8506 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008507 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008508 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8509 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008511
8512 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 }
8514
Dianne Hackborn287952c2010-09-22 22:34:31 -07008515 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008516 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008517 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008518 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008519 long now = SystemClock.uptimeMillis();
8520 for (int i=0; i<mProcessesToGc.size(); i++) {
8521 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008522 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8523 continue;
8524 }
8525 if (!printed) {
8526 if (needSep) pw.println(" ");
8527 needSep = true;
8528 pw.println(" Processes that are waiting to GC:");
8529 printed = true;
8530 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008531 pw.print(" Process "); pw.println(proc);
8532 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8533 pw.print(", last gced=");
8534 pw.print(now-proc.lastRequestedGc);
8535 pw.print(" ms ago, last lowMem=");
8536 pw.print(now-proc.lastLowMemory);
8537 pw.println(" ms ago");
8538
8539 }
8540 }
8541 return needSep;
8542 }
8543
8544 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8545 int opti, boolean dumpAll) {
8546 boolean needSep = false;
8547
8548 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008549 if (needSep) pw.println(" ");
8550 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008551 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008552 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008553 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008554 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8555 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8556 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8557 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8558 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008559 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008560 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008561 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008562 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008563 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008564 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008565
8566 if (needSep) pw.println(" ");
8567 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008568 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008569 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008570 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008571 needSep = true;
8572 }
8573
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008574 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008575
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008576 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008577 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008578 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008579 if (mHeavyWeightProcess != null) {
8580 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8581 }
8582
8583 return true;
8584 }
8585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 /**
8587 * There are three ways to call this:
8588 * - no service specified: dump all the services
8589 * - a flattened component name that matched an existing service was specified as the
8590 * first arg: dump that one service
8591 * - the first arg isn't the flattened component name of an existing service:
8592 * dump all services whose component contains the first arg as a substring
8593 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008594 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8595 int opti, boolean dumpAll) {
8596 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008598 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008599 synchronized (this) {
8600 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008601 services.add(r1);
8602 }
8603 }
8604 } else {
8605 ComponentName componentName = name != null
8606 ? ComponentName.unflattenFromString(name) : null;
8607 int objectId = 0;
8608 if (componentName == null) {
8609 // Not a '/' separated full component name; maybe an object ID?
8610 try {
8611 objectId = Integer.parseInt(name, 16);
8612 name = null;
8613 componentName = null;
8614 } catch (RuntimeException e) {
8615 }
8616 }
8617
8618 synchronized (this) {
8619 for (ServiceRecord r1 : mServices.values()) {
8620 if (componentName != null) {
8621 if (r1.name.equals(componentName)) {
8622 services.add(r1);
8623 }
8624 } else if (name != null) {
8625 if (r1.name.flattenToString().contains(name)) {
8626 services.add(r1);
8627 }
8628 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008629 services.add(r1);
8630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008631 }
8632 }
8633 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008634
8635 if (services.size() <= 0) {
8636 return false;
8637 }
8638
8639 boolean needSep = false;
8640 for (int i=0; i<services.size(); i++) {
8641 if (needSep) {
8642 pw.println();
8643 }
8644 needSep = true;
8645 dumpService("", fd, pw, services.get(i), args, dumpAll);
8646 }
8647 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008648 }
8649
8650 /**
8651 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8652 * there is a thread associated with the service.
8653 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008654 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8655 final ServiceRecord r, String[] args, boolean dumpAll) {
8656 String innerPrefix = prefix + " ";
8657 synchronized (this) {
8658 pw.print(prefix); pw.print("SERVICE ");
8659 pw.print(r.shortName); pw.print(" ");
8660 pw.print(Integer.toHexString(System.identityHashCode(r)));
8661 pw.print(" pid=");
8662 if (r.app != null) pw.println(r.app.pid);
8663 else pw.println("(not running)");
8664 if (dumpAll) {
8665 r.dump(pw, innerPrefix);
8666 }
8667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008668 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008669 pw.print(prefix); pw.println(" Client:");
8670 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008671 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008672 TransferPipe tp = new TransferPipe();
8673 try {
8674 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8675 tp.setBufferPrefix(prefix + " ");
8676 tp.go(fd);
8677 } finally {
8678 tp.kill();
8679 }
8680 } catch (IOException e) {
8681 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008682 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008683 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008684 }
8685 }
8686 }
8687
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008688 static class ItemMatcher {
8689 ArrayList<ComponentName> components;
8690 ArrayList<String> strings;
8691 ArrayList<Integer> objects;
8692 boolean all;
8693
8694 ItemMatcher() {
8695 all = true;
8696 }
8697
8698 void build(String name) {
8699 ComponentName componentName = ComponentName.unflattenFromString(name);
8700 if (componentName != null) {
8701 if (components == null) {
8702 components = new ArrayList<ComponentName>();
8703 }
8704 components.add(componentName);
8705 all = false;
8706 } else {
8707 int objectId = 0;
8708 // Not a '/' separated full component name; maybe an object ID?
8709 try {
8710 objectId = Integer.parseInt(name, 16);
8711 if (objects == null) {
8712 objects = new ArrayList<Integer>();
8713 }
8714 objects.add(objectId);
8715 all = false;
8716 } catch (RuntimeException e) {
8717 // Not an integer; just do string match.
8718 if (strings == null) {
8719 strings = new ArrayList<String>();
8720 }
8721 strings.add(name);
8722 all = false;
8723 }
8724 }
8725 }
8726
8727 int build(String[] args, int opti) {
8728 for (; opti<args.length; opti++) {
8729 String name = args[opti];
8730 if ("--".equals(name)) {
8731 return opti+1;
8732 }
8733 build(name);
8734 }
8735 return opti;
8736 }
8737
8738 boolean match(Object object, ComponentName comp) {
8739 if (all) {
8740 return true;
8741 }
8742 if (components != null) {
8743 for (int i=0; i<components.size(); i++) {
8744 if (components.get(i).equals(comp)) {
8745 return true;
8746 }
8747 }
8748 }
8749 if (objects != null) {
8750 for (int i=0; i<objects.size(); i++) {
8751 if (System.identityHashCode(object) == objects.get(i)) {
8752 return true;
8753 }
8754 }
8755 }
8756 if (strings != null) {
8757 String flat = comp.flattenToString();
8758 for (int i=0; i<strings.size(); i++) {
8759 if (flat.contains(strings.get(i))) {
8760 return true;
8761 }
8762 }
8763 }
8764 return false;
8765 }
8766 }
8767
Dianne Hackborn625ac272010-09-17 18:29:22 -07008768 /**
8769 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008770 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008771 * - the cmd arg isn't the flattened component name of an existing activity:
8772 * dump all activity whose component contains the cmd as a substring
8773 * - A hex number of the ActivityRecord object instance.
8774 */
8775 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8776 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008777 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008778
8779 if ("all".equals(name)) {
8780 synchronized (this) {
8781 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008782 activities.add(r1);
8783 }
8784 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008785 } else if ("top".equals(name)) {
8786 synchronized (this) {
8787 final int N = mMainStack.mHistory.size();
8788 if (N > 0) {
8789 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8790 }
8791 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008792 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008793 ItemMatcher matcher = new ItemMatcher();
8794 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008795
8796 synchronized (this) {
8797 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008798 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008799 activities.add(r1);
8800 }
8801 }
8802 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008803 }
8804
8805 if (activities.size() <= 0) {
8806 return false;
8807 }
8808
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008809 String[] newArgs = new String[args.length - opti];
8810 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8811
Dianne Hackborn30d71892010-12-11 10:37:55 -08008812 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008813 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008814 for (int i=activities.size()-1; i>=0; i--) {
8815 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008816 if (needSep) {
8817 pw.println();
8818 }
8819 needSep = true;
8820 synchronized (this) {
8821 if (lastTask != r.task) {
8822 lastTask = r.task;
8823 pw.print("TASK "); pw.print(lastTask.affinity);
8824 pw.print(" id="); pw.println(lastTask.taskId);
8825 if (dumpAll) {
8826 lastTask.dump(pw, " ");
8827 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008828 }
8829 }
8830 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008831 }
8832 return true;
8833 }
8834
8835 /**
8836 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8837 * there is a thread associated with the activity.
8838 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008839 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008840 final ActivityRecord r, String[] args, boolean dumpAll) {
8841 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008842 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008843 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8844 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8845 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008846 if (r.app != null) pw.println(r.app.pid);
8847 else pw.println("(not running)");
8848 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008849 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008850 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008851 }
8852 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008853 // flush anything that is already in the PrintWriter since the thread is going
8854 // to write to the file descriptor directly
8855 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008856 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008857 TransferPipe tp = new TransferPipe();
8858 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008859 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8860 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 tp.go(fd);
8862 } finally {
8863 tp.kill();
8864 }
8865 } catch (IOException e) {
8866 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008867 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008868 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008869 }
8870 }
8871 }
8872
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008873 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008874 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008875 boolean needSep = false;
8876
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008877 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008878 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008880 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 Iterator it = mRegisteredReceivers.values().iterator();
8882 while (it.hasNext()) {
8883 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008884 if (dumpPackage != null && (r.app == null ||
8885 !dumpPackage.equals(r.app.info.packageName))) {
8886 continue;
8887 }
8888 if (!printed) {
8889 pw.println(" Registered Receivers:");
8890 needSep = true;
8891 printed = true;
8892 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008893 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008894 r.dump(pw, " ");
8895 }
8896 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008897
8898 if (mReceiverResolver.dump(pw, needSep ?
8899 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
8900 " ", dumpPackage, false)) {
8901 needSep = true;
8902 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008903 }
8904
8905 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8906 || mPendingBroadcast != null) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008907 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008908 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008909 BroadcastRecord br = mParallelBroadcasts.get(i);
8910 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8911 continue;
8912 }
8913 if (!printed) {
8914 if (needSep) {
8915 pw.println();
8916 }
8917 needSep = true;
8918 pw.println(" Active broadcasts:");
8919 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008920 pw.println(" Broadcast #" + i + ":");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008921 br.dump(pw, " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008922 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008923 printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008924 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008925 BroadcastRecord br = mOrderedBroadcasts.get(i);
8926 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8927 continue;
8928 }
8929 if (!printed) {
8930 if (needSep) {
8931 pw.println();
8932 }
8933 needSep = true;
8934 pw.println(" Active ordered broadcasts:");
8935 }
8936 pw.println(" Ordered Broadcast #" + i + ":");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008937 mOrderedBroadcasts.get(i).dump(pw, " ");
8938 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008939 if (dumpPackage == null || (mPendingBroadcast != null
8940 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
8941 if (needSep) {
8942 pw.println();
8943 }
8944 pw.println(" Pending broadcast:");
8945 if (mPendingBroadcast != null) {
8946 mPendingBroadcast.dump(pw, " ");
8947 } else {
8948 pw.println(" (null)");
8949 }
8950 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008951 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008953
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008954 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008955 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8956 BroadcastRecord r = mBroadcastHistory[i];
8957 if (r == null) {
8958 break;
8959 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008960 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
8961 continue;
8962 }
8963 if (!printed) {
8964 if (needSep) {
8965 pw.println();
8966 }
8967 needSep = true;
8968 pw.println(" Historical broadcasts:");
8969 printed = true;
8970 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008971 if (dumpAll) {
8972 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8973 r.dump(pw, " ");
8974 } else {
8975 if (i >= 50) {
8976 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008977 break;
8978 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008979 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008980 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008981 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008982 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008983
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008984 if (mStickyBroadcasts != null && dumpPackage == null) {
8985 if (needSep) {
8986 pw.println();
8987 }
8988 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008989 pw.println(" Sticky broadcasts:");
8990 StringBuilder sb = new StringBuilder(128);
8991 for (Map.Entry<String, ArrayList<Intent>> ent
8992 : mStickyBroadcasts.entrySet()) {
8993 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008994 if (dumpAll) {
8995 pw.println(":");
8996 ArrayList<Intent> intents = ent.getValue();
8997 final int N = intents.size();
8998 for (int i=0; i<N; i++) {
8999 sb.setLength(0);
9000 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009001 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009002 pw.println(sb.toString());
9003 Bundle bundle = intents.get(i).getExtras();
9004 if (bundle != null) {
9005 pw.print(" ");
9006 pw.println(bundle.toString());
9007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009009 } else {
9010 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 }
9012 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009013 needSep = true;
9014 }
9015
9016 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009017 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009018 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 pw.println(" mHandler:");
9020 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009021 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009022 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009023
9024 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009025 }
9026
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009027 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009028 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009029 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009030
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009031 ItemMatcher matcher = new ItemMatcher();
9032 matcher.build(args, opti);
9033
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009034 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9035 if (mServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009036 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009037 long nowReal = SystemClock.elapsedRealtime();
9038 Iterator<ServiceRecord> it = mServices.values().iterator();
9039 needSep = false;
9040 while (it.hasNext()) {
9041 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009042 if (!matcher.match(r, r.name)) {
9043 continue;
9044 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009045 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9046 continue;
9047 }
9048 if (!printed) {
9049 pw.println(" Active services:");
9050 printed = true;
9051 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009052 if (needSep) {
9053 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009055 pw.print(" * "); pw.println(r);
9056 if (dumpAll) {
9057 r.dump(pw, " ");
9058 needSep = true;
9059 } else {
9060 pw.print(" app="); pw.println(r.app);
9061 pw.print(" created=");
9062 TimeUtils.formatDuration(r.createTime, nowReal, pw);
9063 pw.print(" started="); pw.print(r.startRequested);
9064 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009065 if (r.connections.size() > 0) {
9066 pw.println(" Connections:");
9067 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9068 for (int i=0; i<clist.size(); i++) {
9069 ConnectionRecord conn = clist.get(i);
9070 pw.print(" ");
9071 pw.print(conn.binding.intent.intent.getIntent().toShortString(
9072 false, false, false));
9073 pw.print(" -> ");
9074 ProcessRecord proc = conn.binding.client;
9075 pw.println(proc != null ? proc.toShortString() : "null");
9076 }
9077 }
9078 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009079 }
9080 if (dumpClient && r.app != null && r.app.thread != null) {
9081 pw.println(" Client:");
9082 pw.flush();
9083 try {
9084 TransferPipe tp = new TransferPipe();
9085 try {
9086 r.app.thread.dumpService(
9087 tp.getWriteFd().getFileDescriptor(), r, args);
9088 tp.setBufferPrefix(" ");
9089 // Short timeout, since blocking here can
9090 // deadlock with the application.
9091 tp.go(fd, 2000);
9092 } finally {
9093 tp.kill();
9094 }
9095 } catch (IOException e) {
9096 pw.println(" Failure while dumping the service: " + e);
9097 } catch (RemoteException e) {
9098 pw.println(" Got a RemoteException while dumping the service");
9099 }
9100 needSep = true;
9101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009102 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009103 needSep = printed;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009105
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009106 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009107 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009108 for (int i=0; i<mPendingServices.size(); i++) {
9109 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009110 if (!matcher.match(r, r.name)) {
9111 continue;
9112 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009113 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9114 continue;
9115 }
9116 if (!printed) {
9117 if (needSep) pw.println(" ");
9118 needSep = true;
9119 pw.println(" Pending services:");
9120 printed = true;
9121 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009122 pw.print(" * Pending "); pw.println(r);
9123 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009124 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009125 needSep = true;
9126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009127
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009128 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009129 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009130 for (int i=0; i<mRestartingServices.size(); i++) {
9131 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009132 if (!matcher.match(r, r.name)) {
9133 continue;
9134 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009135 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9136 continue;
9137 }
9138 if (!printed) {
9139 if (needSep) pw.println(" ");
9140 needSep = true;
9141 pw.println(" Restarting services:");
9142 printed = true;
9143 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009144 pw.print(" * Restarting "); pw.println(r);
9145 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009147 needSep = true;
9148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009149
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009150 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009151 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009152 for (int i=0; i<mStoppingServices.size(); i++) {
9153 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009154 if (!matcher.match(r, r.name)) {
9155 continue;
9156 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009157 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9158 continue;
9159 }
9160 if (!printed) {
9161 if (needSep) pw.println(" ");
9162 needSep = true;
9163 pw.println(" Stopping services:");
9164 printed = true;
9165 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009166 pw.print(" * Stopping "); pw.println(r);
9167 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009168 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009169 needSep = true;
9170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009171
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009172 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009173 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009174 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009175 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009176 = mServiceConnections.values().iterator();
9177 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009178 ArrayList<ConnectionRecord> r = it.next();
9179 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009180 ConnectionRecord cr = r.get(i);
9181 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9182 continue;
9183 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009184 if (dumpPackage != null && (cr.binding.client == null
9185 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9186 continue;
9187 }
9188 if (!printed) {
9189 if (needSep) pw.println(" ");
9190 needSep = true;
9191 pw.println(" Connection bindings to services:");
9192 printed = true;
9193 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009194 pw.print(" * "); pw.println(cr);
9195 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009197 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009198 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009199 }
9200 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009201
9202 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009203 }
9204
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009205 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009206 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009207 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009208
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009209 ItemMatcher matcher = new ItemMatcher();
9210 matcher.build(args, opti);
9211
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009212 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9213 if (mProvidersByClass.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009214 boolean printed = false;
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009215 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009216 = mProvidersByClass.entrySet().iterator();
9217 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009218 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009219 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009220 ComponentName comp = e.getKey();
9221 String cls = comp.getClassName();
9222 int end = cls.lastIndexOf('.');
9223 if (end > 0 && end < (cls.length()-2)) {
9224 cls = cls.substring(end+1);
9225 }
9226 if (!matcher.match(r, comp)) {
9227 continue;
9228 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009229 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9230 continue;
9231 }
9232 if (!printed) {
9233 if (needSep) pw.println(" ");
9234 needSep = true;
9235 pw.println(" Published content providers (by class):");
9236 printed = true;
9237 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009238 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009239 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009240 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009241 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009242 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009243 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009244 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009245 } else {
9246 pw.println();
9247 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009248 if (r.clients.size() > 0) {
9249 pw.println(" Clients:");
9250 for (ProcessRecord cproc : r.clients) {
9251 pw.print(" - "); pw.println(cproc);
9252 }
9253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009256 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009257
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009258 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009259 if (mProvidersByName.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009260 boolean printed = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009261 Iterator<Map.Entry<String, ContentProviderRecord>> it
9262 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009263 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009264 Map.Entry<String, ContentProviderRecord> e = it.next();
9265 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009266 if (!matcher.match(r, r.name)) {
9267 continue;
9268 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009269 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9270 continue;
9271 }
9272 if (!printed) {
9273 if (needSep) pw.println(" ");
9274 needSep = true;
9275 pw.println(" Authority to provider mappings:");
9276 printed = true;
9277 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009278 pw.print(" "); pw.print(e.getKey()); pw.println(":");
9279 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009280 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009283
9284 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009285 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009286 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009287 ContentProviderRecord r = mLaunchingProviders.get(i);
9288 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9289 continue;
9290 }
9291 if (!printed) {
9292 if (needSep) pw.println(" ");
9293 needSep = true;
9294 pw.println(" Launching content providers:");
9295 printed = true;
9296 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009297 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009298 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009299 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009300 }
9301
9302 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009303 if (needSep) pw.println();
9304 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009305 pw.println("Granted Uri Permissions:");
9306 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9307 int uid = mGrantedUriPermissions.keyAt(i);
9308 HashMap<Uri, UriPermission> perms
9309 = mGrantedUriPermissions.valueAt(i);
9310 pw.print(" * UID "); pw.print(uid);
9311 pw.println(" holds:");
9312 for (UriPermission perm : perms.values()) {
9313 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009314 if (dumpAll) {
9315 perm.dump(pw, " ");
9316 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009317 }
9318 }
9319 needSep = true;
9320 }
9321
9322 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009323 }
9324
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009325 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009326 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009327 boolean needSep = false;
9328
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009329 if (mIntentSenderRecords.size() > 0) {
9330 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009331 Iterator<WeakReference<PendingIntentRecord>> it
9332 = mIntentSenderRecords.values().iterator();
9333 while (it.hasNext()) {
9334 WeakReference<PendingIntentRecord> ref = it.next();
9335 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009336 if (dumpPackage != null && (rec == null
9337 || !dumpPackage.equals(rec.key.packageName))) {
9338 continue;
9339 }
9340 if (!printed) {
9341 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9342 printed = true;
9343 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009344 needSep = true;
9345 if (rec != null) {
9346 pw.print(" * "); pw.println(rec);
9347 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009348 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009349 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009350 } else {
9351 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009352 }
9353 }
9354 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009355
9356 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 }
9358
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009359 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009360 String prefix, String label, boolean complete, boolean brief, boolean client,
9361 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009362 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009363 boolean needNL = false;
9364 final String innerPrefix = prefix + " ";
9365 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009366 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009367 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009368 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9369 continue;
9370 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009371 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009372 if (needNL) {
9373 pw.println(" ");
9374 needNL = false;
9375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 if (lastTask != r.task) {
9377 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009378 pw.print(prefix);
9379 pw.print(full ? "* " : " ");
9380 pw.println(lastTask);
9381 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009382 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009383 } else if (complete) {
9384 // Complete + brief == give a summary. Isn't that obvious?!?
9385 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009386 pw.print(prefix); pw.print(" ");
9387 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009388 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009390 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009391 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9392 pw.print(" #"); pw.print(i); pw.print(": ");
9393 pw.println(r);
9394 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009395 r.dump(pw, innerPrefix);
9396 } else if (complete) {
9397 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009398 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009399 if (r.app != null) {
9400 pw.print(innerPrefix); pw.println(r.app);
9401 }
9402 }
9403 if (client && r.app != null && r.app.thread != null) {
9404 // flush anything that is already in the PrintWriter since the thread is going
9405 // to write to the file descriptor directly
9406 pw.flush();
9407 try {
9408 TransferPipe tp = new TransferPipe();
9409 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009410 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9411 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009412 // Short timeout, since blocking here can
9413 // deadlock with the application.
9414 tp.go(fd, 2000);
9415 } finally {
9416 tp.kill();
9417 }
9418 } catch (IOException e) {
9419 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9420 } catch (RemoteException e) {
9421 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9422 }
9423 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009424 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 }
9426 }
9427
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009428 private static String buildOomTag(String prefix, String space, int val, int base) {
9429 if (val == base) {
9430 if (space == null) return prefix;
9431 return prefix + " ";
9432 }
9433 return prefix + "+" + Integer.toString(val-base);
9434 }
9435
9436 private static final int dumpProcessList(PrintWriter pw,
9437 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009438 String prefix, String normalLabel, String persistentLabel,
9439 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009440 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009441 final int N = list.size()-1;
9442 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009443 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009444 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9445 continue;
9446 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009447 pw.println(String.format("%s%s #%2d: %s",
9448 prefix, (r.persistent ? persistentLabel : normalLabel),
9449 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009450 if (r.persistent) {
9451 numPers++;
9452 }
9453 }
9454 return numPers;
9455 }
9456
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009457 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009458 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009459 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009460 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009461
Dianne Hackborn905577f2011-09-07 18:31:28 -07009462 ArrayList<Pair<ProcessRecord, Integer>> list
9463 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9464 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009465 ProcessRecord r = origList.get(i);
9466 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9467 continue;
9468 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009469 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9470 }
9471
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009472 if (list.size() <= 0) {
9473 return false;
9474 }
9475
Dianne Hackborn905577f2011-09-07 18:31:28 -07009476 Comparator<Pair<ProcessRecord, Integer>> comparator
9477 = new Comparator<Pair<ProcessRecord, Integer>>() {
9478 @Override
9479 public int compare(Pair<ProcessRecord, Integer> object1,
9480 Pair<ProcessRecord, Integer> object2) {
9481 if (object1.first.setAdj != object2.first.setAdj) {
9482 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9483 }
9484 if (object1.second.intValue() != object2.second.intValue()) {
9485 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9486 }
9487 return 0;
9488 }
9489 };
9490
9491 Collections.sort(list, comparator);
9492
Dianne Hackborn287952c2010-09-22 22:34:31 -07009493 final long curRealtime = SystemClock.elapsedRealtime();
9494 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9495 final long curUptime = SystemClock.uptimeMillis();
9496 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9497
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009498 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009499 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009500 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009501 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009502 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009503 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9504 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009505 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9506 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009507 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9508 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009509 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9510 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009511 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009512 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009513 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9514 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9515 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9516 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9517 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9518 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9519 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9520 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009521 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9522 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009523 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9524 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009525 } else {
9526 oomAdj = Integer.toString(r.setAdj);
9527 }
9528 String schedGroup;
9529 switch (r.setSchedGroup) {
9530 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9531 schedGroup = "B";
9532 break;
9533 case Process.THREAD_GROUP_DEFAULT:
9534 schedGroup = "F";
9535 break;
9536 default:
9537 schedGroup = Integer.toString(r.setSchedGroup);
9538 break;
9539 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009540 String foreground;
9541 if (r.foregroundActivities) {
9542 foreground = "A";
9543 } else if (r.foregroundServices) {
9544 foreground = "S";
9545 } else {
9546 foreground = " ";
9547 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009548 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009549 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009550 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9551 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009552 if (r.adjSource != null || r.adjTarget != null) {
9553 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009554 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009555 if (r.adjTarget instanceof ComponentName) {
9556 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9557 } else if (r.adjTarget != null) {
9558 pw.print(r.adjTarget.toString());
9559 } else {
9560 pw.print("{null}");
9561 }
9562 pw.print("<=");
9563 if (r.adjSource instanceof ProcessRecord) {
9564 pw.print("Proc{");
9565 pw.print(((ProcessRecord)r.adjSource).toShortString());
9566 pw.println("}");
9567 } else if (r.adjSource != null) {
9568 pw.println(r.adjSource.toString());
9569 } else {
9570 pw.println("{null}");
9571 }
9572 }
9573 if (inclDetails) {
9574 pw.print(prefix);
9575 pw.print(" ");
9576 pw.print("oom: max="); pw.print(r.maxAdj);
9577 pw.print(" hidden="); pw.print(r.hiddenAdj);
9578 pw.print(" curRaw="); pw.print(r.curRawAdj);
9579 pw.print(" setRaw="); pw.print(r.setRawAdj);
9580 pw.print(" cur="); pw.print(r.curAdj);
9581 pw.print(" set="); pw.println(r.setAdj);
9582 pw.print(prefix);
9583 pw.print(" ");
9584 pw.print("keeping="); pw.print(r.keeping);
9585 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009586 pw.print(" empty="); pw.print(r.empty);
9587 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009588
9589 if (!r.keeping) {
9590 if (r.lastWakeTime != 0) {
9591 long wtime;
9592 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9593 synchronized (stats) {
9594 wtime = stats.getProcessWakeTime(r.info.uid,
9595 r.pid, curRealtime);
9596 }
9597 long timeUsed = wtime - r.lastWakeTime;
9598 pw.print(prefix);
9599 pw.print(" ");
9600 pw.print("keep awake over ");
9601 TimeUtils.formatDuration(realtimeSince, pw);
9602 pw.print(" used ");
9603 TimeUtils.formatDuration(timeUsed, pw);
9604 pw.print(" (");
9605 pw.print((timeUsed*100)/realtimeSince);
9606 pw.println("%)");
9607 }
9608 if (r.lastCpuTime != 0) {
9609 long timeUsed = r.curCpuTime - r.lastCpuTime;
9610 pw.print(prefix);
9611 pw.print(" ");
9612 pw.print("run cpu over ");
9613 TimeUtils.formatDuration(uptimeSince, pw);
9614 pw.print(" used ");
9615 TimeUtils.formatDuration(timeUsed, pw);
9616 pw.print(" (");
9617 pw.print((timeUsed*100)/uptimeSince);
9618 pw.println("%)");
9619 }
9620 }
9621 }
9622 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009623 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009624 }
9625
Dianne Hackbornb437e092011-08-05 17:50:29 -07009626 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009627 ArrayList<ProcessRecord> procs;
9628 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009629 if (args != null && args.length > start
9630 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009631 procs = new ArrayList<ProcessRecord>();
9632 int pid = -1;
9633 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009634 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009635 } catch (NumberFormatException e) {
9636
9637 }
9638 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9639 ProcessRecord proc = mLruProcesses.get(i);
9640 if (proc.pid == pid) {
9641 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009642 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009643 procs.add(proc);
9644 }
9645 }
9646 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009647 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009648 return null;
9649 }
9650 } else {
9651 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9652 }
9653 }
9654 return procs;
9655 }
9656
9657 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9658 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009659 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009660 if (procs == null) {
9661 return;
9662 }
9663
9664 long uptime = SystemClock.uptimeMillis();
9665 long realtime = SystemClock.elapsedRealtime();
9666 pw.println("Applications Graphics Acceleration Info:");
9667 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9668
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009669 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9670 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009671 if (r.thread != null) {
9672 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9673 pw.flush();
9674 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009675 TransferPipe tp = new TransferPipe();
9676 try {
9677 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9678 tp.go(fd);
9679 } finally {
9680 tp.kill();
9681 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009682 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009683 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009684 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009685 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009686 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009687 pw.flush();
9688 }
9689 }
9690 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009691 }
9692
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009693 final static class MemItem {
9694 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009695 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009696 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009697 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009698 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009699
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009700 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009701 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009702 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009703 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009704 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009705 }
9706 }
9707
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009708 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009709 boolean sort) {
9710 if (sort) {
9711 Collections.sort(items, new Comparator<MemItem>() {
9712 @Override
9713 public int compare(MemItem lhs, MemItem rhs) {
9714 if (lhs.pss < rhs.pss) {
9715 return 1;
9716 } else if (lhs.pss > rhs.pss) {
9717 return -1;
9718 }
9719 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009720 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009721 });
9722 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009723
9724 for (int i=0; i<items.size(); i++) {
9725 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009726 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009727 if (mi.subitems != null) {
9728 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9729 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009730 }
9731 }
9732
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009733 // These are in KB.
9734 static final long[] DUMP_MEM_BUCKETS = new long[] {
9735 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9736 120*1024, 160*1024, 200*1024,
9737 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9738 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9739 };
9740
Dianne Hackborn672342c2011-11-29 11:29:02 -08009741 static final void appendMemBucket(StringBuilder out, long memKB, String label,
9742 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009743 int start = label.lastIndexOf('.');
9744 if (start >= 0) start++;
9745 else start = 0;
9746 int end = label.length();
9747 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9748 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9749 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9750 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009751 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009752 out.append(label, start, end);
9753 return;
9754 }
9755 }
9756 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009757 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009758 out.append(label, start, end);
9759 }
9760
9761 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9762 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9763 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9764 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9765 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9766 };
9767 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9768 "System", "Persistent", "Foreground",
9769 "Visible", "Perceptible", "Heavy Weight",
9770 "Backup", "A Services", "Home", "Previous",
9771 "B Services", "Background"
9772 };
9773
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009774 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009775 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -08009776 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009777 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009778 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009779
9780 int opti = 0;
9781 while (opti < args.length) {
9782 String opt = args[opti];
9783 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9784 break;
9785 }
9786 opti++;
9787 if ("-a".equals(opt)) {
9788 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009789 } else if ("--oom".equals(opt)) {
9790 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009791 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009792 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009793 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009794 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009795 pw.println("If [process] is specified it can be the name or ");
9796 pw.println("pid of a specific process to dump.");
9797 return;
9798 } else {
9799 pw.println("Unknown argument: " + opt + "; use -h for help");
9800 }
9801 }
9802
9803 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009804 if (procs == null) {
9805 return;
9806 }
9807
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009808 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009809 long uptime = SystemClock.uptimeMillis();
9810 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009811
9812 if (procs.size() == 1 || isCheckinRequest) {
9813 dumpAll = true;
9814 }
9815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 if (isCheckinRequest) {
9817 // short checkin version
9818 pw.println(uptime + "," + realtime);
9819 pw.flush();
9820 } else {
9821 pw.println("Applications Memory Usage (kB):");
9822 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9823 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009824
Dianne Hackbornb437e092011-08-05 17:50:29 -07009825 String[] innerArgs = new String[args.length-opti];
9826 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9827
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009828 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9829 long nativePss=0, dalvikPss=0, otherPss=0;
9830 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9831
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009832 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9833 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9834 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009835
9836 long totalPss = 0;
9837
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009838 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9839 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009841 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009842 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9843 pw.flush();
9844 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009845 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009846 if (dumpAll) {
9847 try {
9848 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9849 } catch (RemoteException e) {
9850 if (!isCheckinRequest) {
9851 pw.println("Got RemoteException!");
9852 pw.flush();
9853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009855 } else {
9856 mi = new Debug.MemoryInfo();
9857 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009859
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009860 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009861 long myTotalPss = mi.getTotalPss();
9862 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009863 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009864 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009865 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009866
9867 nativePss += mi.nativePss;
9868 dalvikPss += mi.dalvikPss;
9869 otherPss += mi.otherPss;
9870 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9871 long mem = mi.getOtherPss(j);
9872 miscPss[j] += mem;
9873 otherPss -= mem;
9874 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009875
9876 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009877 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9878 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009879 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009880 if (oomProcs[oomIndex] == null) {
9881 oomProcs[oomIndex] = new ArrayList<MemItem>();
9882 }
9883 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009884 break;
9885 }
9886 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009888 }
9889 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009890
9891 if (!isCheckinRequest && procs.size() > 1) {
9892 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9893
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009894 catMems.add(new MemItem("Native", "Native", nativePss, -1));
9895 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9896 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009897 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009898 String label = Debug.MemoryInfo.getOtherLabel(j);
9899 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009900 }
9901
Dianne Hackbornb437e092011-08-05 17:50:29 -07009902 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9903 for (int j=0; j<oomPss.length; j++) {
9904 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009905 String label = DUMP_MEM_OOM_LABEL[j];
9906 MemItem item = new MemItem(label, label, oomPss[j],
9907 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009908 item.subitems = oomProcs[j];
9909 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009910 }
9911 }
9912
Dianne Hackborn672342c2011-11-29 11:29:02 -08009913 if (outTag != null || outStack != null) {
9914 if (outTag != null) {
9915 appendMemBucket(outTag, totalPss, "total", false);
9916 }
9917 if (outStack != null) {
9918 appendMemBucket(outStack, totalPss, "total", true);
9919 }
9920 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009921 for (int i=0; i<oomMems.size(); i++) {
9922 MemItem miCat = oomMems.get(i);
9923 if (miCat.subitems == null || miCat.subitems.size() < 1) {
9924 continue;
9925 }
9926 if (miCat.id < ProcessList.SERVICE_ADJ
9927 || miCat.id == ProcessList.HOME_APP_ADJ
9928 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009929 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9930 outTag.append(" / ");
9931 }
9932 if (outStack != null) {
9933 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9934 if (firstLine) {
9935 outStack.append(":");
9936 firstLine = false;
9937 }
9938 outStack.append("\n\t at ");
9939 } else {
9940 outStack.append("$");
9941 }
9942 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009943 for (int j=0; j<miCat.subitems.size(); j++) {
9944 MemItem mi = miCat.subitems.get(j);
9945 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009946 if (outTag != null) {
9947 outTag.append(" ");
9948 }
9949 if (outStack != null) {
9950 outStack.append("$");
9951 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009952 }
Dianne Hackborn672342c2011-11-29 11:29:02 -08009953 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9954 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
9955 }
9956 if (outStack != null) {
9957 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
9958 }
9959 }
9960 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9961 outStack.append("(");
9962 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
9963 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
9964 outStack.append(DUMP_MEM_OOM_LABEL[k]);
9965 outStack.append(":");
9966 outStack.append(DUMP_MEM_OOM_ADJ[k]);
9967 }
9968 }
9969 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009970 }
9971 }
9972 }
9973 }
9974
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009975 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009976 pw.println();
9977 pw.println("Total PSS by process:");
9978 dumpMemItems(pw, " ", procMems, true);
9979 pw.println();
9980 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009981 pw.println("Total PSS by OOM adjustment:");
9982 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009983 if (!oomOnly) {
9984 PrintWriter out = categoryPw != null ? categoryPw : pw;
9985 out.println();
9986 out.println("Total PSS by category:");
9987 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009988 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009989 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009990 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 }
9993
9994 /**
9995 * Searches array of arguments for the specified string
9996 * @param args array of argument strings
9997 * @param value value to search for
9998 * @return true if the value is contained in the array
9999 */
10000 private static boolean scanArgs(String[] args, String value) {
10001 if (args != null) {
10002 for (String arg : args) {
10003 if (value.equals(arg)) {
10004 return true;
10005 }
10006 }
10007 }
10008 return false;
10009 }
10010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010011 private final void killServicesLocked(ProcessRecord app,
10012 boolean allowRestart) {
10013 // Report disconnected services.
10014 if (false) {
10015 // XXX we are letting the client link to the service for
10016 // death notifications.
10017 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010018 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010019 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010020 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010021 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010022 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010023 = r.connections.values().iterator();
10024 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010025 ArrayList<ConnectionRecord> cl = jt.next();
10026 for (int i=0; i<cl.size(); i++) {
10027 ConnectionRecord c = cl.get(i);
10028 if (c.binding.client != app) {
10029 try {
10030 //c.conn.connected(r.className, null);
10031 } catch (Exception e) {
10032 // todo: this should be asynchronous!
10033 Slog.w(TAG, "Exception thrown disconnected servce "
10034 + r.shortName
10035 + " from app " + app.processName, e);
10036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010037 }
10038 }
10039 }
10040 }
10041 }
10042 }
10043 }
10044
10045 // Clean up any connections this application has to other services.
10046 if (app.connections.size() > 0) {
10047 Iterator<ConnectionRecord> it = app.connections.iterator();
10048 while (it.hasNext()) {
10049 ConnectionRecord r = it.next();
10050 removeConnectionLocked(r, app, null);
10051 }
10052 }
10053 app.connections.clear();
10054
10055 if (app.services.size() != 0) {
10056 // Any services running in the application need to be placed
10057 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010058 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010059 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010060 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 synchronized (sr.stats.getBatteryStats()) {
10062 sr.stats.stopLaunchedLocked();
10063 }
10064 sr.app = null;
10065 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010066 if (mStoppingServices.remove(sr)) {
10067 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10068 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010069
10070 boolean hasClients = sr.bindings.size() > 0;
10071 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 Iterator<IntentBindRecord> bindings
10073 = sr.bindings.values().iterator();
10074 while (bindings.hasNext()) {
10075 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010076 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 + ": shouldUnbind=" + b.hasBound);
10078 b.binder = null;
10079 b.requested = b.received = b.hasBound = false;
10080 }
10081 }
10082
Dianne Hackborn070783f2010-12-29 16:46:28 -080010083 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10084 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010085 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010086 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010087 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010088 sr.crashCount, sr.shortName, app.pid);
10089 bringDownServiceLocked(sr, true);
10090 } else if (!allowRestart) {
10091 bringDownServiceLocked(sr, true);
10092 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010093 boolean canceled = scheduleServiceRestartLocked(sr, true);
10094
10095 // Should the service remain running? Note that in the
10096 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010097 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010098 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10099 if (sr.pendingStarts.size() == 0) {
10100 sr.startRequested = false;
10101 if (!hasClients) {
10102 // Whoops, no reason to restart!
10103 bringDownServiceLocked(sr, true);
10104 }
10105 }
10106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 }
10108 }
10109
10110 if (!allowRestart) {
10111 app.services.clear();
10112 }
10113 }
10114
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010115 // Make sure we have no more records on the stopping list.
10116 int i = mStoppingServices.size();
10117 while (i > 0) {
10118 i--;
10119 ServiceRecord sr = mStoppingServices.get(i);
10120 if (sr.app == app) {
10121 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010122 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010123 }
10124 }
10125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 app.executingServices.clear();
10127 }
10128
10129 private final void removeDyingProviderLocked(ProcessRecord proc,
10130 ContentProviderRecord cpr) {
10131 synchronized (cpr) {
10132 cpr.launchingApp = null;
10133 cpr.notifyAll();
10134 }
10135
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010136 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010137 String names[] = cpr.info.authority.split(";");
10138 for (int j = 0; j < names.length; j++) {
10139 mProvidersByName.remove(names[j]);
10140 }
10141
10142 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10143 while (cit.hasNext()) {
10144 ProcessRecord capp = cit.next();
10145 if (!capp.persistent && capp.thread != null
10146 && capp.pid != 0
10147 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010148 Slog.i(TAG, "Kill " + capp.processName
10149 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010150 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010151 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010152 capp.processName, capp.setAdj, "dying provider "
10153 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010154 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010155 }
10156 }
10157
10158 mLaunchingProviders.remove(cpr);
10159 }
10160
10161 /**
10162 * Main code for cleaning up a process when it has gone away. This is
10163 * called both as a result of the process dying, or directly when stopping
10164 * a process when running in single process mode.
10165 */
10166 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010167 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010168 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010169 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170 }
10171
Dianne Hackborn36124872009-10-08 16:22:03 -070010172 mProcessesToGc.remove(app);
10173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010174 // Dismiss any open dialogs.
10175 if (app.crashDialog != null) {
10176 app.crashDialog.dismiss();
10177 app.crashDialog = null;
10178 }
10179 if (app.anrDialog != null) {
10180 app.anrDialog.dismiss();
10181 app.anrDialog = null;
10182 }
10183 if (app.waitDialog != null) {
10184 app.waitDialog.dismiss();
10185 app.waitDialog = null;
10186 }
10187
10188 app.crashing = false;
10189 app.notResponding = false;
10190
10191 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010192 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193 app.thread = null;
10194 app.forcingToForeground = null;
10195 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010196 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010197 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010198 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010200 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201
10202 boolean restart = false;
10203
10204 int NL = mLaunchingProviders.size();
10205
10206 // Remove published content providers.
10207 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010208 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010209 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010210 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010211 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010212 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213
10214 // See if someone is waiting for this provider... in which
10215 // case we don't remove it, but just let it restart.
10216 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010217 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010218 for (; i<NL; i++) {
10219 if (mLaunchingProviders.get(i) == cpr) {
10220 restart = true;
10221 break;
10222 }
10223 }
10224 } else {
10225 i = NL;
10226 }
10227
10228 if (i >= NL) {
10229 removeDyingProviderLocked(app, cpr);
10230 NL = mLaunchingProviders.size();
10231 }
10232 }
10233 app.pubProviders.clear();
10234 }
10235
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010236 // Take care of any launching providers waiting for this process.
10237 if (checkAppInLaunchingProvidersLocked(app, false)) {
10238 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010241 // Unregister from connected content providers.
10242 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070010243 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 while (it.hasNext()) {
10245 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10246 cpr.clients.remove(app);
10247 }
10248 app.conProviders.clear();
10249 }
10250
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010251 // At this point there may be remaining entries in mLaunchingProviders
10252 // where we were the only one waiting, so they are no longer of use.
10253 // Look for these and clean up if found.
10254 // XXX Commented out for now. Trying to figure out a way to reproduce
10255 // the actual situation to identify what is actually going on.
10256 if (false) {
10257 for (int i=0; i<NL; i++) {
10258 ContentProviderRecord cpr = (ContentProviderRecord)
10259 mLaunchingProviders.get(i);
10260 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10261 synchronized (cpr) {
10262 cpr.launchingApp = null;
10263 cpr.notifyAll();
10264 }
10265 }
10266 }
10267 }
10268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010269 skipCurrentReceiverLocked(app);
10270
10271 // Unregister any receivers.
10272 if (app.receivers.size() > 0) {
10273 Iterator<ReceiverList> it = app.receivers.iterator();
10274 while (it.hasNext()) {
10275 removeReceiverLocked(it.next());
10276 }
10277 app.receivers.clear();
10278 }
10279
Christopher Tate181fafa2009-05-14 11:12:14 -070010280 // If the app is undergoing backup, tell the backup manager about it
10281 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010282 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010283 try {
10284 IBackupManager bm = IBackupManager.Stub.asInterface(
10285 ServiceManager.getService(Context.BACKUP_SERVICE));
10286 bm.agentDisconnected(app.info.packageName);
10287 } catch (RemoteException e) {
10288 // can't happen; backup manager is local
10289 }
10290 }
10291
Jeff Sharkey287bd832011-05-28 19:36:26 -070010292 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 // If the caller is restarting this app, then leave it in its
10295 // current lists and let the caller take care of it.
10296 if (restarting) {
10297 return;
10298 }
10299
10300 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010301 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 "Removing non-persistent process during cleanup: " + app);
10303 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010304 if (mHeavyWeightProcess == app) {
10305 mHeavyWeightProcess = null;
10306 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010308 } else if (!app.removed) {
10309 // This app is persistent, so we need to keep its record around.
10310 // If it is not already on the pending app list, add it there
10311 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10313 mPersistentStartingProcesses.add(app);
10314 restart = true;
10315 }
10316 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010317 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10318 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 mProcessesOnHold.remove(app);
10320
The Android Open Source Project4df24232009-03-05 14:34:35 -080010321 if (app == mHomeProcess) {
10322 mHomeProcess = null;
10323 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010324 if (app == mPreviousProcess) {
10325 mPreviousProcess = null;
10326 }
10327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 if (restart) {
10329 // We have components that still need to be running in the
10330 // process, so re-launch it.
10331 mProcessNames.put(app.processName, app.info.uid, app);
10332 startProcessLocked(app, "restart", app.processName);
10333 } else if (app.pid > 0 && app.pid != MY_PID) {
10334 // Goodbye!
10335 synchronized (mPidsSelfLocked) {
10336 mPidsSelfLocked.remove(app.pid);
10337 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10338 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010339 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010340 }
10341 }
10342
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010343 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10344 // Look through the content providers we are waiting to have launched,
10345 // and if any run in this process then either schedule a restart of
10346 // the process or kill the client waiting for it if this process has
10347 // gone bad.
10348 int NL = mLaunchingProviders.size();
10349 boolean restart = false;
10350 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010351 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010352 if (cpr.launchingApp == app) {
10353 if (!alwaysBad && !app.bad) {
10354 restart = true;
10355 } else {
10356 removeDyingProviderLocked(app, cpr);
10357 NL = mLaunchingProviders.size();
10358 }
10359 }
10360 }
10361 return restart;
10362 }
10363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010364 // =========================================================
10365 // SERVICES
10366 // =========================================================
10367
10368 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10369 ActivityManager.RunningServiceInfo info =
10370 new ActivityManager.RunningServiceInfo();
10371 info.service = r.name;
10372 if (r.app != null) {
10373 info.pid = r.app.pid;
10374 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010375 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010376 info.process = r.processName;
10377 info.foreground = r.isForeground;
10378 info.activeSince = r.createTime;
10379 info.started = r.startRequested;
10380 info.clientCount = r.connections.size();
10381 info.crashCount = r.crashCount;
10382 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010383 if (r.isForeground) {
10384 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10385 }
10386 if (r.startRequested) {
10387 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10388 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010389 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010390 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10391 }
10392 if (r.app != null && r.app.persistent) {
10393 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10394 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010395
10396 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10397 for (int i=0; i<connl.size(); i++) {
10398 ConnectionRecord conn = connl.get(i);
10399 if (conn.clientLabel != 0) {
10400 info.clientPackage = conn.binding.client.info.packageName;
10401 info.clientLabel = conn.clientLabel;
10402 return info;
10403 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010404 }
10405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 return info;
10407 }
10408
10409 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10410 int flags) {
10411 synchronized (this) {
10412 ArrayList<ActivityManager.RunningServiceInfo> res
10413 = new ArrayList<ActivityManager.RunningServiceInfo>();
10414
10415 if (mServices.size() > 0) {
10416 Iterator<ServiceRecord> it = mServices.values().iterator();
10417 while (it.hasNext() && res.size() < maxNum) {
10418 res.add(makeRunningServiceInfoLocked(it.next()));
10419 }
10420 }
10421
10422 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10423 ServiceRecord r = mRestartingServices.get(i);
10424 ActivityManager.RunningServiceInfo info =
10425 makeRunningServiceInfoLocked(r);
10426 info.restarting = r.nextRestartTime;
10427 res.add(info);
10428 }
10429
10430 return res;
10431 }
10432 }
10433
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010434 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10435 synchronized (this) {
10436 ServiceRecord r = mServices.get(name);
10437 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010438 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10439 for (int i=0; i<conn.size(); i++) {
10440 if (conn.get(i).clientIntent != null) {
10441 return conn.get(i).clientIntent;
10442 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010443 }
10444 }
10445 }
10446 }
10447 return null;
10448 }
10449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010450 private final ServiceRecord findServiceLocked(ComponentName name,
10451 IBinder token) {
10452 ServiceRecord r = mServices.get(name);
10453 return r == token ? r : null;
10454 }
10455
10456 private final class ServiceLookupResult {
10457 final ServiceRecord record;
10458 final String permission;
10459
10460 ServiceLookupResult(ServiceRecord _record, String _permission) {
10461 record = _record;
10462 permission = _permission;
10463 }
10464 };
10465
10466 private ServiceLookupResult findServiceLocked(Intent service,
10467 String resolvedType) {
10468 ServiceRecord r = null;
10469 if (service.getComponent() != null) {
10470 r = mServices.get(service.getComponent());
10471 }
10472 if (r == null) {
10473 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10474 r = mServicesByIntent.get(filter);
10475 }
10476
10477 if (r == null) {
10478 try {
10479 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010480 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010481 service, resolvedType, 0);
10482 ServiceInfo sInfo =
10483 rInfo != null ? rInfo.serviceInfo : null;
10484 if (sInfo == null) {
10485 return null;
10486 }
10487
10488 ComponentName name = new ComponentName(
10489 sInfo.applicationInfo.packageName, sInfo.name);
10490 r = mServices.get(name);
10491 } catch (RemoteException ex) {
10492 // pm is in same process, this will never happen.
10493 }
10494 }
10495 if (r != null) {
10496 int callingPid = Binder.getCallingPid();
10497 int callingUid = Binder.getCallingUid();
10498 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010499 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010500 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010501 if (!r.exported) {
10502 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10503 + " from pid=" + callingPid
10504 + ", uid=" + callingUid
10505 + " that is not exported from uid " + r.appInfo.uid);
10506 return new ServiceLookupResult(null, "not exported from uid "
10507 + r.appInfo.uid);
10508 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010509 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010510 + " from pid=" + callingPid
10511 + ", uid=" + callingUid
10512 + " requires " + r.permission);
10513 return new ServiceLookupResult(null, r.permission);
10514 }
10515 return new ServiceLookupResult(r, null);
10516 }
10517 return null;
10518 }
10519
10520 private class ServiceRestarter implements Runnable {
10521 private ServiceRecord mService;
10522
10523 void setService(ServiceRecord service) {
10524 mService = service;
10525 }
10526
10527 public void run() {
10528 synchronized(ActivityManagerService.this) {
10529 performServiceRestartLocked(mService);
10530 }
10531 }
10532 }
10533
10534 private ServiceLookupResult retrieveServiceLocked(Intent service,
10535 String resolvedType, int callingPid, int callingUid) {
10536 ServiceRecord r = null;
10537 if (service.getComponent() != null) {
10538 r = mServices.get(service.getComponent());
10539 }
10540 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10541 r = mServicesByIntent.get(filter);
10542 if (r == null) {
10543 try {
10544 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010545 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010546 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010547 ServiceInfo sInfo =
10548 rInfo != null ? rInfo.serviceInfo : null;
10549 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010550 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010551 ": not found");
10552 return null;
10553 }
10554
10555 ComponentName name = new ComponentName(
10556 sInfo.applicationInfo.packageName, sInfo.name);
10557 r = mServices.get(name);
10558 if (r == null) {
10559 filter = new Intent.FilterComparison(service.cloneFilter());
10560 ServiceRestarter res = new ServiceRestarter();
10561 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10562 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10563 synchronized (stats) {
10564 ss = stats.getServiceStatsLocked(
10565 sInfo.applicationInfo.uid, sInfo.packageName,
10566 sInfo.name);
10567 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010568 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010569 res.setService(r);
10570 mServices.put(name, r);
10571 mServicesByIntent.put(filter, r);
10572
10573 // Make sure this component isn't in the pending list.
10574 int N = mPendingServices.size();
10575 for (int i=0; i<N; i++) {
10576 ServiceRecord pr = mPendingServices.get(i);
10577 if (pr.name.equals(name)) {
10578 mPendingServices.remove(i);
10579 i--;
10580 N--;
10581 }
10582 }
10583 }
10584 } catch (RemoteException ex) {
10585 // pm is in same process, this will never happen.
10586 }
10587 }
10588 if (r != null) {
10589 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010590 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010591 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010592 if (!r.exported) {
10593 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10594 + " from pid=" + callingPid
10595 + ", uid=" + callingUid
10596 + " that is not exported from uid " + r.appInfo.uid);
10597 return new ServiceLookupResult(null, "not exported from uid "
10598 + r.appInfo.uid);
10599 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010600 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010601 + " from pid=" + callingPid
10602 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010603 + " requires " + r.permission);
10604 return new ServiceLookupResult(null, r.permission);
10605 }
10606 return new ServiceLookupResult(r, null);
10607 }
10608 return null;
10609 }
10610
Dianne Hackborn287952c2010-09-22 22:34:31 -070010611 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10612 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10613 + why + " of " + r + " in app " + r.app);
10614 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10615 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010616 long now = SystemClock.uptimeMillis();
10617 if (r.executeNesting == 0 && r.app != null) {
10618 if (r.app.executingServices.size() == 0) {
10619 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10620 msg.obj = r.app;
10621 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10622 }
10623 r.app.executingServices.add(r);
10624 }
10625 r.executeNesting++;
10626 r.executingStart = now;
10627 }
10628
10629 private final void sendServiceArgsLocked(ServiceRecord r,
10630 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010631 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010632 if (N == 0) {
10633 return;
10634 }
10635
Dianne Hackborn39792d22010-08-19 18:01:52 -070010636 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010637 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010638 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010639 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10640 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010641 if (si.intent == null && N > 1) {
10642 // If somehow we got a dummy null intent in the middle,
10643 // then skip it. DO NOT skip a null intent when it is
10644 // the only one in the list -- this is to support the
10645 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010646 continue;
10647 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010648 si.deliveredTime = SystemClock.uptimeMillis();
10649 r.deliveredStarts.add(si);
10650 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010651 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010652 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010653 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010654 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010655 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 if (!oomAdjusted) {
10657 oomAdjusted = true;
10658 updateOomAdjLocked(r.app);
10659 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010660 int flags = 0;
10661 if (si.deliveryCount > 0) {
10662 flags |= Service.START_FLAG_RETRY;
10663 }
10664 if (si.doneExecutingCount > 0) {
10665 flags |= Service.START_FLAG_REDELIVERY;
10666 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010667 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010668 } catch (RemoteException e) {
10669 // Remote process gone... we'll let the normal cleanup take
10670 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010671 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010672 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010673 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010674 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 break;
10676 }
10677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010678 }
10679
10680 private final boolean requestServiceBindingLocked(ServiceRecord r,
10681 IntentBindRecord i, boolean rebind) {
10682 if (r.app == null || r.app.thread == null) {
10683 // If service is not currently running, can't yet bind.
10684 return false;
10685 }
10686 if ((!i.requested || rebind) && i.apps.size() > 0) {
10687 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010688 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10690 if (!rebind) {
10691 i.requested = true;
10692 }
10693 i.hasBound = true;
10694 i.doRebind = false;
10695 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010696 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010697 return false;
10698 }
10699 }
10700 return true;
10701 }
10702
10703 private final void requestServiceBindingsLocked(ServiceRecord r) {
10704 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10705 while (bindings.hasNext()) {
10706 IntentBindRecord i = bindings.next();
10707 if (!requestServiceBindingLocked(r, i, false)) {
10708 break;
10709 }
10710 }
10711 }
10712
10713 private final void realStartServiceLocked(ServiceRecord r,
10714 ProcessRecord app) throws RemoteException {
10715 if (app.thread == null) {
10716 throw new RemoteException();
10717 }
10718
10719 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010720 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010721
10722 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010723 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010724 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010725
10726 boolean created = false;
10727 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010728 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010729 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010730 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010731 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010732 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010733 synchronized (r.stats.getBatteryStats()) {
10734 r.stats.startLaunchedLocked();
10735 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010736 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010737 app.thread.scheduleCreateService(r, r.serviceInfo,
10738 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010739 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010740 created = true;
10741 } finally {
10742 if (!created) {
10743 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010744 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010745 }
10746 }
10747
10748 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010749
10750 // If the service is in the started state, and there are no
10751 // pending arguments, then fake up one so its onStartCommand() will
10752 // be called.
10753 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010754 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10755 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010756 }
10757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010758 sendServiceArgsLocked(r, true);
10759 }
10760
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010761 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10762 boolean allowCancel) {
10763 boolean canceled = false;
10764
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010765 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010766 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010767 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010768
Dianne Hackborn070783f2010-12-29 16:46:28 -080010769 if ((r.serviceInfo.applicationInfo.flags
10770 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10771 minDuration /= 4;
10772 }
10773
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010774 // Any delivered but not yet finished starts should be put back
10775 // on the pending list.
10776 final int N = r.deliveredStarts.size();
10777 if (N > 0) {
10778 for (int i=N-1; i>=0; i--) {
10779 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010780 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010781 if (si.intent == null) {
10782 // We'll generate this again if needed.
10783 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10784 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10785 r.pendingStarts.add(0, si);
10786 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10787 dur *= 2;
10788 if (minDuration < dur) minDuration = dur;
10789 if (resetTime < dur) resetTime = dur;
10790 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010791 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010792 + r.name);
10793 canceled = true;
10794 }
10795 }
10796 r.deliveredStarts.clear();
10797 }
10798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799 r.totalRestartCount++;
10800 if (r.restartDelay == 0) {
10801 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010802 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010803 } else {
10804 // If it has been a "reasonably long time" since the service
10805 // was started, then reset our restart duration back to
10806 // the beginning, so we don't infinitely increase the duration
10807 // on a service that just occasionally gets killed (which is
10808 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010809 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010810 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010811 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010812 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010813 if ((r.serviceInfo.applicationInfo.flags
10814 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10815 // Services in peristent processes will restart much more
10816 // quickly, since they are pretty important. (Think SystemUI).
10817 r.restartDelay += minDuration/2;
10818 } else {
10819 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10820 if (r.restartDelay < minDuration) {
10821 r.restartDelay = minDuration;
10822 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 }
10825 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010826
10827 r.nextRestartTime = now + r.restartDelay;
10828
10829 // Make sure that we don't end up restarting a bunch of services
10830 // all at the same time.
10831 boolean repeat;
10832 do {
10833 repeat = false;
10834 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10835 ServiceRecord r2 = mRestartingServices.get(i);
10836 if (r2 != r && r.nextRestartTime
10837 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10838 && r.nextRestartTime
10839 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10840 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10841 r.restartDelay = r.nextRestartTime - now;
10842 repeat = true;
10843 break;
10844 }
10845 }
10846 } while (repeat);
10847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010848 if (!mRestartingServices.contains(r)) {
10849 mRestartingServices.add(r);
10850 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010851
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010852 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010854 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010855 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010856 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010857 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010858 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010859 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010860 r.shortName, r.restartDelay);
10861
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010862 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 }
10864
10865 final void performServiceRestartLocked(ServiceRecord r) {
10866 if (!mRestartingServices.contains(r)) {
10867 return;
10868 }
10869 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10870 }
10871
10872 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10873 if (r.restartDelay == 0) {
10874 return false;
10875 }
10876 r.resetRestartCounter();
10877 mRestartingServices.remove(r);
10878 mHandler.removeCallbacks(r.restarter);
10879 return true;
10880 }
10881
10882 private final boolean bringUpServiceLocked(ServiceRecord r,
10883 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010884 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010885 //r.dump(" ");
10886
Dianne Hackborn36124872009-10-08 16:22:03 -070010887 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 sendServiceArgsLocked(r, false);
10889 return true;
10890 }
10891
10892 if (!whileRestarting && r.restartDelay > 0) {
10893 // If waiting for a restart, then do nothing.
10894 return true;
10895 }
10896
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010897 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010899 // We are now bringing the service up, so no longer in the
10900 // restarting state.
10901 mRestartingServices.remove(r);
10902
Dianne Hackborne7f97212011-02-24 14:40:20 -080010903 // Service is now being launched, its package can't be stopped.
10904 try {
10905 AppGlobals.getPackageManager().setPackageStoppedState(
10906 r.packageName, false);
10907 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010908 } catch (IllegalArgumentException e) {
10909 Slog.w(TAG, "Failed trying to unstop package "
10910 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010911 }
10912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010913 final String appName = r.processName;
10914 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10915 if (app != null && app.thread != null) {
10916 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010917 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918 realStartServiceLocked(r, app);
10919 return true;
10920 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010921 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010922 }
10923
10924 // If a dead object exception was thrown -- fall through to
10925 // restart the application.
10926 }
10927
Dianne Hackborn36124872009-10-08 16:22:03 -070010928 // Not running -- get it started, and enqueue this service record
10929 // to be executed when the app comes up.
10930 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10931 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010932 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010933 + r.appInfo.packageName + "/"
10934 + r.appInfo.uid + " for service "
10935 + r.intent.getIntent() + ": process is bad");
10936 bringDownServiceLocked(r, true);
10937 return false;
10938 }
10939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010940 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010941 mPendingServices.add(r);
10942 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010944 return true;
10945 }
10946
10947 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010948 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949 //r.dump(" ");
10950
10951 // Does it still need to run?
10952 if (!force && r.startRequested) {
10953 return;
10954 }
10955 if (r.connections.size() > 0) {
10956 if (!force) {
10957 // XXX should probably keep a count of the number of auto-create
10958 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010959 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010960 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010961 ArrayList<ConnectionRecord> cr = it.next();
10962 for (int i=0; i<cr.size(); i++) {
10963 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10964 return;
10965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010966 }
10967 }
10968 }
10969
10970 // Report to all of the connections that the service is no longer
10971 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010972 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010973 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010974 ArrayList<ConnectionRecord> c = it.next();
10975 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010976 ConnectionRecord cr = c.get(i);
10977 // There is still a connection to the service that is
10978 // being brought down. Mark it as dead.
10979 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010980 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010981 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010982 } catch (Exception e) {
10983 Slog.w(TAG, "Failure disconnecting service " + r.name +
10984 " to connection " + c.get(i).conn.asBinder() +
10985 " (in " + c.get(i).binding.client.processName + ")", e);
10986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010987 }
10988 }
10989 }
10990
10991 // Tell the service that it has been unbound.
10992 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10993 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10994 while (it.hasNext()) {
10995 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010996 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010997 + ": hasBound=" + ibr.hasBound);
10998 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10999 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011000 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011001 updateOomAdjLocked(r.app);
11002 ibr.hasBound = false;
11003 r.app.thread.scheduleUnbindService(r,
11004 ibr.intent.getIntent());
11005 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011006 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011007 + r.shortName, e);
11008 serviceDoneExecutingLocked(r, true);
11009 }
11010 }
11011 }
11012 }
11013
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011014 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011015 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011016 System.identityHashCode(r), r.shortName,
11017 (r.app != null) ? r.app.pid : -1);
11018
11019 mServices.remove(r.name);
11020 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011021 r.totalRestartCount = 0;
11022 unscheduleServiceRestartLocked(r);
11023
11024 // Also make sure it is not on the pending list.
11025 int N = mPendingServices.size();
11026 for (int i=0; i<N; i++) {
11027 if (mPendingServices.get(i) == r) {
11028 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011029 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011030 i--;
11031 N--;
11032 }
11033 }
11034
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011035 r.cancelNotification();
11036 r.isForeground = false;
11037 r.foregroundId = 0;
11038 r.foregroundNoti = null;
11039
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011040 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011041 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011042 r.pendingStarts.clear();
11043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 if (r.app != null) {
11045 synchronized (r.stats.getBatteryStats()) {
11046 r.stats.stopLaunchedLocked();
11047 }
11048 r.app.services.remove(r);
11049 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011051 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011052 mStoppingServices.add(r);
11053 updateOomAdjLocked(r.app);
11054 r.app.thread.scheduleStopService(r);
11055 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011056 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011057 + r.shortName, e);
11058 serviceDoneExecutingLocked(r, true);
11059 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011060 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011061 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011062 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011063 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011064 }
11065 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011066 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011067 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011068 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080011069
11070 if (r.bindings.size() > 0) {
11071 r.bindings.clear();
11072 }
11073
11074 if (r.restarter instanceof ServiceRestarter) {
11075 ((ServiceRestarter)r.restarter).setService(null);
11076 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011077 }
11078
11079 ComponentName startServiceLocked(IApplicationThread caller,
11080 Intent service, String resolvedType,
11081 int callingPid, int callingUid) {
11082 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011083 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011084 + " type=" + resolvedType + " args=" + service.getExtras());
11085
11086 if (caller != null) {
11087 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11088 if (callerApp == null) {
11089 throw new SecurityException(
11090 "Unable to find app for caller " + caller
11091 + " (pid=" + Binder.getCallingPid()
11092 + ") when starting service " + service);
11093 }
11094 }
11095
11096 ServiceLookupResult res =
11097 retrieveServiceLocked(service, resolvedType,
11098 callingPid, callingUid);
11099 if (res == null) {
11100 return null;
11101 }
11102 if (res.record == null) {
11103 return new ComponentName("!", res.permission != null
11104 ? res.permission : "private to package");
11105 }
11106 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070011107 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11108 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011109 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011110 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011111 }
11112 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011113 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011114 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070011115 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011116 r.lastActivity = SystemClock.uptimeMillis();
11117 synchronized (r.stats.getBatteryStats()) {
11118 r.stats.startRunningLocked();
11119 }
11120 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11121 return new ComponentName("!", "Service process is bad");
11122 }
11123 return r.name;
11124 }
11125 }
11126
11127 public ComponentName startService(IApplicationThread caller, Intent service,
11128 String resolvedType) {
11129 // Refuse possible leaked file descriptors
11130 if (service != null && service.hasFileDescriptors() == true) {
11131 throw new IllegalArgumentException("File descriptors passed in Intent");
11132 }
11133
11134 synchronized(this) {
11135 final int callingPid = Binder.getCallingPid();
11136 final int callingUid = Binder.getCallingUid();
11137 final long origId = Binder.clearCallingIdentity();
11138 ComponentName res = startServiceLocked(caller, service,
11139 resolvedType, callingPid, callingUid);
11140 Binder.restoreCallingIdentity(origId);
11141 return res;
11142 }
11143 }
11144
11145 ComponentName startServiceInPackage(int uid,
11146 Intent service, String resolvedType) {
11147 synchronized(this) {
11148 final long origId = Binder.clearCallingIdentity();
11149 ComponentName res = startServiceLocked(null, service,
11150 resolvedType, -1, uid);
11151 Binder.restoreCallingIdentity(origId);
11152 return res;
11153 }
11154 }
11155
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011156 private void stopServiceLocked(ServiceRecord service) {
11157 synchronized (service.stats.getBatteryStats()) {
11158 service.stats.stopRunningLocked();
11159 }
11160 service.startRequested = false;
11161 service.callStart = false;
11162 bringDownServiceLocked(service, false);
11163 }
11164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 public int stopService(IApplicationThread caller, Intent service,
11166 String resolvedType) {
11167 // Refuse possible leaked file descriptors
11168 if (service != null && service.hasFileDescriptors() == true) {
11169 throw new IllegalArgumentException("File descriptors passed in Intent");
11170 }
11171
11172 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011173 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011174 + " type=" + resolvedType);
11175
11176 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11177 if (caller != null && callerApp == null) {
11178 throw new SecurityException(
11179 "Unable to find app for caller " + caller
11180 + " (pid=" + Binder.getCallingPid()
11181 + ") when stopping service " + service);
11182 }
11183
11184 // If this service is active, make sure it is stopped.
11185 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11186 if (r != null) {
11187 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011188 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011189 try {
11190 stopServiceLocked(r.record);
11191 } finally {
11192 Binder.restoreCallingIdentity(origId);
11193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011194 return 1;
11195 }
11196 return -1;
11197 }
11198 }
11199
11200 return 0;
11201 }
11202
11203 public IBinder peekService(Intent service, String resolvedType) {
11204 // Refuse possible leaked file descriptors
11205 if (service != null && service.hasFileDescriptors() == true) {
11206 throw new IllegalArgumentException("File descriptors passed in Intent");
11207 }
11208
11209 IBinder ret = null;
11210
11211 synchronized(this) {
11212 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11213
11214 if (r != null) {
11215 // r.record is null if findServiceLocked() failed the caller permission check
11216 if (r.record == null) {
11217 throw new SecurityException(
11218 "Permission Denial: Accessing service " + r.record.name
11219 + " from pid=" + Binder.getCallingPid()
11220 + ", uid=" + Binder.getCallingUid()
11221 + " requires " + r.permission);
11222 }
11223 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11224 if (ib != null) {
11225 ret = ib.binder;
11226 }
11227 }
11228 }
11229
11230 return ret;
11231 }
11232
11233 public boolean stopServiceToken(ComponentName className, IBinder token,
11234 int startId) {
11235 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011236 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011237 + " " + token + " startId=" + startId);
11238 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011239 if (r != null) {
11240 if (startId >= 0) {
11241 // Asked to only stop if done with all work. Note that
11242 // to avoid leaks, we will take this as dropping all
11243 // start items up to and including this one.
11244 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11245 if (si != null) {
11246 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011247 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11248 cur.removeUriPermissionsLocked();
11249 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011250 break;
11251 }
11252 }
11253 }
11254
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011255 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011256 return false;
11257 }
11258
11259 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011260 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011261 + " is last, but have " + r.deliveredStarts.size()
11262 + " remaining args");
11263 }
11264 }
11265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011266 synchronized (r.stats.getBatteryStats()) {
11267 r.stats.stopRunningLocked();
11268 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011269 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011270 }
11271 final long origId = Binder.clearCallingIdentity();
11272 bringDownServiceLocked(r, false);
11273 Binder.restoreCallingIdentity(origId);
11274 return true;
11275 }
11276 }
11277 return false;
11278 }
11279
11280 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011281 int id, Notification notification, boolean removeNotification) {
11282 final long origId = Binder.clearCallingIdentity();
11283 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011284 synchronized(this) {
11285 ServiceRecord r = findServiceLocked(className, token);
11286 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011287 if (id != 0) {
11288 if (notification == null) {
11289 throw new IllegalArgumentException("null notification");
11290 }
11291 if (r.foregroundId != id) {
11292 r.cancelNotification();
11293 r.foregroundId = id;
11294 }
11295 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11296 r.foregroundNoti = notification;
11297 r.isForeground = true;
11298 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 if (r.app != null) {
11300 updateServiceForegroundLocked(r.app, true);
11301 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011302 } else {
11303 if (r.isForeground) {
11304 r.isForeground = false;
11305 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011306 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011307 updateServiceForegroundLocked(r.app, true);
11308 }
11309 }
11310 if (removeNotification) {
11311 r.cancelNotification();
11312 r.foregroundId = 0;
11313 r.foregroundNoti = null;
11314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011315 }
11316 }
11317 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011318 } finally {
11319 Binder.restoreCallingIdentity(origId);
11320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 }
11322
11323 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11324 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011325 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011326 if (sr.isForeground) {
11327 anyForeground = true;
11328 break;
11329 }
11330 }
11331 if (anyForeground != proc.foregroundServices) {
11332 proc.foregroundServices = anyForeground;
11333 if (oomAdj) {
11334 updateOomAdjLocked();
11335 }
11336 }
11337 }
11338
11339 public int bindService(IApplicationThread caller, IBinder token,
11340 Intent service, String resolvedType,
11341 IServiceConnection connection, int flags) {
11342 // Refuse possible leaked file descriptors
11343 if (service != null && service.hasFileDescriptors() == true) {
11344 throw new IllegalArgumentException("File descriptors passed in Intent");
11345 }
11346
11347 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011348 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 + " type=" + resolvedType + " conn=" + connection.asBinder()
11350 + " flags=0x" + Integer.toHexString(flags));
11351 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11352 if (callerApp == null) {
11353 throw new SecurityException(
11354 "Unable to find app for caller " + caller
11355 + " (pid=" + Binder.getCallingPid()
11356 + ") when binding service " + service);
11357 }
11358
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011359 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011361 activity = mMainStack.isInStackLocked(token);
11362 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011363 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011364 return 0;
11365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011366 }
11367
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011368 int clientLabel = 0;
11369 PendingIntent clientIntent = null;
11370
11371 if (callerApp.info.uid == Process.SYSTEM_UID) {
11372 // Hacky kind of thing -- allow system stuff to tell us
11373 // what they are, so we can report this elsewhere for
11374 // others to know why certain services are running.
11375 try {
11376 clientIntent = (PendingIntent)service.getParcelableExtra(
11377 Intent.EXTRA_CLIENT_INTENT);
11378 } catch (RuntimeException e) {
11379 }
11380 if (clientIntent != null) {
11381 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11382 if (clientLabel != 0) {
11383 // There are no useful extras in the intent, trash them.
11384 // System code calling with this stuff just needs to know
11385 // this will happen.
11386 service = service.cloneFilter();
11387 }
11388 }
11389 }
11390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391 ServiceLookupResult res =
11392 retrieveServiceLocked(service, resolvedType,
11393 Binder.getCallingPid(), Binder.getCallingUid());
11394 if (res == null) {
11395 return 0;
11396 }
11397 if (res.record == null) {
11398 return -1;
11399 }
11400 ServiceRecord s = res.record;
11401
11402 final long origId = Binder.clearCallingIdentity();
11403
11404 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011405 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011406 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011407 }
11408
11409 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11410 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011411 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412
11413 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011414 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11415 if (clist == null) {
11416 clist = new ArrayList<ConnectionRecord>();
11417 s.connections.put(binder, clist);
11418 }
11419 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011420 b.connections.add(c);
11421 if (activity != null) {
11422 if (activity.connections == null) {
11423 activity.connections = new HashSet<ConnectionRecord>();
11424 }
11425 activity.connections.add(c);
11426 }
11427 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011428 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11429 b.client.hasAboveClient = true;
11430 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011431 clist = mServiceConnections.get(binder);
11432 if (clist == null) {
11433 clist = new ArrayList<ConnectionRecord>();
11434 mServiceConnections.put(binder, clist);
11435 }
11436 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011437
11438 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11439 s.lastActivity = SystemClock.uptimeMillis();
11440 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11441 return 0;
11442 }
11443 }
11444
11445 if (s.app != null) {
11446 // This could have made the service more important.
11447 updateOomAdjLocked(s.app);
11448 }
11449
Joe Onorato8a9b2202010-02-26 18:56:32 -080011450 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451 + ": received=" + b.intent.received
11452 + " apps=" + b.intent.apps.size()
11453 + " doRebind=" + b.intent.doRebind);
11454
11455 if (s.app != null && b.intent.received) {
11456 // Service is already running, so we can immediately
11457 // publish the connection.
11458 try {
11459 c.conn.connected(s.name, b.intent.binder);
11460 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011461 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011462 + " to connection " + c.conn.asBinder()
11463 + " (in " + c.binding.client.processName + ")", e);
11464 }
11465
11466 // If this is the first app connected back to this binding,
11467 // and the service had previously asked to be told when
11468 // rebound, then do so.
11469 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11470 requestServiceBindingLocked(s, b.intent, true);
11471 }
11472 } else if (!b.intent.requested) {
11473 requestServiceBindingLocked(s, b.intent, false);
11474 }
11475
11476 Binder.restoreCallingIdentity(origId);
11477 }
11478
11479 return 1;
11480 }
11481
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011482 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011483 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011484 IBinder binder = c.conn.asBinder();
11485 AppBindRecord b = c.binding;
11486 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011487 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11488 if (clist != null) {
11489 clist.remove(c);
11490 if (clist.size() == 0) {
11491 s.connections.remove(binder);
11492 }
11493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011494 b.connections.remove(c);
11495 if (c.activity != null && c.activity != skipAct) {
11496 if (c.activity.connections != null) {
11497 c.activity.connections.remove(c);
11498 }
11499 }
11500 if (b.client != skipApp) {
11501 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011502 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11503 b.client.updateHasAboveClientLocked();
11504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011505 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011506 clist = mServiceConnections.get(binder);
11507 if (clist != null) {
11508 clist.remove(c);
11509 if (clist.size() == 0) {
11510 mServiceConnections.remove(binder);
11511 }
11512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011513
11514 if (b.connections.size() == 0) {
11515 b.intent.apps.remove(b.client);
11516 }
11517
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011518 if (!c.serviceDead) {
11519 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11520 + ": shouldUnbind=" + b.intent.hasBound);
11521 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11522 && b.intent.hasBound) {
11523 try {
11524 bumpServiceExecutingLocked(s, "unbind");
11525 updateOomAdjLocked(s.app);
11526 b.intent.hasBound = false;
11527 // Assume the client doesn't want to know about a rebind;
11528 // we will deal with that later if it asks for one.
11529 b.intent.doRebind = false;
11530 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11531 } catch (Exception e) {
11532 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11533 serviceDoneExecutingLocked(s, true);
11534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011535 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011536
11537 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11538 bringDownServiceLocked(s, false);
11539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011540 }
11541 }
11542
11543 public boolean unbindService(IServiceConnection connection) {
11544 synchronized (this) {
11545 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011546 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011547 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11548 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011549 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 + connection.asBinder());
11551 return false;
11552 }
11553
11554 final long origId = Binder.clearCallingIdentity();
11555
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011556 while (clist.size() > 0) {
11557 ConnectionRecord r = clist.get(0);
11558 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011559
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011560 if (r.binding.service.app != null) {
11561 // This could have made the service less important.
11562 updateOomAdjLocked(r.binding.service.app);
11563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564 }
11565
11566 Binder.restoreCallingIdentity(origId);
11567 }
11568
11569 return true;
11570 }
11571
11572 public void publishService(IBinder token, Intent intent, IBinder service) {
11573 // Refuse possible leaked file descriptors
11574 if (intent != null && intent.hasFileDescriptors() == true) {
11575 throw new IllegalArgumentException("File descriptors passed in Intent");
11576 }
11577
11578 synchronized(this) {
11579 if (!(token instanceof ServiceRecord)) {
11580 throw new IllegalArgumentException("Invalid service token");
11581 }
11582 ServiceRecord r = (ServiceRecord)token;
11583
11584 final long origId = Binder.clearCallingIdentity();
11585
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011586 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 + " " + intent + ": " + service);
11588 if (r != null) {
11589 Intent.FilterComparison filter
11590 = new Intent.FilterComparison(intent);
11591 IntentBindRecord b = r.bindings.get(filter);
11592 if (b != null && !b.received) {
11593 b.binder = service;
11594 b.requested = true;
11595 b.received = true;
11596 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011597 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011598 = r.connections.values().iterator();
11599 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011600 ArrayList<ConnectionRecord> clist = it.next();
11601 for (int i=0; i<clist.size(); i++) {
11602 ConnectionRecord c = clist.get(i);
11603 if (!filter.equals(c.binding.intent.intent)) {
11604 if (DEBUG_SERVICE) Slog.v(
11605 TAG, "Not publishing to: " + c);
11606 if (DEBUG_SERVICE) Slog.v(
11607 TAG, "Bound intent: " + c.binding.intent.intent);
11608 if (DEBUG_SERVICE) Slog.v(
11609 TAG, "Published intent: " + intent);
11610 continue;
11611 }
11612 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11613 try {
11614 c.conn.connected(r.name, service);
11615 } catch (Exception e) {
11616 Slog.w(TAG, "Failure sending service " + r.name +
11617 " to connection " + c.conn.asBinder() +
11618 " (in " + c.binding.client.processName + ")", e);
11619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011620 }
11621 }
11622 }
11623 }
11624
11625 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11626
11627 Binder.restoreCallingIdentity(origId);
11628 }
11629 }
11630 }
11631
11632 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11633 // Refuse possible leaked file descriptors
11634 if (intent != null && intent.hasFileDescriptors() == true) {
11635 throw new IllegalArgumentException("File descriptors passed in Intent");
11636 }
11637
11638 synchronized(this) {
11639 if (!(token instanceof ServiceRecord)) {
11640 throw new IllegalArgumentException("Invalid service token");
11641 }
11642 ServiceRecord r = (ServiceRecord)token;
11643
11644 final long origId = Binder.clearCallingIdentity();
11645
11646 if (r != null) {
11647 Intent.FilterComparison filter
11648 = new Intent.FilterComparison(intent);
11649 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011650 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011651 + " at " + b + ": apps="
11652 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011653
11654 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011656 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011657 // Applications have already bound since the last
11658 // unbind, so just rebind right here.
11659 requestServiceBindingLocked(r, b, true);
11660 } else {
11661 // Note to tell the service the next time there is
11662 // a new client.
11663 b.doRebind = true;
11664 }
11665 }
11666
Per Edelberg78f9fff2010-08-30 20:01:35 +020011667 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011668
11669 Binder.restoreCallingIdentity(origId);
11670 }
11671 }
11672 }
11673
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011674 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011675 synchronized(this) {
11676 if (!(token instanceof ServiceRecord)) {
11677 throw new IllegalArgumentException("Invalid service token");
11678 }
11679 ServiceRecord r = (ServiceRecord)token;
11680 boolean inStopping = mStoppingServices.contains(token);
11681 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011683 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011684 + " with incorrect token: given " + token
11685 + ", expected " + r);
11686 return;
11687 }
11688
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011689 if (type == 1) {
11690 // This is a call from a service start... take care of
11691 // book-keeping.
11692 r.callStart = true;
11693 switch (res) {
11694 case Service.START_STICKY_COMPATIBILITY:
11695 case Service.START_STICKY: {
11696 // We are done with the associated start arguments.
11697 r.findDeliveredStart(startId, true);
11698 // Don't stop if killed.
11699 r.stopIfKilled = false;
11700 break;
11701 }
11702 case Service.START_NOT_STICKY: {
11703 // We are done with the associated start arguments.
11704 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011705 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011706 // There is no more work, and this service
11707 // doesn't want to hang around if killed.
11708 r.stopIfKilled = true;
11709 }
11710 break;
11711 }
11712 case Service.START_REDELIVER_INTENT: {
11713 // We'll keep this item until they explicitly
11714 // call stop for it, but keep track of the fact
11715 // that it was delivered.
11716 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11717 if (si != null) {
11718 si.deliveryCount = 0;
11719 si.doneExecutingCount++;
11720 // Don't stop if killed.
11721 r.stopIfKilled = true;
11722 }
11723 break;
11724 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011725 case Service.START_TASK_REMOVED_COMPLETE: {
11726 // Special processing for onTaskRemoved(). Don't
11727 // impact normal onStartCommand() processing.
11728 r.findDeliveredStart(startId, true);
11729 break;
11730 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011731 default:
11732 throw new IllegalArgumentException(
11733 "Unknown service start result: " + res);
11734 }
11735 if (res == Service.START_STICKY_COMPATIBILITY) {
11736 r.callStart = false;
11737 }
11738 }
11739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011740 final long origId = Binder.clearCallingIdentity();
11741 serviceDoneExecutingLocked(r, inStopping);
11742 Binder.restoreCallingIdentity(origId);
11743 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011744 Slog.w(TAG, "Done executing unknown service from pid "
11745 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 }
11747 }
11748 }
11749
11750 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011751 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11752 + ": nesting=" + r.executeNesting
11753 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011754 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011755 r.executeNesting--;
11756 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011757 if (DEBUG_SERVICE) Slog.v(TAG,
11758 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011759 r.app.executingServices.remove(r);
11760 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011761 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11762 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011763 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11764 }
11765 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011766 if (DEBUG_SERVICE) Slog.v(TAG,
11767 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011768 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011769 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011770 }
11771 updateOomAdjLocked(r.app);
11772 }
11773 }
11774
11775 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011776 String anrMessage = null;
11777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 synchronized(this) {
11779 if (proc.executingServices.size() == 0 || proc.thread == null) {
11780 return;
11781 }
11782 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11783 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11784 ServiceRecord timeout = null;
11785 long nextTime = 0;
11786 while (it.hasNext()) {
11787 ServiceRecord sr = it.next();
11788 if (sr.executingStart < maxTime) {
11789 timeout = sr;
11790 break;
11791 }
11792 if (sr.executingStart > nextTime) {
11793 nextTime = sr.executingStart;
11794 }
11795 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011796 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011797 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011798 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 } else {
11800 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11801 msg.obj = proc;
11802 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11803 }
11804 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011805
11806 if (anrMessage != null) {
11807 appNotResponding(proc, null, null, anrMessage);
11808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011809 }
11810
11811 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011812 // BACKUP AND RESTORE
11813 // =========================================================
11814
11815 // Cause the target app to be launched if necessary and its backup agent
11816 // instantiated. The backup agent will invoke backupAgentCreated() on the
11817 // activity manager to announce its creation.
11818 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011819 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011820 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11821
11822 synchronized(this) {
11823 // !!! TODO: currently no check here that we're already bound
11824 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11825 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11826 synchronized (stats) {
11827 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11828 }
11829
Dianne Hackborne7f97212011-02-24 14:40:20 -080011830 // Backup agent is now in use, its package can't be stopped.
11831 try {
11832 AppGlobals.getPackageManager().setPackageStoppedState(
11833 app.packageName, false);
11834 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011835 } catch (IllegalArgumentException e) {
11836 Slog.w(TAG, "Failed trying to unstop package "
11837 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011838 }
11839
Christopher Tate181fafa2009-05-14 11:12:14 -070011840 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011841 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11842 ? new ComponentName(app.packageName, app.backupAgentName)
11843 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011844 // startProcessLocked() returns existing proc's record if it's already running
11845 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011846 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011847 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011848 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011849 return false;
11850 }
11851
11852 r.app = proc;
11853 mBackupTarget = r;
11854 mBackupAppName = app.packageName;
11855
Christopher Tate6fa95972009-06-05 18:43:55 -070011856 // Try not to kill the process during backup
11857 updateOomAdjLocked(proc);
11858
Christopher Tate181fafa2009-05-14 11:12:14 -070011859 // If the process is already attached, schedule the creation of the backup agent now.
11860 // If it is not yet live, this will be done when it attaches to the framework.
11861 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011862 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011863 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011864 proc.thread.scheduleCreateBackupAgent(app,
11865 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011866 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011867 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011868 }
11869 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011870 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011871 }
11872 // Invariants: at this point, the target app process exists and the application
11873 // is either already running or in the process of coming up. mBackupTarget and
11874 // mBackupAppName describe the app, so that when it binds back to the AM we
11875 // know that it's scheduled for a backup-agent operation.
11876 }
11877
11878 return true;
11879 }
11880
11881 // A backup agent has just come up
11882 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011883 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011884 + " = " + agent);
11885
11886 synchronized(this) {
11887 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011888 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011889 return;
11890 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011891 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011892
Dianne Hackborn06740692010-09-22 22:46:21 -070011893 long oldIdent = Binder.clearCallingIdentity();
11894 try {
11895 IBackupManager bm = IBackupManager.Stub.asInterface(
11896 ServiceManager.getService(Context.BACKUP_SERVICE));
11897 bm.agentConnected(agentPackageName, agent);
11898 } catch (RemoteException e) {
11899 // can't happen; the backup manager service is local
11900 } catch (Exception e) {
11901 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11902 e.printStackTrace();
11903 } finally {
11904 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011905 }
11906 }
11907
11908 // done with this agent
11909 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011910 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011911 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011912 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011913 return;
11914 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011915
11916 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011917 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011918 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011919 return;
11920 }
11921
Christopher Tate181fafa2009-05-14 11:12:14 -070011922 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011923 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011924 return;
11925 }
11926
Christopher Tate6fa95972009-06-05 18:43:55 -070011927 ProcessRecord proc = mBackupTarget.app;
11928 mBackupTarget = null;
11929 mBackupAppName = null;
11930
11931 // Not backing this app up any more; reset its OOM adjustment
11932 updateOomAdjLocked(proc);
11933
Christopher Tatec7b31e32009-06-10 15:49:30 -070011934 // If the app crashed during backup, 'thread' will be null here
11935 if (proc.thread != null) {
11936 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011937 proc.thread.scheduleDestroyBackupAgent(appInfo,
11938 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011939 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011940 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011941 e.printStackTrace();
11942 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011943 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011944 }
11945 }
11946 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011947 // BROADCASTS
11948 // =========================================================
11949
Josh Bartel7f208742010-02-25 11:01:44 -060011950 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011951 List cur) {
11952 final ContentResolver resolver = mContext.getContentResolver();
11953 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11954 if (list == null) {
11955 return cur;
11956 }
11957 int N = list.size();
11958 for (int i=0; i<N; i++) {
11959 Intent intent = list.get(i);
11960 if (filter.match(resolver, intent, true, TAG) >= 0) {
11961 if (cur == null) {
11962 cur = new ArrayList<Intent>();
11963 }
11964 cur.add(intent);
11965 }
11966 }
11967 return cur;
11968 }
11969
11970 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011971 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011972 + mBroadcastsScheduled);
11973
11974 if (mBroadcastsScheduled) {
11975 return;
11976 }
11977 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11978 mBroadcastsScheduled = true;
11979 }
11980
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011981 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011982 IIntentReceiver receiver, IntentFilter filter, String permission) {
11983 synchronized(this) {
11984 ProcessRecord callerApp = null;
11985 if (caller != null) {
11986 callerApp = getRecordForAppLocked(caller);
11987 if (callerApp == null) {
11988 throw new SecurityException(
11989 "Unable to find app for caller " + caller
11990 + " (pid=" + Binder.getCallingPid()
11991 + ") when registering receiver " + receiver);
11992 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011993 if (callerApp.info.uid != Process.SYSTEM_UID &&
11994 !callerApp.pkgList.contains(callerPackage)) {
11995 throw new SecurityException("Given caller package " + callerPackage
11996 + " is not running in process " + callerApp);
11997 }
11998 } else {
11999 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012000 }
12001
12002 List allSticky = null;
12003
12004 // Look for any matching sticky broadcasts...
12005 Iterator actions = filter.actionsIterator();
12006 if (actions != null) {
12007 while (actions.hasNext()) {
12008 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012009 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012010 }
12011 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012012 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 }
12014
12015 // The first sticky in the list is returned directly back to
12016 // the client.
12017 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12018
Joe Onorato8a9b2202010-02-26 18:56:32 -080012019 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 + ": " + sticky);
12021
12022 if (receiver == null) {
12023 return sticky;
12024 }
12025
12026 ReceiverList rl
12027 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12028 if (rl == null) {
12029 rl = new ReceiverList(this, callerApp,
12030 Binder.getCallingPid(),
12031 Binder.getCallingUid(), receiver);
12032 if (rl.app != null) {
12033 rl.app.receivers.add(rl);
12034 } else {
12035 try {
12036 receiver.asBinder().linkToDeath(rl, 0);
12037 } catch (RemoteException e) {
12038 return sticky;
12039 }
12040 rl.linkedToDeath = true;
12041 }
12042 mRegisteredReceivers.put(receiver.asBinder(), rl);
12043 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012044 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012045 rl.add(bf);
12046 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012047 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012048 }
12049 mReceiverResolver.addFilter(bf);
12050
12051 // Enqueue broadcasts for all existing stickies that match
12052 // this filter.
12053 if (allSticky != null) {
12054 ArrayList receivers = new ArrayList();
12055 receivers.add(bf);
12056
12057 int N = allSticky.size();
12058 for (int i=0; i<N; i++) {
12059 Intent intent = (Intent)allSticky.get(i);
12060 BroadcastRecord r = new BroadcastRecord(intent, null,
12061 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012062 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012063 if (mParallelBroadcasts.size() == 0) {
12064 scheduleBroadcastsLocked();
12065 }
12066 mParallelBroadcasts.add(r);
12067 }
12068 }
12069
12070 return sticky;
12071 }
12072 }
12073
12074 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012075 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012076
12077 boolean doNext = false;
12078
12079 synchronized(this) {
12080 ReceiverList rl
12081 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12082 if (rl != null) {
12083 if (rl.curBroadcast != null) {
12084 BroadcastRecord r = rl.curBroadcast;
12085 doNext = finishReceiverLocked(
12086 receiver.asBinder(), r.resultCode, r.resultData,
12087 r.resultExtras, r.resultAbort, true);
12088 }
12089
12090 if (rl.app != null) {
12091 rl.app.receivers.remove(rl);
12092 }
12093 removeReceiverLocked(rl);
12094 if (rl.linkedToDeath) {
12095 rl.linkedToDeath = false;
12096 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12097 }
12098 }
12099 }
12100
12101 if (!doNext) {
12102 return;
12103 }
12104
12105 final long origId = Binder.clearCallingIdentity();
12106 processNextBroadcast(false);
12107 trimApplications();
12108 Binder.restoreCallingIdentity(origId);
12109 }
12110
12111 void removeReceiverLocked(ReceiverList rl) {
12112 mRegisteredReceivers.remove(rl.receiver.asBinder());
12113 int N = rl.size();
12114 for (int i=0; i<N; i++) {
12115 mReceiverResolver.removeFilter(rl.get(i));
12116 }
12117 }
12118
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012119 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12120 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12121 ProcessRecord r = mLruProcesses.get(i);
12122 if (r.thread != null) {
12123 try {
12124 r.thread.dispatchPackageBroadcast(cmd, packages);
12125 } catch (RemoteException ex) {
12126 }
12127 }
12128 }
12129 }
12130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012131 private final int broadcastIntentLocked(ProcessRecord callerApp,
12132 String callerPackage, Intent intent, String resolvedType,
12133 IIntentReceiver resultTo, int resultCode, String resultData,
12134 Bundle map, String requiredPermission,
12135 boolean ordered, boolean sticky, int callingPid, int callingUid) {
12136 intent = new Intent(intent);
12137
Dianne Hackborne7f97212011-02-24 14:40:20 -080012138 // By default broadcasts do not go to stopped apps.
12139 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12140
Joe Onorato8a9b2202010-02-26 18:56:32 -080012141 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12143 + " ordered=" + ordered);
12144 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012145 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 }
12147
12148 // Handle special intents: if this broadcast is from the package
12149 // manager about a package being removed, we need to remove all of
12150 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012151 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012152 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012153 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12154 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012155 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012156 || uidRemoved) {
12157 if (checkComponentPermission(
12158 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012159 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012160 == PackageManager.PERMISSION_GRANTED) {
12161 if (uidRemoved) {
12162 final Bundle intentExtras = intent.getExtras();
12163 final int uid = intentExtras != null
12164 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12165 if (uid >= 0) {
12166 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12167 synchronized (bs) {
12168 bs.removeUidStatsLocked(uid);
12169 }
12170 }
12171 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012172 // If resources are unvailble just force stop all
12173 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012174 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012175 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12176 if (list != null && (list.length > 0)) {
12177 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070012178 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012179 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012180 sendPackageBroadcastLocked(
12181 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012182 }
12183 } else {
12184 Uri data = intent.getData();
12185 String ssp;
12186 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12187 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12188 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070012189 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012190 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012191 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012192 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12193 new String[] {ssp});
12194 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012195 }
12196 }
12197 }
12198 } else {
12199 String msg = "Permission Denial: " + intent.getAction()
12200 + " broadcast from " + callerPackage + " (pid=" + callingPid
12201 + ", uid=" + callingUid + ")"
12202 + " requires "
12203 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012204 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012205 throw new SecurityException(msg);
12206 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012207
12208 // Special case for adding a package: by default turn on compatibility
12209 // mode.
12210 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012211 Uri data = intent.getData();
12212 String ssp;
12213 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12214 mCompatModePackages.handlePackageAddedLocked(ssp,
12215 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012217 }
12218
12219 /*
12220 * If this is the time zone changed action, queue up a message that will reset the timezone
12221 * of all currently running processes. This message will get queued up before the broadcast
12222 * happens.
12223 */
12224 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12225 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12226 }
12227
Robert Greenwalt03595d02010-11-02 14:08:23 -070012228 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12229 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12230 }
12231
Robert Greenwalt434203a2010-10-11 16:00:27 -070012232 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12233 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12234 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12235 }
12236
Dianne Hackborn854060af2009-07-09 18:14:31 -070012237 /*
12238 * Prevent non-system code (defined here to be non-persistent
12239 * processes) from sending protected broadcasts.
12240 */
12241 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12242 || callingUid == Process.SHELL_UID || callingUid == 0) {
12243 // Always okay.
12244 } else if (callerApp == null || !callerApp.persistent) {
12245 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012246 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012247 intent.getAction())) {
12248 String msg = "Permission Denial: not allowed to send broadcast "
12249 + intent.getAction() + " from pid="
12250 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012251 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012252 throw new SecurityException(msg);
12253 }
12254 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012255 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012256 return BROADCAST_SUCCESS;
12257 }
12258 }
12259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012260 // Add to the sticky list if requested.
12261 if (sticky) {
12262 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12263 callingPid, callingUid)
12264 != PackageManager.PERMISSION_GRANTED) {
12265 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12266 + callingPid + ", uid=" + callingUid
12267 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012268 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012269 throw new SecurityException(msg);
12270 }
12271 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012272 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012273 + " and enforce permission " + requiredPermission);
12274 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12275 }
12276 if (intent.getComponent() != null) {
12277 throw new SecurityException(
12278 "Sticky broadcasts can't target a specific component");
12279 }
12280 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12281 if (list == null) {
12282 list = new ArrayList<Intent>();
12283 mStickyBroadcasts.put(intent.getAction(), list);
12284 }
12285 int N = list.size();
12286 int i;
12287 for (i=0; i<N; i++) {
12288 if (intent.filterEquals(list.get(i))) {
12289 // This sticky already exists, replace it.
12290 list.set(i, new Intent(intent));
12291 break;
12292 }
12293 }
12294 if (i >= N) {
12295 list.add(new Intent(intent));
12296 }
12297 }
12298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012299 // Figure out who all will receive this broadcast.
12300 List receivers = null;
12301 List<BroadcastFilter> registeredReceivers = null;
12302 try {
12303 if (intent.getComponent() != null) {
12304 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012305 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070012306 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012307 if (ai != null) {
12308 receivers = new ArrayList();
12309 ResolveInfo ri = new ResolveInfo();
12310 ri.activityInfo = ai;
12311 receivers.add(ri);
12312 }
12313 } else {
12314 // Need to resolve the intent to interested receivers...
12315 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12316 == 0) {
12317 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012318 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012319 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012320 }
Mihai Preda074edef2009-05-18 17:13:31 +020012321 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012322 }
12323 } catch (RemoteException ex) {
12324 // pm is in same process, this will never happen.
12325 }
12326
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012327 final boolean replacePending =
12328 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12329
Joe Onorato8a9b2202010-02-26 18:56:32 -080012330 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012331 + " replacePending=" + replacePending);
12332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012333 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12334 if (!ordered && NR > 0) {
12335 // If we are not serializing this broadcast, then send the
12336 // registered receivers separately so they don't wait for the
12337 // components to be launched.
12338 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12339 callerPackage, callingPid, callingUid, requiredPermission,
12340 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012341 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012342 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 TAG, "Enqueueing parallel broadcast " + r
12344 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012345 boolean replaced = false;
12346 if (replacePending) {
12347 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12348 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012349 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012350 "***** DROPPING PARALLEL: " + intent);
12351 mParallelBroadcasts.set(i, r);
12352 replaced = true;
12353 break;
12354 }
12355 }
12356 }
12357 if (!replaced) {
12358 mParallelBroadcasts.add(r);
12359 scheduleBroadcastsLocked();
12360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012361 registeredReceivers = null;
12362 NR = 0;
12363 }
12364
12365 // Merge into one list.
12366 int ir = 0;
12367 if (receivers != null) {
12368 // A special case for PACKAGE_ADDED: do not allow the package
12369 // being added to see this broadcast. This prevents them from
12370 // using this as a back door to get run as soon as they are
12371 // installed. Maybe in the future we want to have a special install
12372 // broadcast or such for apps, but we'd like to deliberately make
12373 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012374 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012375 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12376 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12377 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012378 Uri data = intent.getData();
12379 if (data != null) {
12380 String pkgName = data.getSchemeSpecificPart();
12381 if (pkgName != null) {
12382 skipPackages = new String[] { pkgName };
12383 }
12384 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012385 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012386 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012387 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012388 if (skipPackages != null && (skipPackages.length > 0)) {
12389 for (String skipPackage : skipPackages) {
12390 if (skipPackage != null) {
12391 int NT = receivers.size();
12392 for (int it=0; it<NT; it++) {
12393 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12394 if (curt.activityInfo.packageName.equals(skipPackage)) {
12395 receivers.remove(it);
12396 it--;
12397 NT--;
12398 }
12399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012400 }
12401 }
12402 }
12403
12404 int NT = receivers != null ? receivers.size() : 0;
12405 int it = 0;
12406 ResolveInfo curt = null;
12407 BroadcastFilter curr = null;
12408 while (it < NT && ir < NR) {
12409 if (curt == null) {
12410 curt = (ResolveInfo)receivers.get(it);
12411 }
12412 if (curr == null) {
12413 curr = registeredReceivers.get(ir);
12414 }
12415 if (curr.getPriority() >= curt.priority) {
12416 // Insert this broadcast record into the final list.
12417 receivers.add(it, curr);
12418 ir++;
12419 curr = null;
12420 it++;
12421 NT++;
12422 } else {
12423 // Skip to the next ResolveInfo in the final list.
12424 it++;
12425 curt = null;
12426 }
12427 }
12428 }
12429 while (ir < NR) {
12430 if (receivers == null) {
12431 receivers = new ArrayList();
12432 }
12433 receivers.add(registeredReceivers.get(ir));
12434 ir++;
12435 }
12436
12437 if ((receivers != null && receivers.size() > 0)
12438 || resultTo != null) {
12439 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12440 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012441 receivers, resultTo, resultCode, resultData, map, ordered,
12442 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012443 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012444 TAG, "Enqueueing ordered broadcast " + r
12445 + ": prev had " + mOrderedBroadcasts.size());
12446 if (DEBUG_BROADCAST) {
12447 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012448 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012449 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012450 boolean replaced = false;
12451 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012452 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012453 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012454 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012455 "***** DROPPING ORDERED: " + intent);
12456 mOrderedBroadcasts.set(i, r);
12457 replaced = true;
12458 break;
12459 }
12460 }
12461 }
12462 if (!replaced) {
12463 mOrderedBroadcasts.add(r);
12464 scheduleBroadcastsLocked();
12465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012466 }
12467
12468 return BROADCAST_SUCCESS;
12469 }
12470
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012471 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012472 // Refuse possible leaked file descriptors
12473 if (intent != null && intent.hasFileDescriptors() == true) {
12474 throw new IllegalArgumentException("File descriptors passed in Intent");
12475 }
12476
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012477 int flags = intent.getFlags();
12478
12479 if (!mProcessesReady) {
12480 // if the caller really truly claims to know what they're doing, go
12481 // ahead and allow the broadcast without launching any receivers
12482 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12483 intent = new Intent(intent);
12484 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12485 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12486 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12487 + " before boot completion");
12488 throw new IllegalStateException("Cannot broadcast before boot completed");
12489 }
12490 }
12491
12492 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12493 throw new IllegalArgumentException(
12494 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12495 }
12496
12497 return intent;
12498 }
12499
12500 public final int broadcastIntent(IApplicationThread caller,
12501 Intent intent, String resolvedType, IIntentReceiver resultTo,
12502 int resultCode, String resultData, Bundle map,
12503 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012505 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12508 final int callingPid = Binder.getCallingPid();
12509 final int callingUid = Binder.getCallingUid();
12510 final long origId = Binder.clearCallingIdentity();
12511 int res = broadcastIntentLocked(callerApp,
12512 callerApp != null ? callerApp.info.packageName : null,
12513 intent, resolvedType, resultTo,
12514 resultCode, resultData, map, requiredPermission, serialized,
12515 sticky, callingPid, callingUid);
12516 Binder.restoreCallingIdentity(origId);
12517 return res;
12518 }
12519 }
12520
12521 int broadcastIntentInPackage(String packageName, int uid,
12522 Intent intent, String resolvedType, IIntentReceiver resultTo,
12523 int resultCode, String resultData, Bundle map,
12524 String requiredPermission, boolean serialized, boolean sticky) {
12525 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012526 intent = verifyBroadcastLocked(intent);
12527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012528 final long origId = Binder.clearCallingIdentity();
12529 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12530 resultTo, resultCode, resultData, map, requiredPermission,
12531 serialized, sticky, -1, uid);
12532 Binder.restoreCallingIdentity(origId);
12533 return res;
12534 }
12535 }
12536
12537 public final void unbroadcastIntent(IApplicationThread caller,
12538 Intent intent) {
12539 // Refuse possible leaked file descriptors
12540 if (intent != null && intent.hasFileDescriptors() == true) {
12541 throw new IllegalArgumentException("File descriptors passed in Intent");
12542 }
12543
12544 synchronized(this) {
12545 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12546 != PackageManager.PERMISSION_GRANTED) {
12547 String msg = "Permission Denial: unbroadcastIntent() from pid="
12548 + Binder.getCallingPid()
12549 + ", uid=" + Binder.getCallingUid()
12550 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012551 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012552 throw new SecurityException(msg);
12553 }
12554 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12555 if (list != null) {
12556 int N = list.size();
12557 int i;
12558 for (i=0; i<N; i++) {
12559 if (intent.filterEquals(list.get(i))) {
12560 list.remove(i);
12561 break;
12562 }
12563 }
12564 }
12565 }
12566 }
12567
12568 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12569 String resultData, Bundle resultExtras, boolean resultAbort,
12570 boolean explicit) {
12571 if (mOrderedBroadcasts.size() == 0) {
12572 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012573 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574 }
12575 return false;
12576 }
12577 BroadcastRecord r = mOrderedBroadcasts.get(0);
12578 if (r.receiver == null) {
12579 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012580 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581 }
12582 return false;
12583 }
12584 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012585 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012586 return false;
12587 }
12588 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012589 r.state = BroadcastRecord.IDLE;
12590 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012591 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012592 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012593 }
12594 }
12595 r.receiver = null;
12596 r.intent.setComponent(null);
12597 if (r.curApp != null) {
12598 r.curApp.curReceiver = null;
12599 }
12600 if (r.curFilter != null) {
12601 r.curFilter.receiverList.curBroadcast = null;
12602 }
12603 r.curFilter = null;
12604 r.curApp = null;
12605 r.curComponent = null;
12606 r.curReceiver = null;
12607 mPendingBroadcast = null;
12608
12609 r.resultCode = resultCode;
12610 r.resultData = resultData;
12611 r.resultExtras = resultExtras;
12612 r.resultAbort = resultAbort;
12613
12614 // We will process the next receiver right now if this is finishing
12615 // an app receiver (which is always asynchronous) or after we have
12616 // come back from calling a receiver.
12617 return state == BroadcastRecord.APP_RECEIVE
12618 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12619 }
12620
12621 public void finishReceiver(IBinder who, int resultCode, String resultData,
12622 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012623 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012624
12625 // Refuse possible leaked file descriptors
12626 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12627 throw new IllegalArgumentException("File descriptors passed in Bundle");
12628 }
12629
12630 boolean doNext;
12631
12632 final long origId = Binder.clearCallingIdentity();
12633
12634 synchronized(this) {
12635 doNext = finishReceiverLocked(
12636 who, resultCode, resultData, resultExtras, resultAbort, true);
12637 }
12638
12639 if (doNext) {
12640 processNextBroadcast(false);
12641 }
12642 trimApplications();
12643
12644 Binder.restoreCallingIdentity(origId);
12645 }
12646
Jeff Brown4d94a762010-09-23 11:33:28 -070012647 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012648 if (r.nextReceiver > 0) {
12649 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12650 if (curReceiver instanceof BroadcastFilter) {
12651 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012652 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012653 System.identityHashCode(r),
12654 r.intent.getAction(),
12655 r.nextReceiver - 1,
12656 System.identityHashCode(bf));
12657 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012658 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012659 System.identityHashCode(r),
12660 r.intent.getAction(),
12661 r.nextReceiver - 1,
12662 ((ResolveInfo)curReceiver).toString());
12663 }
12664 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012665 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012666 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012667 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012668 System.identityHashCode(r),
12669 r.intent.getAction(),
12670 r.nextReceiver,
12671 "NONE");
12672 }
12673 }
12674
Jeff Brown4d94a762010-09-23 11:33:28 -070012675 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12676 if (! mPendingBroadcastTimeoutMessage) {
12677 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12678 mHandler.sendMessageAtTime(msg, timeoutTime);
12679 mPendingBroadcastTimeoutMessage = true;
12680 }
12681 }
12682
12683 private final void cancelBroadcastTimeoutLocked() {
12684 if (mPendingBroadcastTimeoutMessage) {
12685 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12686 mPendingBroadcastTimeoutMessage = false;
12687 }
12688 }
12689
12690 private final void broadcastTimeoutLocked(boolean fromMsg) {
12691 if (fromMsg) {
12692 mPendingBroadcastTimeoutMessage = false;
12693 }
12694
12695 if (mOrderedBroadcasts.size() == 0) {
12696 return;
12697 }
12698
12699 long now = SystemClock.uptimeMillis();
12700 BroadcastRecord r = mOrderedBroadcasts.get(0);
12701 if (fromMsg) {
12702 if (mDidDexOpt) {
12703 // Delay timeouts until dexopt finishes.
12704 mDidDexOpt = false;
12705 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12706 setBroadcastTimeoutLocked(timeoutTime);
12707 return;
12708 }
12709 if (! mProcessesReady) {
12710 // Only process broadcast timeouts if the system is ready. That way
12711 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12712 // to do heavy lifting for system up.
12713 return;
12714 }
12715
12716 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12717 if (timeoutTime > now) {
12718 // We can observe premature timeouts because we do not cancel and reset the
12719 // broadcast timeout message after each receiver finishes. Instead, we set up
12720 // an initial timeout then kick it down the road a little further as needed
12721 // when it expires.
12722 if (DEBUG_BROADCAST) Slog.v(TAG,
12723 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12724 + timeoutTime);
12725 setBroadcastTimeoutLocked(timeoutTime);
12726 return;
12727 }
12728 }
12729
12730 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12731 + ", started " + (now - r.receiverTime) + "ms ago");
12732 r.receiverTime = now;
12733 r.anrCount++;
12734
12735 // Current receiver has passed its expiration date.
12736 if (r.nextReceiver <= 0) {
12737 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12738 return;
12739 }
12740
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012741 ProcessRecord app = null;
12742 String anrMessage = null;
12743
Jeff Brown4d94a762010-09-23 11:33:28 -070012744 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12745 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12746 logBroadcastReceiverDiscardLocked(r);
12747 if (curReceiver instanceof BroadcastFilter) {
12748 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12749 if (bf.receiverList.pid != 0
12750 && bf.receiverList.pid != MY_PID) {
12751 synchronized (this.mPidsSelfLocked) {
12752 app = this.mPidsSelfLocked.get(
12753 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012755 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012756 } else {
12757 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012759
Jeff Brown4d94a762010-09-23 11:33:28 -070012760 if (app != null) {
12761 anrMessage = "Broadcast of " + r.intent.toString();
12762 }
12763
12764 if (mPendingBroadcast == r) {
12765 mPendingBroadcast = null;
12766 }
12767
12768 // Move on to the next receiver.
12769 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12770 r.resultExtras, r.resultAbort, true);
12771 scheduleBroadcastsLocked();
12772
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012773 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012774 // Post the ANR to the handler since we do not want to process ANRs while
12775 // potentially holding our lock.
12776 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 }
12779
12780 private final void processCurBroadcastLocked(BroadcastRecord r,
12781 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012782 if (DEBUG_BROADCAST) Slog.v(TAG,
12783 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012784 if (app.thread == null) {
12785 throw new RemoteException();
12786 }
12787 r.receiver = app.thread.asBinder();
12788 r.curApp = app;
12789 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012790 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012791
12792 // Tell the application to launch this receiver.
12793 r.intent.setComponent(r.curComponent);
12794
12795 boolean started = false;
12796 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012797 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012798 "Delivering to component " + r.curComponent
12799 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012800 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012801 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012802 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012803 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012804 if (DEBUG_BROADCAST) Slog.v(TAG,
12805 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012806 started = true;
12807 } finally {
12808 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012809 if (DEBUG_BROADCAST) Slog.v(TAG,
12810 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012811 r.receiver = null;
12812 r.curApp = null;
12813 app.curReceiver = null;
12814 }
12815 }
12816
12817 }
12818
Jeff Brown4d94a762010-09-23 11:33:28 -070012819 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012820 Intent intent, int resultCode, String data, Bundle extras,
12821 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012822 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012823 if (app != null && app.thread != null) {
12824 // If we have an app thread, do the call through that so it is
12825 // correctly ordered with other one-way calls.
12826 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012827 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012828 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012829 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012830 }
12831 }
12832
Jeff Brown4d94a762010-09-23 11:33:28 -070012833 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012834 BroadcastFilter filter, boolean ordered) {
12835 boolean skip = false;
12836 if (filter.requiredPermission != null) {
12837 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012838 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012840 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012841 + r.intent.toString()
12842 + " from " + r.callerPackage + " (pid="
12843 + r.callingPid + ", uid=" + r.callingUid + ")"
12844 + " requires " + filter.requiredPermission
12845 + " due to registered receiver " + filter);
12846 skip = true;
12847 }
12848 }
12849 if (r.requiredPermission != null) {
12850 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012851 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012852 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012853 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012854 + r.intent.toString()
12855 + " to " + filter.receiverList.app
12856 + " (pid=" + filter.receiverList.pid
12857 + ", uid=" + filter.receiverList.uid + ")"
12858 + " requires " + r.requiredPermission
12859 + " due to sender " + r.callerPackage
12860 + " (uid " + r.callingUid + ")");
12861 skip = true;
12862 }
12863 }
12864
12865 if (!skip) {
12866 // If this is not being sent as an ordered broadcast, then we
12867 // don't want to touch the fields that keep track of the current
12868 // state of ordered broadcasts.
12869 if (ordered) {
12870 r.receiver = filter.receiverList.receiver.asBinder();
12871 r.curFilter = filter;
12872 filter.receiverList.curBroadcast = r;
12873 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012874 if (filter.receiverList.app != null) {
12875 // Bump hosting application to no longer be in background
12876 // scheduling class. Note that we can't do that if there
12877 // isn't an app... but we can only be in that case for
12878 // things that directly call the IActivityManager API, which
12879 // are already core system stuff so don't matter for this.
12880 r.curApp = filter.receiverList.app;
12881 filter.receiverList.app.curReceiver = r;
12882 updateOomAdjLocked();
12883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012884 }
12885 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012886 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012887 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012888 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012889 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012891 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012892 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012893 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012894 if (ordered) {
12895 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12896 }
12897 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012898 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012899 if (ordered) {
12900 r.receiver = null;
12901 r.curFilter = null;
12902 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012903 if (filter.receiverList.app != null) {
12904 filter.receiverList.app.curReceiver = null;
12905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906 }
12907 }
12908 }
12909 }
12910
Dianne Hackborn12527f92009-11-11 17:39:50 -080012911 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12912 if (r.callingUid < 0) {
12913 // This was from a registerReceiver() call; ignore it.
12914 return;
12915 }
12916 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12917 MAX_BROADCAST_HISTORY-1);
12918 r.finishTime = SystemClock.uptimeMillis();
12919 mBroadcastHistory[0] = r;
12920 }
12921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012922 private final void processNextBroadcast(boolean fromMsg) {
12923 synchronized(this) {
12924 BroadcastRecord r;
12925
Joe Onorato8a9b2202010-02-26 18:56:32 -080012926 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012927 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012928 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012929
12930 updateCpuStats();
12931
12932 if (fromMsg) {
12933 mBroadcastsScheduled = false;
12934 }
12935
12936 // First, deliver any non-serialized broadcasts right away.
12937 while (mParallelBroadcasts.size() > 0) {
12938 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012939 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012940 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012942 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012943 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012944 for (int i=0; i<N; i++) {
12945 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012946 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012947 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012948 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012949 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012950 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012951 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012952 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012953 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012954 }
12955
12956 // Now take care of the next serialized one...
12957
12958 // If we are waiting for a process to come up to handle the next
12959 // broadcast, then do nothing at this point. Just in case, we
12960 // check that the process we're waiting for still exists.
12961 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012962 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012963 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012964 + mPendingBroadcast.curApp);
12965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966
12967 boolean isDead;
12968 synchronized (mPidsSelfLocked) {
12969 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12970 }
12971 if (!isDead) {
12972 // It's still alive, so keep waiting
12973 return;
12974 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012975 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012976 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012977 mPendingBroadcast.state = BroadcastRecord.IDLE;
12978 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012979 mPendingBroadcast = null;
12980 }
12981 }
12982
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012983 boolean looped = false;
12984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012985 do {
12986 if (mOrderedBroadcasts.size() == 0) {
12987 // No more broadcasts pending, so all done!
12988 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012989 if (looped) {
12990 // If we had finished the last ordered broadcast, then
12991 // make sure all processes have correct oom and sched
12992 // adjustments.
12993 updateOomAdjLocked();
12994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 return;
12996 }
12997 r = mOrderedBroadcasts.get(0);
12998 boolean forceReceive = false;
12999
13000 // Ensure that even if something goes awry with the timeout
13001 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013002 // and continue to make progress.
13003 //
13004 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070013005 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013006 // one time heavy lifting after system upgrades and can take
13007 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013008 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013009 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013010 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 if ((numReceivers > 0) &&
13012 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013013 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 + " now=" + now
13015 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080013016 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017 + " intent=" + r.intent
13018 + " numReceivers=" + numReceivers
13019 + " nextReceiver=" + r.nextReceiver
13020 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070013021 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013022 forceReceive = true;
13023 r.state = BroadcastRecord.IDLE;
13024 }
13025 }
13026
13027 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013028 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013029 "processNextBroadcast() called when not idle (state="
13030 + r.state + ")");
13031 return;
13032 }
13033
13034 if (r.receivers == null || r.nextReceiver >= numReceivers
13035 || r.resultAbort || forceReceive) {
13036 // No more receivers for this broadcast! Send the final
13037 // result if requested...
13038 if (r.resultTo != null) {
13039 try {
13040 if (DEBUG_BROADCAST) {
13041 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013042 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013043 + " seq=" + seq + " app=" + r.callerApp);
13044 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013045 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013046 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013047 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020013048 // Set this to null so that the reference
13049 // (local and remote) isnt kept in the mBroadcastHistory.
13050 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013051 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013052 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 }
13054 }
13055
Joe Onorato8a9b2202010-02-26 18:56:32 -080013056 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070013057 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013058
Joe Onorato8a9b2202010-02-26 18:56:32 -080013059 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013060 + r);
13061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013062 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080013063 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013064 mOrderedBroadcasts.remove(0);
13065 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013066 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013067 continue;
13068 }
13069 } while (r == null);
13070
13071 // Get the next receiver...
13072 int recIdx = r.nextReceiver++;
13073
13074 // Keep track of when this receiver started, and make sure there
13075 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080013076 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013077 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080013078 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013079 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013080 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013081 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013082 }
13083 if (! mPendingBroadcastTimeoutMessage) {
13084 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013085 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070013086 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
13087 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013088 }
13089
13090 Object nextReceiver = r.receivers.get(recIdx);
13091 if (nextReceiver instanceof BroadcastFilter) {
13092 // Simple case: this is a registered receiver who gets
13093 // a direct call.
13094 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013095 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013096 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013097 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013098 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013099 if (r.receiver == null || !r.ordered) {
13100 // The receiver has already finished, so schedule to
13101 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013102 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
13103 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013104 r.state = BroadcastRecord.IDLE;
13105 scheduleBroadcastsLocked();
13106 }
13107 return;
13108 }
13109
13110 // Hard case: need to instantiate the receiver, possibly
13111 // starting its application process to host it.
13112
13113 ResolveInfo info =
13114 (ResolveInfo)nextReceiver;
13115
13116 boolean skip = false;
13117 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013118 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
13119 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013120 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013121 if (!info.activityInfo.exported) {
13122 Slog.w(TAG, "Permission Denial: broadcasting "
13123 + r.intent.toString()
13124 + " from " + r.callerPackage + " (pid=" + r.callingPid
13125 + ", uid=" + r.callingUid + ")"
13126 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
13127 + " due to receiver " + info.activityInfo.packageName
13128 + "/" + info.activityInfo.name);
13129 } else {
13130 Slog.w(TAG, "Permission Denial: broadcasting "
13131 + r.intent.toString()
13132 + " from " + r.callerPackage + " (pid=" + r.callingPid
13133 + ", uid=" + r.callingUid + ")"
13134 + " requires " + info.activityInfo.permission
13135 + " due to receiver " + info.activityInfo.packageName
13136 + "/" + info.activityInfo.name);
13137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 skip = true;
13139 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013140 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013141 r.requiredPermission != null) {
13142 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013143 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013144 checkPermission(r.requiredPermission,
13145 info.activityInfo.applicationInfo.packageName);
13146 } catch (RemoteException e) {
13147 perm = PackageManager.PERMISSION_DENIED;
13148 }
13149 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013150 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 + r.intent + " to "
13152 + info.activityInfo.applicationInfo.packageName
13153 + " requires " + r.requiredPermission
13154 + " due to sender " + r.callerPackage
13155 + " (uid " + r.callingUid + ")");
13156 skip = true;
13157 }
13158 }
13159 if (r.curApp != null && r.curApp.crashing) {
13160 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013161 if (DEBUG_BROADCAST) Slog.v(TAG,
13162 "Skipping deliver ordered " + r + " to " + r.curApp
13163 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013164 skip = true;
13165 }
13166
13167 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013168 if (DEBUG_BROADCAST) Slog.v(TAG,
13169 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013170 r.receiver = null;
13171 r.curFilter = null;
13172 r.state = BroadcastRecord.IDLE;
13173 scheduleBroadcastsLocked();
13174 return;
13175 }
13176
13177 r.state = BroadcastRecord.APP_RECEIVE;
13178 String targetProcess = info.activityInfo.processName;
13179 r.curComponent = new ComponentName(
13180 info.activityInfo.applicationInfo.packageName,
13181 info.activityInfo.name);
13182 r.curReceiver = info.activityInfo;
13183
Dianne Hackborne7f97212011-02-24 14:40:20 -080013184 // Broadcast is being executed, its package can't be stopped.
13185 try {
13186 AppGlobals.getPackageManager().setPackageStoppedState(
13187 r.curComponent.getPackageName(), false);
13188 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080013189 } catch (IllegalArgumentException e) {
13190 Slog.w(TAG, "Failed trying to unstop package "
13191 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080013192 }
13193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013194 // Is this receiver's application already running?
13195 ProcessRecord app = getProcessRecordLocked(targetProcess,
13196 info.activityInfo.applicationInfo.uid);
13197 if (app != null && app.thread != null) {
13198 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013199 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013200 processCurBroadcastLocked(r, app);
13201 return;
13202 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013203 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013204 + r.curComponent, e);
13205 }
13206
13207 // If a dead object exception was thrown -- fall through to
13208 // restart the application.
13209 }
13210
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013211 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013212 if (DEBUG_BROADCAST) Slog.v(TAG,
13213 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013214 if ((r.curApp=startProcessLocked(targetProcess,
13215 info.activityInfo.applicationInfo, true,
13216 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013217 "broadcast", r.curComponent,
13218 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13219 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013220 // Ah, this recipient is unavailable. Finish it if necessary,
13221 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013222 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013223 + info.activityInfo.applicationInfo.packageName + "/"
13224 + info.activityInfo.applicationInfo.uid + " for broadcast "
13225 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070013226 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013227 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13228 r.resultExtras, r.resultAbort, true);
13229 scheduleBroadcastsLocked();
13230 r.state = BroadcastRecord.IDLE;
13231 return;
13232 }
13233
13234 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013235 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013236 }
13237 }
13238
13239 // =========================================================
13240 // INSTRUMENTATION
13241 // =========================================================
13242
13243 public boolean startInstrumentation(ComponentName className,
13244 String profileFile, int flags, Bundle arguments,
13245 IInstrumentationWatcher watcher) {
13246 // Refuse possible leaked file descriptors
13247 if (arguments != null && arguments.hasFileDescriptors()) {
13248 throw new IllegalArgumentException("File descriptors passed in Bundle");
13249 }
13250
13251 synchronized(this) {
13252 InstrumentationInfo ii = null;
13253 ApplicationInfo ai = null;
13254 try {
13255 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013256 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013257 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013258 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013259 } catch (PackageManager.NameNotFoundException e) {
13260 }
13261 if (ii == null) {
13262 reportStartInstrumentationFailure(watcher, className,
13263 "Unable to find instrumentation info for: " + className);
13264 return false;
13265 }
13266 if (ai == null) {
13267 reportStartInstrumentationFailure(watcher, className,
13268 "Unable to find instrumentation target package: " + ii.targetPackage);
13269 return false;
13270 }
13271
13272 int match = mContext.getPackageManager().checkSignatures(
13273 ii.targetPackage, ii.packageName);
13274 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13275 String msg = "Permission Denial: starting instrumentation "
13276 + className + " from pid="
13277 + Binder.getCallingPid()
13278 + ", uid=" + Binder.getCallingPid()
13279 + " not allowed because package " + ii.packageName
13280 + " does not have a signature matching the target "
13281 + ii.targetPackage;
13282 reportStartInstrumentationFailure(watcher, className, msg);
13283 throw new SecurityException(msg);
13284 }
13285
13286 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013287 // Instrumentation can kill and relaunch even persistent processes
13288 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013289 ProcessRecord app = addAppLocked(ai);
13290 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013291 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 app.instrumentationProfileFile = profileFile;
13293 app.instrumentationArguments = arguments;
13294 app.instrumentationWatcher = watcher;
13295 app.instrumentationResultClass = className;
13296 Binder.restoreCallingIdentity(origId);
13297 }
13298
13299 return true;
13300 }
13301
13302 /**
13303 * Report errors that occur while attempting to start Instrumentation. Always writes the
13304 * error to the logs, but if somebody is watching, send the report there too. This enables
13305 * the "am" command to report errors with more information.
13306 *
13307 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13308 * @param cn The component name of the instrumentation.
13309 * @param report The error report.
13310 */
13311 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13312 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013313 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013314 try {
13315 if (watcher != null) {
13316 Bundle results = new Bundle();
13317 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13318 results.putString("Error", report);
13319 watcher.instrumentationStatus(cn, -1, results);
13320 }
13321 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013322 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 }
13324 }
13325
13326 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13327 if (app.instrumentationWatcher != null) {
13328 try {
13329 // NOTE: IInstrumentationWatcher *must* be oneway here
13330 app.instrumentationWatcher.instrumentationFinished(
13331 app.instrumentationClass,
13332 resultCode,
13333 results);
13334 } catch (RemoteException e) {
13335 }
13336 }
13337 app.instrumentationWatcher = null;
13338 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013339 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013340 app.instrumentationProfileFile = null;
13341 app.instrumentationArguments = null;
13342
Christopher Tate3dacd842011-08-19 14:56:15 -070013343 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013344 }
13345
13346 public void finishInstrumentation(IApplicationThread target,
13347 int resultCode, Bundle results) {
13348 // Refuse possible leaked file descriptors
13349 if (results != null && results.hasFileDescriptors()) {
13350 throw new IllegalArgumentException("File descriptors passed in Intent");
13351 }
13352
13353 synchronized(this) {
13354 ProcessRecord app = getRecordForAppLocked(target);
13355 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013356 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013357 return;
13358 }
13359 final long origId = Binder.clearCallingIdentity();
13360 finishInstrumentationLocked(app, resultCode, results);
13361 Binder.restoreCallingIdentity(origId);
13362 }
13363 }
13364
13365 // =========================================================
13366 // CONFIGURATION
13367 // =========================================================
13368
13369 public ConfigurationInfo getDeviceConfigurationInfo() {
13370 ConfigurationInfo config = new ConfigurationInfo();
13371 synchronized (this) {
13372 config.reqTouchScreen = mConfiguration.touchscreen;
13373 config.reqKeyboardType = mConfiguration.keyboard;
13374 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013375 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13376 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013377 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13378 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013379 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13380 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13382 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013383 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013384 }
13385 return config;
13386 }
13387
13388 public Configuration getConfiguration() {
13389 Configuration ci;
13390 synchronized(this) {
13391 ci = new Configuration(mConfiguration);
13392 }
13393 return ci;
13394 }
13395
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013396 public void updatePersistentConfiguration(Configuration values) {
13397 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13398 "updateConfiguration()");
13399 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13400 "updateConfiguration()");
13401 if (values == null) {
13402 throw new NullPointerException("Configuration must not be null");
13403 }
13404
13405 synchronized(this) {
13406 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013407 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013408 Binder.restoreCallingIdentity(origId);
13409 }
13410 }
13411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013412 public void updateConfiguration(Configuration values) {
13413 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13414 "updateConfiguration()");
13415
13416 synchronized(this) {
13417 if (values == null && mWindowManager != null) {
13418 // sentinel: fetch the current configuration from the window manager
13419 values = mWindowManager.computeNewConfiguration();
13420 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013421
13422 if (mWindowManager != null) {
13423 mProcessList.applyDisplaySize(mWindowManager);
13424 }
13425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013426 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013427 if (values != null) {
13428 Settings.System.clearConfiguration(values);
13429 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013430 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013431 Binder.restoreCallingIdentity(origId);
13432 }
13433 }
13434
13435 /**
13436 * Do either or both things: (1) change the current configuration, and (2)
13437 * make sure the given activity is running with the (now) current
13438 * configuration. Returns true if the activity has been left running, or
13439 * false if <var>starting</var> is being destroyed to match the new
13440 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013441 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013442 */
13443 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013444 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013445 int changes = 0;
13446
13447 boolean kept = true;
13448
13449 if (values != null) {
13450 Configuration newConfig = new Configuration(mConfiguration);
13451 changes = newConfig.updateFrom(values);
13452 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013453 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013454 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013455 }
13456
Doug Zongker2bec3d42009-12-04 12:52:44 -080013457 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013458
Dianne Hackborn813075a62011-11-14 17:45:19 -080013459 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013460 saveLocaleLocked(values.locale,
13461 !values.locale.equals(mConfiguration.locale),
13462 values.userSetLocale);
13463 }
13464
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013465 mConfigurationSeq++;
13466 if (mConfigurationSeq <= 0) {
13467 mConfigurationSeq = 1;
13468 }
13469 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013470 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013471 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013472
13473 final Configuration configCopy = new Configuration(mConfiguration);
13474
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013475 AttributeCache ac = AttributeCache.instance();
13476 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013477 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013479
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013480 // Make sure all resources in our process are updated
13481 // right now, so that anyone who is going to retrieve
13482 // resource values after we return will be sure to get
13483 // the new ones. This is especially important during
13484 // boot, where the first config change needs to guarantee
13485 // all resources have that config before following boot
13486 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013487 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013488
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013489 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013490 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013491 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013492 mHandler.sendMessage(msg);
13493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013494
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013495 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13496 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013497 try {
13498 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013499 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013500 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013501 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013502 }
13503 } catch (Exception e) {
13504 }
13505 }
13506 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013507 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13508 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013509 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13510 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013511 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13512 broadcastIntentLocked(null, null,
13513 new Intent(Intent.ACTION_LOCALE_CHANGED),
13514 null, null, 0, null, null,
13515 null, false, false, MY_PID, Process.SYSTEM_UID);
13516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 }
13518 }
13519
13520 if (changes != 0 && starting == null) {
13521 // If the configuration changed, and the caller is not already
13522 // in the process of starting an activity, then find the top
13523 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013524 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013525 }
13526
13527 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013528 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013529 // And we need to make sure at this point that all other activities
13530 // are made visible with the correct configuration.
13531 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013532 }
13533
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013534 if (values != null && mWindowManager != null) {
13535 mWindowManager.setNewConfiguration(mConfiguration);
13536 }
13537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013538 return kept;
13539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013540
13541 /**
13542 * Save the locale. You must be inside a synchronized (this) block.
13543 */
13544 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13545 if(isDiff) {
13546 SystemProperties.set("user.language", l.getLanguage());
13547 SystemProperties.set("user.region", l.getCountry());
13548 }
13549
13550 if(isPersist) {
13551 SystemProperties.set("persist.sys.language", l.getLanguage());
13552 SystemProperties.set("persist.sys.country", l.getCountry());
13553 SystemProperties.set("persist.sys.localevar", l.getVariant());
13554 }
13555 }
13556
13557 // =========================================================
13558 // LIFETIME MANAGEMENT
13559 // =========================================================
13560
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013561 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013562 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013563 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013564 // This adjustment has already been computed. If we are calling
13565 // from the top, we may have already computed our adjustment with
13566 // an earlier hidden adjustment that isn't really for us... if
13567 // so, use the new hidden adjustment.
13568 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013569 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013570 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013571 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013572 }
13573
13574 if (app.thread == null) {
13575 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013576 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013577 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013578 }
13579
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013580 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13581 app.adjSource = null;
13582 app.adjTarget = null;
13583 app.empty = false;
13584 app.hidden = false;
13585
13586 final int activitiesSize = app.activities.size();
13587
Dianne Hackborn7d608422011-08-07 16:24:18 -070013588 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013589 // The max adjustment doesn't allow this app to be anything
13590 // below foreground, so it is not worth doing work for it.
13591 app.adjType = "fixed";
13592 app.adjSeq = mAdjSeq;
13593 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013594 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013595 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013596 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013597 // System process can do UI, and when they do we want to have
13598 // them trim their memory after the user leaves the UI. To
13599 // facilitate this, here we need to determine whether or not it
13600 // is currently showing UI.
13601 app.systemNoUi = true;
13602 if (app == TOP_APP) {
13603 app.systemNoUi = false;
13604 } else if (activitiesSize > 0) {
13605 for (int j = 0; j < activitiesSize; j++) {
13606 final ActivityRecord r = app.activities.get(j);
13607 if (r.visible) {
13608 app.systemNoUi = false;
13609 break;
13610 }
13611 }
13612 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013613 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013614 }
13615
13616 final boolean hadForegroundActivities = app.foregroundActivities;
13617
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013618 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013619 app.keeping = false;
13620 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013621
The Android Open Source Project4df24232009-03-05 14:34:35 -080013622 // Determine the importance of the process, starting with most
13623 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013624 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013625 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013626 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013627 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013628 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013629 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013630 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013631 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013632 } else if (app.instrumentationClass != null) {
13633 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013634 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013635 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013636 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013637 } else if (app.curReceiver != null ||
13638 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13639 // An app that is currently receiving a broadcast also
13640 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013641 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013642 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013643 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013644 } else if (app.executingServices.size() > 0) {
13645 // An app that is currently executing a service callback also
13646 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013647 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013648 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013649 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013650 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013651 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013652 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013653 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013654 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013655 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013656 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013657 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013658 // A very not-needed process. If this is lower in the lru list,
13659 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013660 adj = hiddenAdj;
13661 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013662 app.hidden = true;
13663 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013664 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013665 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013666
13667 // Examine all activities if not already foreground.
13668 if (!app.foregroundActivities && activitiesSize > 0) {
13669 for (int j = 0; j < activitiesSize; j++) {
13670 final ActivityRecord r = app.activities.get(j);
13671 if (r.visible) {
13672 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013673 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13674 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013675 app.adjType = "visible";
13676 }
13677 schedGroup = Process.THREAD_GROUP_DEFAULT;
13678 app.hidden = false;
13679 app.foregroundActivities = true;
13680 break;
13681 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13682 || r.state == ActivityState.STOPPING) {
13683 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013684 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13685 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013686 app.adjType = "stopping";
13687 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080013688 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013689 app.foregroundActivities = true;
13690 }
13691 }
13692 }
13693
Dianne Hackborn7d608422011-08-07 16:24:18 -070013694 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013695 if (app.foregroundServices) {
13696 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013697 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013698 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013699 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013700 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013701 } else if (app.forcingToForeground != null) {
13702 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013703 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013704 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013705 app.adjType = "force-foreground";
13706 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013707 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013708 }
13709 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013710
Dianne Hackborn7d608422011-08-07 16:24:18 -070013711 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013712 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013713 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013714 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013715 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013716 app.adjType = "heavy";
13717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013718
Dianne Hackborn7d608422011-08-07 16:24:18 -070013719 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013720 // This process is hosting what we currently consider to be the
13721 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013722 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013723 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013724 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013725 app.adjType = "home";
13726 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013727
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013728 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13729 && app.activities.size() > 0) {
13730 // This was the previous process that showed UI to the user.
13731 // We want to try to keep it around more aggressively, to give
13732 // a good experience around switching between two apps.
13733 adj = ProcessList.PREVIOUS_APP_ADJ;
13734 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13735 app.hidden = false;
13736 app.adjType = "previous";
13737 }
13738
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013739 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13740 + " reason=" + app.adjType);
13741
The Android Open Source Project4df24232009-03-05 14:34:35 -080013742 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013743 // there are applications dependent on our services or providers, but
13744 // this gives us a baseline and makes sure we don't get into an
13745 // infinite recursion.
13746 app.adjSeq = mAdjSeq;
13747 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013748
Christopher Tate6fa95972009-06-05 18:43:55 -070013749 if (mBackupTarget != null && app == mBackupTarget.app) {
13750 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013751 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013752 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013753 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013754 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013755 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013756 }
13757 }
13758
Dianne Hackborn7d608422011-08-07 16:24:18 -070013759 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013760 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013761 final long now = SystemClock.uptimeMillis();
13762 // This process is more important if the top activity is
13763 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013764 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013765 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013766 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013767 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013768 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013769 // If this process has shown some UI, let it immediately
13770 // go to the LRU list because it may be pretty heavy with
13771 // UI stuff. We'll tag it with a label just to help
13772 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013773 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013774 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013775 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013776 } else {
13777 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13778 // This service has seen some activity within
13779 // recent memory, so we will keep its process ahead
13780 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013781 if (adj > ProcessList.SERVICE_ADJ) {
13782 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013783 app.adjType = "started-services";
13784 app.hidden = false;
13785 }
13786 }
13787 // If we have let the service slide into the background
13788 // state, still have some text describing what it is doing
13789 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013790 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013791 app.adjType = "started-bg-services";
13792 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013793 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013794 // Don't kill this process because it is doing work; it
13795 // has said it is doing work.
13796 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013797 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013798 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013799 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013800 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013801 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013802 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013803 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013804 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013805 // XXX should compute this based on the max of
13806 // all connected clients.
13807 ConnectionRecord cr = clist.get(i);
13808 if (cr.binding.client == app) {
13809 // Binding to ourself is not interesting.
13810 continue;
13811 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013812 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013813 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013814 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013815 int myHiddenAdj = hiddenAdj;
13816 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013817 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013818 myHiddenAdj = client.hiddenAdj;
13819 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013820 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013821 }
13822 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013823 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013824 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013825 String adjType = null;
13826 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13827 // Not doing bind OOM management, so treat
13828 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013829 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013830 // If this process has shown some UI, let it immediately
13831 // go to the LRU list because it may be pretty heavy with
13832 // UI stuff. We'll tag it with a label just to help
13833 // debug and understand what is going on.
13834 if (adj > clientAdj) {
13835 adjType = "bound-bg-ui-services";
13836 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013837 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013838 clientAdj = adj;
13839 } else {
13840 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13841 // This service has not seen activity within
13842 // recent memory, so allow it to drop to the
13843 // LRU list if there is no other reason to keep
13844 // it around. We'll also tag it with a label just
13845 // to help debug and undertand what is going on.
13846 if (adj > clientAdj) {
13847 adjType = "bound-bg-services";
13848 }
13849 clientAdj = adj;
13850 }
13851 }
13852 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013853 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013854 // If this process has recently shown UI, and
13855 // the process that is binding to it is less
13856 // important than being visible, then we don't
13857 // care about the binding as much as we care
13858 // about letting this process get into the LRU
13859 // list to be killed and restarted if needed for
13860 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013861 if (app.hasShownUi && app != mHomeProcess
13862 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013863 adjType = "bound-bg-ui-services";
13864 } else {
13865 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13866 |Context.BIND_IMPORTANT)) != 0) {
13867 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013868 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13869 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13870 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13871 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13872 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013873 adj = clientAdj;
13874 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013875 app.pendingUiClean = true;
13876 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13877 adj = ProcessList.VISIBLE_APP_ADJ;
13878 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013879 }
13880 if (!client.hidden) {
13881 app.hidden = false;
13882 }
13883 if (client.keeping) {
13884 app.keeping = true;
13885 }
13886 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013887 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013888 }
13889 if (adjType != null) {
13890 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013891 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13892 .REASON_SERVICE_IN_USE;
13893 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013894 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013895 app.adjTarget = s.name;
13896 }
13897 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13898 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13899 schedGroup = Process.THREAD_GROUP_DEFAULT;
13900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013901 }
13902 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013903 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13904 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013905 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013906 (a.visible || a.state == ActivityState.RESUMED
13907 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013908 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013909 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13910 schedGroup = Process.THREAD_GROUP_DEFAULT;
13911 }
13912 app.hidden = false;
13913 app.adjType = "service";
13914 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13915 .REASON_SERVICE_IN_USE;
13916 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013917 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013918 app.adjTarget = s.name;
13919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013921 }
13922 }
13923 }
13924 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013925
Dianne Hackborn287952c2010-09-22 22:34:31 -070013926 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013927 // would like to avoid killing it unless it would prevent the current
13928 // application from running. By default we put the process in
13929 // with the rest of the background processes; as we scan through
13930 // its services we may bump it up from there.
13931 if (adj > hiddenAdj) {
13932 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013933 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013934 app.adjType = "bg-services";
13935 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013936 }
13937
Dianne Hackborn7d608422011-08-07 16:24:18 -070013938 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013939 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013940 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013941 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013942 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013943 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013944 if (cpr.clients.size() != 0) {
13945 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013946 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013947 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013948 if (client == app) {
13949 // Being our own client is not interesting.
13950 continue;
13951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013952 int myHiddenAdj = hiddenAdj;
13953 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013954 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013955 myHiddenAdj = client.hiddenAdj;
13956 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013957 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013958 }
13959 }
13960 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013961 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013962 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013963 if (app.hasShownUi && app != mHomeProcess
13964 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013965 app.adjType = "bg-ui-provider";
13966 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013967 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13968 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013969 app.adjType = "provider";
13970 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013971 if (!client.hidden) {
13972 app.hidden = false;
13973 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013974 if (client.keeping) {
13975 app.keeping = true;
13976 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013977 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13978 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013979 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013980 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013981 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013982 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013983 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13984 schedGroup = Process.THREAD_GROUP_DEFAULT;
13985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013986 }
13987 }
13988 // If the provider has external (non-framework) process
13989 // dependencies, ensure that its adjustment is at least
13990 // FOREGROUND_APP_ADJ.
13991 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013992 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13993 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013994 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013995 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013996 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013997 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013998 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013999 }
14000 }
14001 }
14002 }
14003
14004 app.curRawAdj = adj;
14005
Joe Onorato8a9b2202010-02-26 18:56:32 -080014006 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014007 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14008 if (adj > app.maxAdj) {
14009 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014010 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014011 schedGroup = Process.THREAD_GROUP_DEFAULT;
14012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014013 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014014 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014015 app.keeping = true;
14016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014017
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014018 if (app.hasAboveClient) {
14019 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14020 // then we need to drop its adjustment to be lower than the service's
14021 // in order to honor the request. We want to drop it by one adjustment
14022 // level... but there is special meaning applied to various levels so
14023 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014024 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014025 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014026 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14027 adj = ProcessList.VISIBLE_APP_ADJ;
14028 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14029 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14030 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14031 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014032 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014033 adj++;
14034 }
14035 }
14036
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014037 if (adj == ProcessList.SERVICE_ADJ) {
14038 if (doingAll) {
14039 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14040 mNewNumServiceProcs++;
14041 }
14042 if (app.serviceb) {
14043 adj = ProcessList.SERVICE_B_ADJ;
14044 }
14045 } else {
14046 app.serviceb = false;
14047 }
14048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014049 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014050 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014051
14052 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014053 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14054 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014055 }
14056
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014057 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014058 }
14059
14060 /**
14061 * Ask a given process to GC right now.
14062 */
14063 final void performAppGcLocked(ProcessRecord app) {
14064 try {
14065 app.lastRequestedGc = SystemClock.uptimeMillis();
14066 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014067 if (app.reportLowMemory) {
14068 app.reportLowMemory = false;
14069 app.thread.scheduleLowMemory();
14070 } else {
14071 app.thread.processInBackground();
14072 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014073 }
14074 } catch (Exception e) {
14075 // whatever.
14076 }
14077 }
14078
14079 /**
14080 * Returns true if things are idle enough to perform GCs.
14081 */
Josh Bartel7f208742010-02-25 11:01:44 -060014082 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014083 return mParallelBroadcasts.size() == 0
14084 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014085 && (mSleeping || (mMainStack.mResumedActivity != null &&
14086 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014087 }
14088
14089 /**
14090 * Perform GCs on all processes that are waiting for it, but only
14091 * if things are idle.
14092 */
14093 final void performAppGcsLocked() {
14094 final int N = mProcessesToGc.size();
14095 if (N <= 0) {
14096 return;
14097 }
Josh Bartel7f208742010-02-25 11:01:44 -060014098 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014099 while (mProcessesToGc.size() > 0) {
14100 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014101 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014102 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14103 <= SystemClock.uptimeMillis()) {
14104 // To avoid spamming the system, we will GC processes one
14105 // at a time, waiting a few seconds between each.
14106 performAppGcLocked(proc);
14107 scheduleAppGcsLocked();
14108 return;
14109 } else {
14110 // It hasn't been long enough since we last GCed this
14111 // process... put it in the list to wait for its time.
14112 addProcessToGcListLocked(proc);
14113 break;
14114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014115 }
14116 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014117
14118 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014119 }
14120 }
14121
14122 /**
14123 * If all looks good, perform GCs on all processes waiting for them.
14124 */
14125 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014126 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014127 performAppGcsLocked();
14128 return;
14129 }
14130 // Still not idle, wait some more.
14131 scheduleAppGcsLocked();
14132 }
14133
14134 /**
14135 * Schedule the execution of all pending app GCs.
14136 */
14137 final void scheduleAppGcsLocked() {
14138 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014139
14140 if (mProcessesToGc.size() > 0) {
14141 // Schedule a GC for the time to the next process.
14142 ProcessRecord proc = mProcessesToGc.get(0);
14143 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14144
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014145 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014146 long now = SystemClock.uptimeMillis();
14147 if (when < (now+GC_TIMEOUT)) {
14148 when = now + GC_TIMEOUT;
14149 }
14150 mHandler.sendMessageAtTime(msg, when);
14151 }
14152 }
14153
14154 /**
14155 * Add a process to the array of processes waiting to be GCed. Keeps the
14156 * list in sorted order by the last GC time. The process can't already be
14157 * on the list.
14158 */
14159 final void addProcessToGcListLocked(ProcessRecord proc) {
14160 boolean added = false;
14161 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14162 if (mProcessesToGc.get(i).lastRequestedGc <
14163 proc.lastRequestedGc) {
14164 added = true;
14165 mProcessesToGc.add(i+1, proc);
14166 break;
14167 }
14168 }
14169 if (!added) {
14170 mProcessesToGc.add(0, proc);
14171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014172 }
14173
14174 /**
14175 * Set up to ask a process to GC itself. This will either do it
14176 * immediately, or put it on the list of processes to gc the next
14177 * time things are idle.
14178 */
14179 final void scheduleAppGcLocked(ProcessRecord app) {
14180 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014181 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014182 return;
14183 }
14184 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014185 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014186 scheduleAppGcsLocked();
14187 }
14188 }
14189
Dianne Hackborn287952c2010-09-22 22:34:31 -070014190 final void checkExcessivePowerUsageLocked(boolean doKills) {
14191 updateCpuStatsNow();
14192
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014193 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014194 boolean doWakeKills = doKills;
14195 boolean doCpuKills = doKills;
14196 if (mLastPowerCheckRealtime == 0) {
14197 doWakeKills = false;
14198 }
14199 if (mLastPowerCheckUptime == 0) {
14200 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014201 }
14202 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014203 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014204 }
14205 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014206 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14207 final long curUptime = SystemClock.uptimeMillis();
14208 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14209 mLastPowerCheckRealtime = curRealtime;
14210 mLastPowerCheckUptime = curUptime;
14211 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14212 doWakeKills = false;
14213 }
14214 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14215 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014216 }
14217 int i = mLruProcesses.size();
14218 while (i > 0) {
14219 i--;
14220 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014221 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014222 long wtime;
14223 synchronized (stats) {
14224 wtime = stats.getProcessWakeTime(app.info.uid,
14225 app.pid, curRealtime);
14226 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014227 long wtimeUsed = wtime - app.lastWakeTime;
14228 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14229 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014230 StringBuilder sb = new StringBuilder(128);
14231 sb.append("Wake for ");
14232 app.toShortString(sb);
14233 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014234 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014235 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014236 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014237 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014238 sb.append((wtimeUsed*100)/realtimeSince);
14239 sb.append("%)");
14240 Slog.i(TAG, sb.toString());
14241 sb.setLength(0);
14242 sb.append("CPU for ");
14243 app.toShortString(sb);
14244 sb.append(": over ");
14245 TimeUtils.formatDuration(uptimeSince, sb);
14246 sb.append(" used ");
14247 TimeUtils.formatDuration(cputimeUsed, sb);
14248 sb.append(" (");
14249 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014250 sb.append("%)");
14251 Slog.i(TAG, sb.toString());
14252 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014253 // If a process has held a wake lock for more
14254 // than 50% of the time during this period,
14255 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014256 if (doWakeKills && realtimeSince > 0
14257 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14258 synchronized (stats) {
14259 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14260 realtimeSince, wtimeUsed);
14261 }
14262 Slog.w(TAG, "Excessive wake lock in " + app.processName
14263 + " (pid " + app.pid + "): held " + wtimeUsed
14264 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014265 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14266 app.processName, app.setAdj, "excessive wake lock");
14267 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014268 } else if (doCpuKills && uptimeSince > 0
14269 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14270 synchronized (stats) {
14271 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14272 uptimeSince, cputimeUsed);
14273 }
14274 Slog.w(TAG, "Excessive CPU in " + app.processName
14275 + " (pid " + app.pid + "): used " + cputimeUsed
14276 + " during " + uptimeSince);
14277 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14278 app.processName, app.setAdj, "excessive cpu");
14279 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014280 } else {
14281 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014282 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014283 }
14284 }
14285 }
14286 }
14287
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014288 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014289 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014290 app.hiddenAdj = hiddenAdj;
14291
14292 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014293 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014294 }
14295
Dianne Hackborn287952c2010-09-22 22:34:31 -070014296 final boolean wasKeeping = app.keeping;
14297
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014298 boolean success = true;
14299
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014300 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014301
Jeff Brown10e89712011-07-08 18:52:57 -070014302 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014303 if (false) {
14304 // Removing for now. Forcing GCs is not so useful anymore
14305 // with Dalvik, and the new memory level hint facility is
14306 // better for what we need to do these days.
14307 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14308 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14309 // If this app is transitioning from foreground to
14310 // non-foreground, have it do a gc.
14311 scheduleAppGcLocked(app);
14312 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14313 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14314 // Likewise do a gc when an app is moving in to the
14315 // background (such as a service stopping).
14316 scheduleAppGcLocked(app);
14317 }
Jeff Brown10e89712011-07-08 18:52:57 -070014318 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014319
Jeff Brown10e89712011-07-08 18:52:57 -070014320 if (wasKeeping && !app.keeping) {
14321 // This app is no longer something we want to keep. Note
14322 // its current wake lock time to later know to kill it if
14323 // it is not behaving well.
14324 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14325 synchronized (stats) {
14326 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14327 app.pid, SystemClock.elapsedRealtime());
14328 }
14329 app.lastCpuTime = app.curCpuTime;
14330 }
14331
14332 app.setRawAdj = app.curRawAdj;
14333 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014334
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014335 if (app.curAdj != app.setAdj) {
14336 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014337 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014338 TAG, "Set " + app.pid + " " + app.processName +
14339 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014340 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014341 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014342 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014343 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014344 }
14345 }
14346 if (app.setSchedGroup != app.curSchedGroup) {
14347 app.setSchedGroup = app.curSchedGroup;
14348 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14349 "Setting process group of " + app.processName
14350 + " to " + app.curSchedGroup);
14351 if (app.waitingToKill != null &&
14352 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14353 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14354 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14355 app.processName, app.setAdj, app.waitingToKill);
14356 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014357 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014358 } else {
14359 if (true) {
14360 long oldId = Binder.clearCallingIdentity();
14361 try {
14362 Process.setProcessGroup(app.pid, app.curSchedGroup);
14363 } catch (Exception e) {
14364 Slog.w(TAG, "Failed setting process group of " + app.pid
14365 + " to " + app.curSchedGroup);
14366 e.printStackTrace();
14367 } finally {
14368 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014369 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014370 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014371 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014372 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014373 app.thread.setSchedulingGroup(app.curSchedGroup);
14374 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014375 }
14376 }
14377 }
14378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014379 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014380 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014381 }
14382
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014383 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014384 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014385 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014386 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014387 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014388 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014389 }
14390 }
14391 return resumedActivity;
14392 }
14393
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014394 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014395 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014396 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14397 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014398 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14399 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014400
14401 mAdjSeq++;
14402
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014403 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014404 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14405 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014406 if (nowHidden != wasHidden) {
14407 // Changed to/from hidden state, so apps after it in the LRU
14408 // list may also be changed.
14409 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014410 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014411 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014412 }
14413
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014414 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014415 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014416 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14417
14418 if (false) {
14419 RuntimeException e = new RuntimeException();
14420 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014421 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014422 }
14423
14424 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014425 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014426
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014427 // Let's determine how many processes we have running vs.
14428 // how many slots we have for background processes; we may want
14429 // to put multiple processes in a slot of there are enough of
14430 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014431 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014432 int factor = (mLruProcesses.size()-4)/numSlots;
14433 if (factor < 1) factor = 1;
14434 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014435 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014436
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014437 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014438 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014439 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014440 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014441 while (i > 0) {
14442 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014443 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014444 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014445 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14446 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014447 && app.curAdj == curHiddenAdj) {
14448 step++;
14449 if (step >= factor) {
14450 step = 0;
14451 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014452 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014453 }
14454 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014455 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014456 numHidden++;
14457 if (numHidden > mProcessLimit) {
14458 Slog.i(TAG, "No longer want " + app.processName
14459 + " (pid " + app.pid + "): hidden #" + numHidden);
14460 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14461 app.processName, app.setAdj, "too many background");
14462 app.killedBackground = true;
14463 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014464 }
14465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014466 }
14467 }
14468
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014469 mNumServiceProcs = mNewNumServiceProcs;
14470
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014471 // Now determine the memory trimming level of background processes.
14472 // Unfortunately we need to start at the back of the list to do this
14473 // properly. We only do this if the number of background apps we
14474 // are managing to keep around is less than half the maximum we desire;
14475 // if we are keeping a good number around, we'll let them use whatever
14476 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014477 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014478 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014479 factor = numHidden/3;
14480 int minFactor = 2;
14481 if (mHomeProcess != null) minFactor++;
14482 if (mPreviousProcess != null) minFactor++;
14483 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014484 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014485 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014486 for (i=0; i<N; i++) {
14487 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014488 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14489 && app.curAdj != ProcessList.SERVICE_B_ADJ
14490 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014491 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14492 try {
14493 app.thread.scheduleTrimMemory(curLevel);
14494 } catch (RemoteException e) {
14495 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014496 if (false) {
14497 // For now we won't do this; our memory trimming seems
14498 // to be good enough at this point that destroying
14499 // activities causes more harm than good.
14500 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14501 && app != mHomeProcess && app != mPreviousProcess) {
14502 // For these apps we will also finish their activities
14503 // to help them free memory.
14504 mMainStack.destroyActivitiesLocked(app, false, "trim");
14505 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014506 }
14507 }
14508 app.trimMemoryLevel = curLevel;
14509 step++;
14510 if (step >= factor) {
14511 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014512 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14513 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014514 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014515 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14516 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014517 break;
14518 }
14519 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014520 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014521 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014522 && app.thread != null) {
14523 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014524 app.thread.scheduleTrimMemory(
14525 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014526 } catch (RemoteException e) {
14527 }
14528 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014529 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014530 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014531 && app.pendingUiClean) {
14532 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14533 && app.thread != null) {
14534 try {
14535 app.thread.scheduleTrimMemory(
14536 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14537 } catch (RemoteException e) {
14538 }
14539 }
14540 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14541 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014542 } else {
14543 app.trimMemoryLevel = 0;
14544 }
14545 }
14546 } else {
14547 final int N = mLruProcesses.size();
14548 for (i=0; i<N; i++) {
14549 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014550 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014551 && app.pendingUiClean) {
14552 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14553 && app.thread != null) {
14554 try {
14555 app.thread.scheduleTrimMemory(
14556 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14557 } catch (RemoteException e) {
14558 }
14559 }
14560 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14561 app.pendingUiClean = false;
14562 } else {
14563 app.trimMemoryLevel = 0;
14564 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014565 }
14566 }
14567
14568 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014569 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014571 }
14572
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014573 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014574 synchronized (this) {
14575 int i;
14576
14577 // First remove any unused application processes whose package
14578 // has been removed.
14579 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14580 final ProcessRecord app = mRemovedProcesses.get(i);
14581 if (app.activities.size() == 0
14582 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014583 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014584 TAG, "Exiting empty application process "
14585 + app.processName + " ("
14586 + (app.thread != null ? app.thread.asBinder() : null)
14587 + ")\n");
14588 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014589 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14590 app.processName, app.setAdj, "empty");
14591 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014592 } else {
14593 try {
14594 app.thread.scheduleExit();
14595 } catch (Exception e) {
14596 // Ignore exceptions.
14597 }
14598 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014599 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014600 mRemovedProcesses.remove(i);
14601
14602 if (app.persistent) {
14603 if (app.persistent) {
14604 addAppLocked(app.info);
14605 }
14606 }
14607 }
14608 }
14609
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014610 // Now update the oom adj for all processes.
14611 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014612 }
14613 }
14614
14615 /** This method sends the specified signal to each of the persistent apps */
14616 public void signalPersistentProcesses(int sig) throws RemoteException {
14617 if (sig != Process.SIGNAL_USR1) {
14618 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14619 }
14620
14621 synchronized (this) {
14622 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14623 != PackageManager.PERMISSION_GRANTED) {
14624 throw new SecurityException("Requires permission "
14625 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14626 }
14627
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014628 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14629 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014630 if (r.thread != null && r.persistent) {
14631 Process.sendSignal(r.pid, sig);
14632 }
14633 }
14634 }
14635 }
14636
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014637 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14638 if (proc == null || proc == mProfileProc) {
14639 proc = mProfileProc;
14640 path = mProfileFile;
14641 profileType = mProfileType;
14642 clearProfilerLocked();
14643 }
14644 if (proc == null) {
14645 return;
14646 }
14647 try {
14648 proc.thread.profilerControl(false, path, null, profileType);
14649 } catch (RemoteException e) {
14650 throw new IllegalStateException("Process disappeared");
14651 }
14652 }
14653
14654 private void clearProfilerLocked() {
14655 if (mProfileFd != null) {
14656 try {
14657 mProfileFd.close();
14658 } catch (IOException e) {
14659 }
14660 }
14661 mProfileApp = null;
14662 mProfileProc = null;
14663 mProfileFile = null;
14664 mProfileType = 0;
14665 mAutoStopProfiler = false;
14666 }
14667
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014668 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014669 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014670
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014671 try {
14672 synchronized (this) {
14673 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14674 // its own permission.
14675 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14676 != PackageManager.PERMISSION_GRANTED) {
14677 throw new SecurityException("Requires permission "
14678 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014679 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014680
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014681 if (start && fd == null) {
14682 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014683 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014684
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014685 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014686 if (process != null) {
14687 try {
14688 int pid = Integer.parseInt(process);
14689 synchronized (mPidsSelfLocked) {
14690 proc = mPidsSelfLocked.get(pid);
14691 }
14692 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014693 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014694
14695 if (proc == null) {
14696 HashMap<String, SparseArray<ProcessRecord>> all
14697 = mProcessNames.getMap();
14698 SparseArray<ProcessRecord> procs = all.get(process);
14699 if (procs != null && procs.size() > 0) {
14700 proc = procs.valueAt(0);
14701 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014702 }
14703 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014704
14705 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014706 throw new IllegalArgumentException("Unknown process: " + process);
14707 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014708
14709 if (start) {
14710 stopProfilerLocked(null, null, 0);
14711 setProfileApp(proc.info, proc.processName, path, fd, false);
14712 mProfileProc = proc;
14713 mProfileType = profileType;
14714 try {
14715 fd = fd.dup();
14716 } catch (IOException e) {
14717 fd = null;
14718 }
14719 proc.thread.profilerControl(start, path, fd, profileType);
14720 fd = null;
14721 mProfileFd = null;
14722 } else {
14723 stopProfilerLocked(proc, path, profileType);
14724 if (fd != null) {
14725 try {
14726 fd.close();
14727 } catch (IOException e) {
14728 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014729 }
14730 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014731
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014732 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014733 }
14734 } catch (RemoteException e) {
14735 throw new IllegalStateException("Process disappeared");
14736 } finally {
14737 if (fd != null) {
14738 try {
14739 fd.close();
14740 } catch (IOException e) {
14741 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014742 }
14743 }
14744 }
Andy McFadden824c5102010-07-09 16:26:57 -070014745
14746 public boolean dumpHeap(String process, boolean managed,
14747 String path, ParcelFileDescriptor fd) throws RemoteException {
14748
14749 try {
14750 synchronized (this) {
14751 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14752 // its own permission (same as profileControl).
14753 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14754 != PackageManager.PERMISSION_GRANTED) {
14755 throw new SecurityException("Requires permission "
14756 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14757 }
14758
14759 if (fd == null) {
14760 throw new IllegalArgumentException("null fd");
14761 }
14762
14763 ProcessRecord proc = null;
14764 try {
14765 int pid = Integer.parseInt(process);
14766 synchronized (mPidsSelfLocked) {
14767 proc = mPidsSelfLocked.get(pid);
14768 }
14769 } catch (NumberFormatException e) {
14770 }
14771
14772 if (proc == null) {
14773 HashMap<String, SparseArray<ProcessRecord>> all
14774 = mProcessNames.getMap();
14775 SparseArray<ProcessRecord> procs = all.get(process);
14776 if (procs != null && procs.size() > 0) {
14777 proc = procs.valueAt(0);
14778 }
14779 }
14780
14781 if (proc == null || proc.thread == null) {
14782 throw new IllegalArgumentException("Unknown process: " + process);
14783 }
14784
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014785 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14786 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014787 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14788 throw new SecurityException("Process not debuggable: " + proc);
14789 }
14790 }
14791
14792 proc.thread.dumpHeap(managed, path, fd);
14793 fd = null;
14794 return true;
14795 }
14796 } catch (RemoteException e) {
14797 throw new IllegalStateException("Process disappeared");
14798 } finally {
14799 if (fd != null) {
14800 try {
14801 fd.close();
14802 } catch (IOException e) {
14803 }
14804 }
14805 }
14806 }
14807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014808 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14809 public void monitor() {
14810 synchronized (this) { }
14811 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014812
14813 public void onCoreSettingsChange(Bundle settings) {
14814 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14815 ProcessRecord processRecord = mLruProcesses.get(i);
14816 try {
14817 if (processRecord.thread != null) {
14818 processRecord.thread.setCoreSettings(settings);
14819 }
14820 } catch (RemoteException re) {
14821 /* ignore */
14822 }
14823 }
14824 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014825
14826 // Multi-user methods
14827
14828 public boolean switchUser(int userid) {
14829 // TODO
14830 return true;
14831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014832}