blob: b6f118482bca7496c5ccf6ca815391469885f49d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700123import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.DataInputStream;
125import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.File;
127import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700130import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200131import java.io.IOException;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700132import java.io.InputStream;
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 // Maximum number of recent tasks that we can remember.
191 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700192
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700193 // Amount of time after a call to stopAppSwitches() during which we will
194 // prevent further untrusted switches from happening.
195 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196
197 // How long we wait for a launched process to attach to the activity manager
198 // before we decide it's never going to come up for real.
199 static final int PROC_START_TIMEOUT = 10*1000;
200
Jeff Brown3f9dd282011-07-08 20:02:19 -0700201 // How long we wait for a launched process to attach to the activity manager
202 // before we decide it's never going to come up for real, when the process was
203 // started with a wrapper for instrumentation (such as Valgrind) because it
204 // could take much longer than usual.
205 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 // How long to wait after going idle before forcing apps to GC.
208 static final int GC_TIMEOUT = 5*1000;
209
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700210 // The minimum amount of time between successive GC requests for a process.
211 static final int GC_MIN_INTERVAL = 60*1000;
212
Dianne Hackborn287952c2010-09-22 22:34:31 -0700213 // The rate at which we check for apps using excessive power -- 15 mins.
214 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
215
216 // The minimum sample duration we will allow before deciding we have
217 // enough data on wake locks to start killing things.
218 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
219
220 // The minimum sample duration we will allow before deciding we have
221 // enough data on CPU usage to start killing things.
222 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 // How long we allow a receiver to run before giving up on it.
225 static final int BROADCAST_TIMEOUT = 10*1000;
226
227 // How long we wait for a service to finish executing.
228 static final int SERVICE_TIMEOUT = 20*1000;
229
230 // How long a service needs to be running until restarting its process
231 // is no longer considered to be a relaunch of the service.
232 static final int SERVICE_RESTART_DURATION = 5*1000;
233
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700234 // How long a service needs to be running until it will start back at
235 // SERVICE_RESTART_DURATION after being killed.
236 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
237
238 // Multiplying factor to increase restart duration time by, for each time
239 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
240 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
241
242 // The minimum amount of time between restarting services that we allow.
243 // That is, when multiple services are restarting, we won't allow each
244 // to restart less than this amount of time from the last one.
245 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 // Maximum amount of time for there to be no activity on a service before
248 // we consider it non-essential and allow its process to go on the
249 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700250 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251
252 // How long we wait until we timeout on key dispatching.
253 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 // How long we wait until we timeout on key dispatching during instrumentation.
256 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
257
Dan Egnor42471dd2010-01-07 17:25:22 -0800258 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259
260 static final String[] EMPTY_STRING_ARRAY = new String[0];
261
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700262 public ActivityStack mMainStack;
263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700265 * Description of a request to start a new activity, which has been held
266 * due to app switches being disabled.
267 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700268 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700269 ActivityRecord r;
270 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700271 Uri[] grantedUriPermissions;
272 int grantedMode;
273 boolean onlyIfNeeded;
274 }
275
276 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
277 = new ArrayList<PendingActivityLaunch>();
278
279 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 * List of all active broadcasts that are to be executed immediately
281 * (without waiting for another broadcast to finish). Currently this only
282 * contains broadcasts to registered receivers, to avoid spinning up
283 * a bunch of processes to execute IntentReceiver components.
284 */
285 final ArrayList<BroadcastRecord> mParallelBroadcasts
286 = new ArrayList<BroadcastRecord>();
287
288 /**
289 * List of all active broadcasts that are to be executed one at a time.
290 * The object at the top of the list is the currently activity broadcasts;
291 * those after it are waiting for the top to finish..
292 */
293 final ArrayList<BroadcastRecord> mOrderedBroadcasts
294 = new ArrayList<BroadcastRecord>();
295
296 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800297 * Historical data of past broadcasts, for debugging.
298 */
Dianne Hackborn28695e02011-11-02 21:59:51 -0700299 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800300 final BroadcastRecord[] mBroadcastHistory
301 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
302
303 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 * Set when we current have a BROADCAST_INTENT_MSG in flight.
305 */
306 boolean mBroadcastsScheduled = false;
307
308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * Activity we have told the window manager to have key focus.
310 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700311 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700312 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 * List of intents that were used to start the most recent tasks.
314 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700315 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316
317 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700318 * Process management.
319 */
320 final ProcessList mProcessList = new ProcessList();
321
322 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 * All of the applications we currently have running organized by name.
324 * The keys are strings of the application package name (as
325 * returned by the package manager), and the keys are ApplicationRecord
326 * objects.
327 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700328 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329
330 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700331 * The currently running heavy-weight process, if any.
332 */
333 ProcessRecord mHeavyWeightProcess = null;
334
335 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 * The last time that various processes have crashed.
337 */
338 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
339
340 /**
341 * Set of applications that we consider to be bad, and will reject
342 * incoming broadcasts from (which the user has no control over).
343 * Processes are added to this set when they have crashed twice within
344 * a minimum amount of time; they are removed from it when they are
345 * later restarted (hopefully due to some user action). The value is the
346 * time it was added to the list.
347 */
348 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
349
350 /**
351 * All of the processes we currently have running organized by pid.
352 * The keys are the pid running the application.
353 *
354 * <p>NOTE: This object is protected by its own lock, NOT the global
355 * activity manager lock!
356 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700357 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358
359 /**
360 * All of the processes that have been forced to be foreground. The key
361 * is the pid of the caller who requested it (we hold a death
362 * link on it).
363 */
364 abstract class ForegroundToken implements IBinder.DeathRecipient {
365 int pid;
366 IBinder token;
367 }
368 final SparseArray<ForegroundToken> mForegroundProcesses
369 = new SparseArray<ForegroundToken>();
370
371 /**
372 * List of records for processes that someone had tried to start before the
373 * system was ready. We don't start them at that point, but ensure they
374 * are started by the time booting is complete.
375 */
376 final ArrayList<ProcessRecord> mProcessesOnHold
377 = new ArrayList<ProcessRecord>();
378
379 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 * List of persistent applications that are in the process
381 * of being started.
382 */
383 final ArrayList<ProcessRecord> mPersistentStartingProcesses
384 = new ArrayList<ProcessRecord>();
385
386 /**
387 * Processes that are being forcibly torn down.
388 */
389 final ArrayList<ProcessRecord> mRemovedProcesses
390 = new ArrayList<ProcessRecord>();
391
392 /**
393 * List of running applications, sorted by recent usage.
394 * The first entry in the list is the least recently used.
395 * It contains ApplicationRecord objects. This list does NOT include
396 * any persistent application records (since we never want to exit them).
397 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800398 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 = new ArrayList<ProcessRecord>();
400
401 /**
402 * List of processes that should gc as soon as things are idle.
403 */
404 final ArrayList<ProcessRecord> mProcessesToGc
405 = new ArrayList<ProcessRecord>();
406
407 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800408 * This is the process holding what we currently consider to be
409 * the "home" activity.
410 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700411 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800412
413 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700414 * This is the process holding the activity the user last visited that
415 * is in a different process from the one they are currently in.
416 */
417 ProcessRecord mPreviousProcess;
418
419 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400420 * Packages that the user has asked to have run in screen size
421 * compatibility mode instead of filling the screen.
422 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700423 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400424
425 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 * Set of PendingResultRecord objects that are currently active.
427 */
428 final HashSet mPendingResultRecords = new HashSet();
429
430 /**
431 * Set of IntentSenderRecord objects that are currently active.
432 */
433 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
434 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
435
436 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800437 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700438 * already logged DropBox entries for. Guarded by itself. If
439 * something (rogue user app) forces this over
440 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
441 */
442 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
443 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
444
445 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700446 * Strict Mode background batched logging state.
447 *
448 * The string buffer is guarded by itself, and its lock is also
449 * used to determine if another batched write is already
450 * in-flight.
451 */
452 private final StringBuilder mStrictModeBuffer = new StringBuilder();
453
454 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700455 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
456 */
457 private boolean mPendingBroadcastTimeoutMessage;
458
459 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 * Intent broadcast that we have tried to start, but are
461 * waiting for its application's process to be created. We only
462 * need one (instead of a list) because we always process broadcasts
463 * one at a time, so no others can be started while waiting for this
464 * one.
465 */
466 BroadcastRecord mPendingBroadcast = null;
467
468 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700469 * The receiver index that is pending, to restart the broadcast if needed.
470 */
471 int mPendingBroadcastRecvIndex;
472
473 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 * Keeps track of all IIntentReceivers that have been registered for
475 * broadcasts. Hash keys are the receiver IBinder, hash value is
476 * a ReceiverList.
477 */
478 final HashMap mRegisteredReceivers = new HashMap();
479
480 /**
481 * Resolver for broadcast intents to registered receivers.
482 * Holds BroadcastFilter (subclass of IntentFilter).
483 */
484 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
485 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
486 @Override
487 protected boolean allowFilterResult(
488 BroadcastFilter filter, List<BroadcastFilter> dest) {
489 IBinder target = filter.receiverList.receiver.asBinder();
490 for (int i=dest.size()-1; i>=0; i--) {
491 if (dest.get(i).receiverList.receiver.asBinder() == target) {
492 return false;
493 }
494 }
495 return true;
496 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700497
498 @Override
499 protected String packageForFilter(BroadcastFilter filter) {
500 return filter.packageName;
501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 };
503
504 /**
505 * State of all active sticky broadcasts. Keys are the action of the
506 * sticky Intent, values are an ArrayList of all broadcasted intents with
507 * that action (which should usually be one).
508 */
509 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
510 new HashMap<String, ArrayList<Intent>>();
511
512 /**
513 * All currently running services.
514 */
515 final HashMap<ComponentName, ServiceRecord> mServices =
516 new HashMap<ComponentName, ServiceRecord>();
517
518 /**
519 * All currently running services indexed by the Intent used to start them.
520 */
521 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
522 new HashMap<Intent.FilterComparison, ServiceRecord>();
523
524 /**
525 * All currently bound service connections. Keys are the IBinder of
526 * the client's IServiceConnection.
527 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700528 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
529 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530
531 /**
532 * List of services that we have been asked to start,
533 * but haven't yet been able to. It is used to hold start requests
534 * while waiting for their corresponding application thread to get
535 * going.
536 */
537 final ArrayList<ServiceRecord> mPendingServices
538 = new ArrayList<ServiceRecord>();
539
540 /**
541 * List of services that are scheduled to restart following a crash.
542 */
543 final ArrayList<ServiceRecord> mRestartingServices
544 = new ArrayList<ServiceRecord>();
545
546 /**
547 * List of services that are in the process of being stopped.
548 */
549 final ArrayList<ServiceRecord> mStoppingServices
550 = new ArrayList<ServiceRecord>();
551
552 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700553 * Backup/restore process management
554 */
555 String mBackupAppName = null;
556 BackupRecord mBackupTarget = null;
557
558 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 * List of PendingThumbnailsRecord objects of clients who are still
560 * waiting to receive all of the thumbnails for a task.
561 */
562 final ArrayList mPendingThumbnails = new ArrayList();
563
564 /**
565 * List of HistoryRecord objects that have been finished and must
566 * still report back to a pending thumbnail receiver.
567 */
568 final ArrayList mCancelledThumbnails = new ArrayList();
569
570 /**
571 * All of the currently running global content providers. Keys are a
572 * string containing the provider name and values are a
573 * ContentProviderRecord object containing the data about it. Note
574 * that a single provider may be published under multiple names, so
575 * there may be multiple entries here for a single one in mProvidersByClass.
576 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700577 final HashMap<String, ContentProviderRecord> mProvidersByName
578 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579
580 /**
581 * All of the currently running global content providers. Keys are a
582 * string containing the provider's implementation class and values are a
583 * ContentProviderRecord object containing the data about it.
584 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700585 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
586 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587
588 /**
589 * List of content providers who have clients waiting for them. The
590 * application is currently being launched and the provider will be
591 * removed from this list once it is published.
592 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700593 final ArrayList<ContentProviderRecord> mLaunchingProviders
594 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595
596 /**
597 * Global set of specific Uri permissions that have been granted.
598 */
599 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
600 = new SparseArray<HashMap<Uri, UriPermission>>();
601
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800602 CoreSettingsObserver mCoreSettingsObserver;
603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 /**
605 * Thread-local storage used to carry caller permissions over through
606 * indirect content-provider access.
607 * @see #ActivityManagerService.openContentUri()
608 */
609 private class Identity {
610 public int pid;
611 public int uid;
612
613 Identity(int _pid, int _uid) {
614 pid = _pid;
615 uid = _uid;
616 }
617 }
618 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
619
620 /**
621 * All information we have collected about the runtime performance of
622 * any user id that can impact battery performance.
623 */
624 final BatteryStatsService mBatteryStatsService;
625
626 /**
627 * information about component usage
628 */
629 final UsageStatsService mUsageStatsService;
630
631 /**
632 * Current configuration information. HistoryRecord objects are given
633 * a reference to this object to indicate which configuration they are
634 * currently running in, so this object must be kept immutable.
635 */
636 Configuration mConfiguration = new Configuration();
637
638 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800639 * Current sequencing integer of the configuration, for skipping old
640 * configurations.
641 */
642 int mConfigurationSeq = 0;
643
644 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700645 * Hardware-reported OpenGLES version.
646 */
647 final int GL_ES_VERSION;
648
649 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 * List of initialization arguments to pass to all processes when binding applications to them.
651 * For example, references to the commonly used services.
652 */
653 HashMap<String, IBinder> mAppBindArgs;
654
655 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700656 * Temporary to avoid allocations. Protected by main lock.
657 */
658 final StringBuilder mStringBuilder = new StringBuilder(256);
659
660 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 * Used to control how we initialize the service.
662 */
663 boolean mStartRunning = false;
664 ComponentName mTopComponent;
665 String mTopAction;
666 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700667 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 boolean mSystemReady = false;
669 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700670 boolean mWaitingUpdate = false;
671 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700672 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700673 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674
675 Context mContext;
676
677 int mFactoryTest;
678
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700679 boolean mCheckedForSetup;
680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700682 * The time at which we will allow normal application switches again,
683 * after a call to {@link #stopAppSwitches()}.
684 */
685 long mAppSwitchesAllowedTime;
686
687 /**
688 * This is set to true after the first switch after mAppSwitchesAllowedTime
689 * is set; any switches after that will clear the time.
690 */
691 boolean mDidAppSwitch;
692
693 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700694 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700695 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700696 long mLastPowerCheckRealtime;
697
698 /**
699 * Last time (in uptime) at which we checked for power usage.
700 */
701 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700702
703 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 * Set while we are wanting to sleep, to prevent any
705 * activities from being started/resumed.
706 */
707 boolean mSleeping = false;
708
709 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700710 * Set if we are shutting down the system, similar to sleeping.
711 */
712 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713
714 /**
715 * Task identifier that activities are currently being started
716 * in. Incremented each time a new task is created.
717 * todo: Replace this with a TokenSpace class that generates non-repeating
718 * integers that won't wrap.
719 */
720 int mCurTask = 1;
721
722 /**
723 * Current sequence id for oom_adj computation traversal.
724 */
725 int mAdjSeq = 0;
726
727 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700728 * Current sequence id for process LRU updating.
729 */
730 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731
732 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700733 * Keep track of the number of service processes we last found, to
734 * determine on the next iteration which should be B services.
735 */
736 int mNumServiceProcs = 0;
737 int mNewNumServiceProcs = 0;
738
739 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 * System monitoring: number of processes that died since the last
741 * N procs were started.
742 */
743 int[] mProcDeaths = new int[20];
744
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700745 /**
746 * This is set if we had to do a delayed dexopt of an app before launching
747 * it, to increasing the ANR timeouts in that case.
748 */
749 boolean mDidDexOpt;
750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 String mDebugApp = null;
752 boolean mWaitForDebugger = false;
753 boolean mDebugTransient = false;
754 String mOrigDebugApp = null;
755 boolean mOrigWaitForDebugger = false;
756 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700757 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700758 String mProfileApp = null;
759 ProcessRecord mProfileProc = null;
760 String mProfileFile;
761 ParcelFileDescriptor mProfileFd;
762 int mProfileType = 0;
763 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700765 final RemoteCallbackList<IActivityWatcher> mWatchers
766 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700767
768 final RemoteCallbackList<IProcessObserver> mProcessObservers
769 = new RemoteCallbackList<IProcessObserver>();
770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 /**
772 * Callback of last caller to {@link #requestPss}.
773 */
774 Runnable mRequestPssCallback;
775
776 /**
777 * Remaining processes for which we are waiting results from the last
778 * call to {@link #requestPss}.
779 */
780 final ArrayList<ProcessRecord> mRequestPssList
781 = new ArrayList<ProcessRecord>();
782
783 /**
784 * Runtime statistics collection thread. This object's lock is used to
785 * protect all related state.
786 */
787 final Thread mProcessStatsThread;
788
789 /**
790 * Used to collect process stats when showing not responding dialog.
791 * Protected by mProcessStatsThread.
792 */
793 final ProcessStats mProcessStats = new ProcessStats(
794 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700795 final AtomicLong mLastCpuTime = new AtomicLong(0);
796 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 long mLastWriteTime = 0;
799
800 /**
801 * Set to true after the system has finished booting.
802 */
803 boolean mBooted = false;
804
Dianne Hackborn7d608422011-08-07 16:24:18 -0700805 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700806 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807
808 WindowManagerService mWindowManager;
809
810 static ActivityManagerService mSelf;
811 static ActivityThread mSystemThread;
812
813 private final class AppDeathRecipient implements IBinder.DeathRecipient {
814 final ProcessRecord mApp;
815 final int mPid;
816 final IApplicationThread mAppThread;
817
818 AppDeathRecipient(ProcessRecord app, int pid,
819 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 TAG, "New death recipient " + this
822 + " for thread " + thread.asBinder());
823 mApp = app;
824 mPid = pid;
825 mAppThread = thread;
826 }
827
828 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800829 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 TAG, "Death received in " + this
831 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 synchronized(ActivityManagerService.this) {
833 appDiedLocked(mApp, mPid, mAppThread);
834 }
835 }
836 }
837
838 static final int SHOW_ERROR_MSG = 1;
839 static final int SHOW_NOT_RESPONDING_MSG = 2;
840 static final int SHOW_FACTORY_ERROR_MSG = 3;
841 static final int UPDATE_CONFIGURATION_MSG = 4;
842 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
843 static final int WAIT_FOR_DEBUGGER_MSG = 6;
844 static final int BROADCAST_INTENT_MSG = 7;
845 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 static final int SERVICE_TIMEOUT_MSG = 12;
847 static final int UPDATE_TIME_ZONE = 13;
848 static final int SHOW_UID_ERROR_MSG = 14;
849 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700851 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700852 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800853 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700854 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
855 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700856 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700857 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700858 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700859 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700860 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700861 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
862 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700863 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864
865 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700866 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700867 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868
869 final Handler mHandler = new Handler() {
870 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800871 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 //}
873
874 public void handleMessage(Message msg) {
875 switch (msg.what) {
876 case SHOW_ERROR_MSG: {
877 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 synchronized (ActivityManagerService.this) {
879 ProcessRecord proc = (ProcessRecord)data.get("app");
880 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800881 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 return;
883 }
884 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700885 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800886 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 d.show();
888 proc.crashDialog = d;
889 } else {
890 // The device is asleep, so just pretend that the user
891 // saw a crash dialog and hit "force quit".
892 res.set(0);
893 }
894 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700895
896 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 } break;
898 case SHOW_NOT_RESPONDING_MSG: {
899 synchronized (ActivityManagerService.this) {
900 HashMap data = (HashMap) msg.obj;
901 ProcessRecord proc = (ProcessRecord)data.get("app");
902 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800903 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 return;
905 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800906
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700907 Intent intent = new Intent("android.intent.action.ANR");
908 if (!mProcessesReady) {
909 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
910 }
911 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800912 null, null, 0, null, null, null,
913 false, false, MY_PID, Process.SYSTEM_UID);
914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700916 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 d.show();
918 proc.anrDialog = d;
919 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700920
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700921 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700923 case SHOW_STRICT_MODE_VIOLATION_MSG: {
924 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
925 synchronized (ActivityManagerService.this) {
926 ProcessRecord proc = (ProcessRecord) data.get("app");
927 if (proc == null) {
928 Slog.e(TAG, "App not found when showing strict mode dialog.");
929 break;
930 }
931 if (proc.crashDialog != null) {
932 Slog.e(TAG, "App already has strict mode dialog: " + proc);
933 return;
934 }
935 AppErrorResult res = (AppErrorResult) data.get("result");
936 if (!mSleeping && !mShuttingDown) {
937 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
938 d.show();
939 proc.crashDialog = d;
940 } else {
941 // The device is asleep, so just pretend that the user
942 // saw a crash dialog and hit "force quit".
943 res.set(0);
944 }
945 }
946 ensureBootCompleted();
947 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 case SHOW_FACTORY_ERROR_MSG: {
949 Dialog d = new FactoryErrorDialog(
950 mContext, msg.getData().getCharSequence("msg"));
951 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700952 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 } break;
954 case UPDATE_CONFIGURATION_MSG: {
955 final ContentResolver resolver = mContext.getContentResolver();
956 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
957 } break;
958 case GC_BACKGROUND_PROCESSES_MSG: {
959 synchronized (ActivityManagerService.this) {
960 performAppGcsIfAppropriateLocked();
961 }
962 } break;
963 case WAIT_FOR_DEBUGGER_MSG: {
964 synchronized (ActivityManagerService.this) {
965 ProcessRecord app = (ProcessRecord)msg.obj;
966 if (msg.arg1 != 0) {
967 if (!app.waitedForDebugger) {
968 Dialog d = new AppWaitingForDebuggerDialog(
969 ActivityManagerService.this,
970 mContext, app);
971 app.waitDialog = d;
972 app.waitedForDebugger = true;
973 d.show();
974 }
975 } else {
976 if (app.waitDialog != null) {
977 app.waitDialog.dismiss();
978 app.waitDialog = null;
979 }
980 }
981 }
982 } break;
983 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800984 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 TAG, "Received BROADCAST_INTENT_MSG");
986 processNextBroadcast(true);
987 } break;
988 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700989 synchronized (ActivityManagerService.this) {
990 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700994 if (mDidDexOpt) {
995 mDidDexOpt = false;
996 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
997 nmsg.obj = msg.obj;
998 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
999 return;
1000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 serviceTimeout((ProcessRecord)msg.obj);
1002 } break;
1003 case UPDATE_TIME_ZONE: {
1004 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001005 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1006 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 if (r.thread != null) {
1008 try {
1009 r.thread.updateTimeZone();
1010 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001011 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 }
1013 }
1014 }
1015 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001016 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001017 case CLEAR_DNS_CACHE: {
1018 synchronized (ActivityManagerService.this) {
1019 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1020 ProcessRecord r = mLruProcesses.get(i);
1021 if (r.thread != null) {
1022 try {
1023 r.thread.clearDnsCache();
1024 } catch (RemoteException ex) {
1025 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1026 }
1027 }
1028 }
1029 }
1030 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001031 case UPDATE_HTTP_PROXY: {
1032 ProxyProperties proxy = (ProxyProperties)msg.obj;
1033 String host = "";
1034 String port = "";
1035 String exclList = "";
1036 if (proxy != null) {
1037 host = proxy.getHost();
1038 port = Integer.toString(proxy.getPort());
1039 exclList = proxy.getExclusionList();
1040 }
1041 synchronized (ActivityManagerService.this) {
1042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1043 ProcessRecord r = mLruProcesses.get(i);
1044 if (r.thread != null) {
1045 try {
1046 r.thread.setHttpProxy(host, port, exclList);
1047 } catch (RemoteException ex) {
1048 Slog.w(TAG, "Failed to update http proxy for: " +
1049 r.info.processName);
1050 }
1051 }
1052 }
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case SHOW_UID_ERROR_MSG: {
1056 // XXX This is a temporary dialog, no need to localize.
1057 AlertDialog d = new BaseErrorDialog(mContext);
1058 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1059 d.setCancelable(false);
1060 d.setTitle("System UIDs Inconsistent");
1061 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 +02001062 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1064 mUidAlert = d;
1065 d.show();
1066 } break;
1067 case IM_FEELING_LUCKY_MSG: {
1068 if (mUidAlert != null) {
1069 mUidAlert.dismiss();
1070 mUidAlert = null;
1071 }
1072 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001074 if (mDidDexOpt) {
1075 mDidDexOpt = false;
1076 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1077 nmsg.obj = msg.obj;
1078 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1079 return;
1080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 ProcessRecord app = (ProcessRecord)msg.obj;
1082 synchronized (ActivityManagerService.this) {
1083 processStartTimedOutLocked(app);
1084 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001085 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001086 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1087 synchronized (ActivityManagerService.this) {
1088 doPendingActivityLaunchesLocked(true);
1089 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001090 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001091 case KILL_APPLICATION_MSG: {
1092 synchronized (ActivityManagerService.this) {
1093 int uid = msg.arg1;
1094 boolean restart = (msg.arg2 == 1);
1095 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001096 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001097 }
1098 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001099 case FINALIZE_PENDING_INTENT_MSG: {
1100 ((PendingIntentRecord)msg.obj).completeFinalize();
1101 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001102 case POST_HEAVY_NOTIFICATION_MSG: {
1103 INotificationManager inm = NotificationManager.getService();
1104 if (inm == null) {
1105 return;
1106 }
1107
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001108 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001109 ProcessRecord process = root.app;
1110 if (process == null) {
1111 return;
1112 }
1113
1114 try {
1115 Context context = mContext.createPackageContext(process.info.packageName, 0);
1116 String text = mContext.getString(R.string.heavy_weight_notification,
1117 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1118 Notification notification = new Notification();
1119 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1120 notification.when = 0;
1121 notification.flags = Notification.FLAG_ONGOING_EVENT;
1122 notification.tickerText = text;
1123 notification.defaults = 0; // please be quiet
1124 notification.sound = null;
1125 notification.vibrate = null;
1126 notification.setLatestEventInfo(context, text,
1127 mContext.getText(R.string.heavy_weight_notification_detail),
1128 PendingIntent.getActivity(mContext, 0, root.intent,
1129 PendingIntent.FLAG_CANCEL_CURRENT));
1130
1131 try {
1132 int[] outId = new int[1];
1133 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1134 notification, outId);
1135 } catch (RuntimeException e) {
1136 Slog.w(ActivityManagerService.TAG,
1137 "Error showing notification for heavy-weight app", e);
1138 } catch (RemoteException e) {
1139 }
1140 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001141 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001142 }
1143 } break;
1144 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1145 INotificationManager inm = NotificationManager.getService();
1146 if (inm == null) {
1147 return;
1148 }
1149 try {
1150 inm.cancelNotification("android",
1151 R.string.heavy_weight_notification);
1152 } catch (RuntimeException e) {
1153 Slog.w(ActivityManagerService.TAG,
1154 "Error canceling notification for service", e);
1155 } catch (RemoteException e) {
1156 }
1157 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001158 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1159 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001160 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001161 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001162 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1163 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001164 }
1165 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001166 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1167 synchronized (ActivityManagerService.this) {
1168 ActivityRecord ar = (ActivityRecord)msg.obj;
1169 if (mCompatModeDialog != null) {
1170 if (mCompatModeDialog.mAppInfo.packageName.equals(
1171 ar.info.applicationInfo.packageName)) {
1172 return;
1173 }
1174 mCompatModeDialog.dismiss();
1175 mCompatModeDialog = null;
1176 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001177 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001178 if (mCompatModePackages.getPackageAskCompatModeLocked(
1179 ar.packageName)) {
1180 int mode = mCompatModePackages.computeCompatModeLocked(
1181 ar.info.applicationInfo);
1182 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1183 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1184 mCompatModeDialog = new CompatModeDialog(
1185 ActivityManagerService.this, mContext,
1186 ar.info.applicationInfo);
1187 mCompatModeDialog.show();
1188 }
1189 }
1190 }
1191 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001192 break;
1193 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001194 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001195 final int pid = msg.arg1;
1196 final int uid = msg.arg2;
1197 final boolean foregroundActivities = (Boolean) msg.obj;
1198 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001199 break;
1200 }
1201 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001202 final int pid = msg.arg1;
1203 final int uid = msg.arg2;
1204 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001205 break;
1206 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001207 case REPORT_MEM_USAGE: {
1208 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1209 if (!isDebuggable) {
1210 return;
1211 }
1212 synchronized (ActivityManagerService.this) {
1213 long now = SystemClock.uptimeMillis();
1214 if (now < (mLastMemUsageReportTime+10000)) {
1215 // Don't report more than every 10 seconds to somewhat
1216 // avoid spamming.
1217 return;
1218 }
1219 mLastMemUsageReportTime = now;
1220 }
1221 Thread thread = new Thread() {
1222 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001223 StringBuilder dropBuilder = new StringBuilder(1024);
1224 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001225 try {
1226 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1227 "procrank", });
1228 final InputStreamReader converter = new InputStreamReader(
1229 proc.getInputStream());
1230 BufferedReader in = new BufferedReader(converter);
1231 String line;
1232 while (true) {
1233 line = in.readLine();
1234 if (line == null) {
1235 break;
1236 }
1237 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001238 logBuilder.append(line);
1239 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001240 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001241 dropBuilder.append(line);
1242 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001243 }
1244 converter.close();
1245 } catch (IOException e) {
1246 }
1247 StringWriter sw = new StringWriter();
1248 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001249 StringWriter catSw = new StringWriter();
1250 PrintWriter catPw = new PrintWriter(catSw);
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08001251 String[] emptyArgs = new String[] { };
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001252 StringBuilder tag = new StringBuilder(128);
1253 dumpProcessesLocked(null, catPw, emptyArgs, 0, false);
1254 catPw.println();
1255 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false);
1256 catPw.println();
1257 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false);
1258 catPw.println();
1259 tag.append("Low on memory -- ");
1260 dumpApplicationMemoryUsage(null, pw, " ", emptyArgs, true, catPw, tag);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001261 String memUsage = sw.toString();
1262 dropBuilder.append('\n');
1263 dropBuilder.append(memUsage);
1264 dropBuilder.append(catSw.toString());
1265 logBuilder.append(memUsage);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001266 addErrorToDropBox("lowmem", null, "system_server", null,
1267 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001268 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001269 synchronized (ActivityManagerService.this) {
1270 long now = SystemClock.uptimeMillis();
1271 if (mLastMemUsageReportTime < now) {
1272 mLastMemUsageReportTime = now;
1273 }
1274 }
1275 }
1276 };
1277 thread.start();
1278 break;
1279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 }
1281 }
1282 };
1283
1284 public static void setSystemProcess() {
1285 try {
1286 ActivityManagerService m = mSelf;
1287
1288 ServiceManager.addService("activity", m);
1289 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001290 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 if (MONITOR_CPU_USAGE) {
1292 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 ServiceManager.addService("permission", new PermissionController(m));
1295
1296 ApplicationInfo info =
1297 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001298 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001299 mSystemThread.installSystemApplicationInfo(info);
1300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 synchronized (mSelf) {
1302 ProcessRecord app = mSelf.newProcessRecordLocked(
1303 mSystemThread.getApplicationThread(), info,
1304 info.processName);
1305 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001306 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001307 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1309 synchronized (mSelf.mPidsSelfLocked) {
1310 mSelf.mPidsSelfLocked.put(app.pid, app);
1311 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001312 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 }
1314 } catch (PackageManager.NameNotFoundException e) {
1315 throw new RuntimeException(
1316 "Unable to find android system package", e);
1317 }
1318 }
1319
1320 public void setWindowManager(WindowManagerService wm) {
1321 mWindowManager = wm;
1322 }
1323
1324 public static final Context main(int factoryTest) {
1325 AThread thr = new AThread();
1326 thr.start();
1327
1328 synchronized (thr) {
1329 while (thr.mService == null) {
1330 try {
1331 thr.wait();
1332 } catch (InterruptedException e) {
1333 }
1334 }
1335 }
1336
1337 ActivityManagerService m = thr.mService;
1338 mSelf = m;
1339 ActivityThread at = ActivityThread.systemMain();
1340 mSystemThread = at;
1341 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001342 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 m.mContext = context;
1344 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001345 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346
1347 m.mBatteryStatsService.publish(context);
1348 m.mUsageStatsService.publish(context);
1349
1350 synchronized (thr) {
1351 thr.mReady = true;
1352 thr.notifyAll();
1353 }
1354
1355 m.startRunning(null, null, null, null);
1356
1357 return context;
1358 }
1359
1360 public static ActivityManagerService self() {
1361 return mSelf;
1362 }
1363
1364 static class AThread extends Thread {
1365 ActivityManagerService mService;
1366 boolean mReady = false;
1367
1368 public AThread() {
1369 super("ActivityManager");
1370 }
1371
1372 public void run() {
1373 Looper.prepare();
1374
1375 android.os.Process.setThreadPriority(
1376 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001377 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378
1379 ActivityManagerService m = new ActivityManagerService();
1380
1381 synchronized (this) {
1382 mService = m;
1383 notifyAll();
1384 }
1385
1386 synchronized (this) {
1387 while (!mReady) {
1388 try {
1389 wait();
1390 } catch (InterruptedException e) {
1391 }
1392 }
1393 }
1394
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001395 // For debug builds, log event loop stalls to dropbox for analysis.
1396 if (StrictMode.conditionallyEnableDebugLogging()) {
1397 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1398 }
1399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 Looper.loop();
1401 }
1402 }
1403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 static class MemBinder extends Binder {
1405 ActivityManagerService mActivityManagerService;
1406 MemBinder(ActivityManagerService activityManagerService) {
1407 mActivityManagerService = activityManagerService;
1408 }
1409
1410 @Override
1411 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001412 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1413 != PackageManager.PERMISSION_GRANTED) {
1414 pw.println("Permission Denial: can't dump meminfo from from pid="
1415 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1416 + " without permission " + android.Manifest.permission.DUMP);
1417 return;
1418 }
1419
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001420 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
1421 false, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 }
1423 }
1424
Chet Haase9c1e23b2011-03-24 10:51:31 -07001425 static class GraphicsBinder extends Binder {
1426 ActivityManagerService mActivityManagerService;
1427 GraphicsBinder(ActivityManagerService activityManagerService) {
1428 mActivityManagerService = activityManagerService;
1429 }
1430
1431 @Override
1432 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001433 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1434 != PackageManager.PERMISSION_GRANTED) {
1435 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1436 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1437 + " without permission " + android.Manifest.permission.DUMP);
1438 return;
1439 }
1440
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001441 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001442 }
1443 }
1444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 static class CpuBinder extends Binder {
1446 ActivityManagerService mActivityManagerService;
1447 CpuBinder(ActivityManagerService activityManagerService) {
1448 mActivityManagerService = activityManagerService;
1449 }
1450
1451 @Override
1452 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001453 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1454 != PackageManager.PERMISSION_GRANTED) {
1455 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1456 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1457 + " without permission " + android.Manifest.permission.DUMP);
1458 return;
1459 }
1460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001462 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1463 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1464 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 }
1466 }
1467 }
1468
1469 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001470 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 File dataDir = Environment.getDataDirectory();
1473 File systemDir = new File(dataDir, "system");
1474 systemDir.mkdirs();
1475 mBatteryStatsService = new BatteryStatsService(new File(
1476 systemDir, "batterystats.bin").toString());
1477 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001478 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001479 mOnBattery = DEBUG_POWER ? true
1480 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001481 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001483 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001484 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485
Jack Palevichb90d28c2009-07-22 15:35:24 -07001486 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1487 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1488
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001489 mConfiguration.setToDefaults();
1490 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001491 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 mProcessStats.init();
1493
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001494 mCompatModePackages = new CompatModePackages(this, systemDir);
1495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 // Add ourself to the Watchdog monitors.
1497 Watchdog.getInstance().addMonitor(this);
1498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 mProcessStatsThread = new Thread("ProcessStats") {
1500 public void run() {
1501 while (true) {
1502 try {
1503 try {
1504 synchronized(this) {
1505 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001506 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001508 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 // + ", write delay=" + nextWriteDelay);
1510 if (nextWriteDelay < nextCpuDelay) {
1511 nextCpuDelay = nextWriteDelay;
1512 }
1513 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001514 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 this.wait(nextCpuDelay);
1516 }
1517 }
1518 } catch (InterruptedException e) {
1519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 updateCpuStatsNow();
1521 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001522 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 }
1524 }
1525 }
1526 };
1527 mProcessStatsThread.start();
1528 }
1529
1530 @Override
1531 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1532 throws RemoteException {
1533 try {
1534 return super.onTransact(code, data, reply, flags);
1535 } catch (RuntimeException e) {
1536 // The activity manager only throws security exceptions, so let's
1537 // log all others.
1538 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001539 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 }
1541 throw e;
1542 }
1543 }
1544
1545 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001546 final long now = SystemClock.uptimeMillis();
1547 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1548 return;
1549 }
1550 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1551 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 mProcessStatsThread.notify();
1553 }
1554 }
1555 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 void updateCpuStatsNow() {
1558 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001559 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 final long now = SystemClock.uptimeMillis();
1561 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001564 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1565 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 haveNewCpuStats = true;
1567 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001568 //Slog.i(TAG, mProcessStats.printCurrentState());
1569 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 // + mProcessStats.getTotalCpuPercent() + "%");
1571
Joe Onorato8a9b2202010-02-26 18:56:32 -08001572 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 if ("true".equals(SystemProperties.get("events.cpu"))) {
1574 int user = mProcessStats.getLastUserTime();
1575 int system = mProcessStats.getLastSystemTime();
1576 int iowait = mProcessStats.getLastIoWaitTime();
1577 int irq = mProcessStats.getLastIrqTime();
1578 int softIrq = mProcessStats.getLastSoftIrqTime();
1579 int idle = mProcessStats.getLastIdleTime();
1580
1581 int total = user + system + iowait + irq + softIrq + idle;
1582 if (total == 0) total = 1;
1583
Doug Zongker2bec3d42009-12-04 12:52:44 -08001584 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 ((user+system+iowait+irq+softIrq) * 100) / total,
1586 (user * 100) / total,
1587 (system * 100) / total,
1588 (iowait * 100) / total,
1589 (irq * 100) / total,
1590 (softIrq * 100) / total);
1591 }
1592 }
1593
Amith Yamasanie43530a2009-08-21 13:11:37 -07001594 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001595 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001596 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 synchronized(mPidsSelfLocked) {
1598 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001599 if (mOnBattery) {
1600 int perc = bstats.startAddingCpuLocked();
1601 int totalUTime = 0;
1602 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001603 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001605 ProcessStats.Stats st = mProcessStats.getStats(i);
1606 if (!st.working) {
1607 continue;
1608 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001610 int otherUTime = (st.rel_utime*perc)/100;
1611 int otherSTime = (st.rel_stime*perc)/100;
1612 totalUTime += otherUTime;
1613 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 if (pr != null) {
1615 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001616 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1617 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001618 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001619 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001620 } else {
1621 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001622 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001623 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001624 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1625 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001626 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 }
1629 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001630 bstats.finishAddingCpuLocked(perc, totalUTime,
1631 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 }
1633 }
1634 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1637 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001638 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 }
1640 }
1641 }
1642 }
1643
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001644 @Override
1645 public void batteryNeedsCpuUpdate() {
1646 updateCpuStatsNow();
1647 }
1648
1649 @Override
1650 public void batteryPowerChanged(boolean onBattery) {
1651 // When plugging in, update the CPU stats first before changing
1652 // the plug state.
1653 updateCpuStatsNow();
1654 synchronized (this) {
1655 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001656 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001657 }
1658 }
1659 }
1660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 /**
1662 * Initialize the application bind args. These are passed to each
1663 * process when the bindApplication() IPC is sent to the process. They're
1664 * lazily setup to make sure the services are running when they're asked for.
1665 */
1666 private HashMap<String, IBinder> getCommonServicesLocked() {
1667 if (mAppBindArgs == null) {
1668 mAppBindArgs = new HashMap<String, IBinder>();
1669
1670 // Setup the application init args
1671 mAppBindArgs.put("package", ServiceManager.getService("package"));
1672 mAppBindArgs.put("window", ServiceManager.getService("window"));
1673 mAppBindArgs.put(Context.ALARM_SERVICE,
1674 ServiceManager.getService(Context.ALARM_SERVICE));
1675 }
1676 return mAppBindArgs;
1677 }
1678
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001679 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 if (mFocusedActivity != r) {
1681 mFocusedActivity = r;
Dianne Hackbornbe707852011-11-11 14:32:10 -08001682 mWindowManager.setFocusedApp(r.appToken, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 }
1684 }
1685
Dianne Hackborn906497c2010-05-10 15:57:38 -07001686 private final void updateLruProcessInternalLocked(ProcessRecord app,
1687 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001688 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001689 int lrui = mLruProcesses.indexOf(app);
1690 if (lrui >= 0) mLruProcesses.remove(lrui);
1691
1692 int i = mLruProcesses.size()-1;
1693 int skipTop = 0;
1694
Dianne Hackborn906497c2010-05-10 15:57:38 -07001695 app.lruSeq = mLruSeq;
1696
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001697 // compute the new weight for this process.
1698 if (updateActivityTime) {
1699 app.lastActivityTime = SystemClock.uptimeMillis();
1700 }
1701 if (app.activities.size() > 0) {
1702 // If this process has activities, we more strongly want to keep
1703 // it around.
1704 app.lruWeight = app.lastActivityTime;
1705 } else if (app.pubProviders.size() > 0) {
1706 // If this process contains content providers, we want to keep
1707 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001708 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001709 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001710 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001711 } else {
1712 // If this process doesn't have activities, we less strongly
1713 // want to keep it around, and generally want to avoid getting
1714 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001715 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001716 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001717 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001718 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001719
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001720 while (i >= 0) {
1721 ProcessRecord p = mLruProcesses.get(i);
1722 // If this app shouldn't be in front of the first N background
1723 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001724 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001725 skipTop--;
1726 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001727 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001728 mLruProcesses.add(i+1, app);
1729 break;
1730 }
1731 i--;
1732 }
1733 if (i < 0) {
1734 mLruProcesses.add(0, app);
1735 }
1736
Dianne Hackborn906497c2010-05-10 15:57:38 -07001737 // If the app is currently using a content provider or service,
1738 // bump those processes as well.
1739 if (app.connections.size() > 0) {
1740 for (ConnectionRecord cr : app.connections) {
1741 if (cr.binding != null && cr.binding.service != null
1742 && cr.binding.service.app != null
1743 && cr.binding.service.app.lruSeq != mLruSeq) {
1744 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1745 updateActivityTime, i+1);
1746 }
1747 }
1748 }
1749 if (app.conProviders.size() > 0) {
1750 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001751 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1752 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001753 updateActivityTime, i+1);
1754 }
1755 }
1756 }
1757
Joe Onorato8a9b2202010-02-26 18:56:32 -08001758 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 if (oomAdj) {
1760 updateOomAdjLocked();
1761 }
1762 }
1763
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001764 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001765 boolean oomAdj, boolean updateActivityTime) {
1766 mLruSeq++;
1767 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1768 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001769
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001770 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 String processName, int uid) {
1772 if (uid == Process.SYSTEM_UID) {
1773 // The system gets to run in any process. If there are multiple
1774 // processes with the same uid, just pick the first (this
1775 // should never happen).
1776 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1777 processName);
1778 return procs != null ? procs.valueAt(0) : null;
1779 }
1780 ProcessRecord proc = mProcessNames.get(processName, uid);
1781 return proc;
1782 }
1783
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001784 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001785 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001786 try {
1787 if (pm.performDexOpt(packageName)) {
1788 mDidDexOpt = true;
1789 }
1790 } catch (RemoteException e) {
1791 }
1792 }
1793
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001794 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 int transit = mWindowManager.getPendingAppTransition();
1796 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1797 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1798 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1799 }
1800
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001801 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001803 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1805 // We don't have to do anything more if:
1806 // (1) There is an existing application record; and
1807 // (2) The caller doesn't think it is dead, OR there is no thread
1808 // object attached to it so we know it couldn't have crashed; and
1809 // (3) There is a pid assigned to it, so it is either starting or
1810 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001811 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 + " app=" + app + " knownToBeDead=" + knownToBeDead
1813 + " thread=" + (app != null ? app.thread : null)
1814 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001815 if (app != null && app.pid > 0) {
1816 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001817 // We already have the app running, or are waiting for it to
1818 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001819 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001820 // If this is a new package in the process, add the package to the list
1821 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001822 return app;
1823 } else {
1824 // An application record is attached to a previous process,
1825 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001826 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001827 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 String hostingNameStr = hostingName != null
1832 ? hostingName.flattenToShortString() : null;
1833
1834 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1835 // If we are in the background, then check to see if this process
1836 // is bad. If so, we will just silently fail.
1837 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001838 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1839 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 return null;
1841 }
1842 } else {
1843 // When the user is explicitly starting a process, then clear its
1844 // crash count so that we won't make it bad until they see at
1845 // least one crash dialog again, and make the process good again
1846 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001847 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1848 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 mProcessCrashTimes.remove(info.processName, info.uid);
1850 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001851 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 info.processName);
1853 mBadProcesses.remove(info.processName, info.uid);
1854 if (app != null) {
1855 app.bad = false;
1856 }
1857 }
1858 }
1859
1860 if (app == null) {
1861 app = newProcessRecordLocked(null, info, processName);
1862 mProcessNames.put(processName, info.uid, app);
1863 } else {
1864 // If this is a new package in the process, add the package to the list
1865 app.addPackage(info.packageName);
1866 }
1867
1868 // If the system is not ready yet, then hold off on starting this
1869 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001870 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001871 && !isAllowedWhileBooting(info)
1872 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 if (!mProcessesOnHold.contains(app)) {
1874 mProcessesOnHold.add(app);
1875 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001876 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001877 return app;
1878 }
1879
1880 startProcessLocked(app, hostingType, hostingNameStr);
1881 return (app.pid != 0) ? app : null;
1882 }
1883
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001884 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1885 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1886 }
1887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001888 private final void startProcessLocked(ProcessRecord app,
1889 String hostingType, String hostingNameStr) {
1890 if (app.pid > 0 && app.pid != MY_PID) {
1891 synchronized (mPidsSelfLocked) {
1892 mPidsSelfLocked.remove(app.pid);
1893 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1894 }
1895 app.pid = 0;
1896 }
1897
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001898 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1899 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 mProcessesOnHold.remove(app);
1901
1902 updateCpuStats();
1903
1904 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1905 mProcDeaths[0] = 0;
1906
1907 try {
1908 int uid = app.info.uid;
1909 int[] gids = null;
1910 try {
1911 gids = mContext.getPackageManager().getPackageGids(
1912 app.info.packageName);
1913 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001914 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 }
1916 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1917 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1918 && mTopComponent != null
1919 && app.processName.equals(mTopComponent.getPackageName())) {
1920 uid = 0;
1921 }
1922 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1923 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1924 uid = 0;
1925 }
1926 }
1927 int debugFlags = 0;
1928 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1929 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001930 // Also turn on CheckJNI for debuggable apps. It's quite
1931 // awkward to turn on otherwise.
1932 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001933 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001934 // Run the app in safe mode if its manifest requests so or the
1935 // system is booted in safe mode.
1936 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1937 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001938 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1941 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1942 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001943 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1944 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1945 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 if ("1".equals(SystemProperties.get("debug.assert"))) {
1947 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1948 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001949
1950 // Start the process. It will either succeed and return a result containing
1951 // the PID of the new process, or else throw a RuntimeException.
1952 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001953 app.processName, uid, uid, gids, debugFlags,
1954 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1957 synchronized (bs) {
1958 if (bs.isOnBattery()) {
1959 app.batteryStats.incStartsLocked();
1960 }
1961 }
1962
Jeff Brown3f9dd282011-07-08 20:02:19 -07001963 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 app.processName, hostingType,
1965 hostingNameStr != null ? hostingNameStr : "");
1966
1967 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001968 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 }
1970
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001971 StringBuilder buf = mStringBuilder;
1972 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001973 buf.append("Start proc ");
1974 buf.append(app.processName);
1975 buf.append(" for ");
1976 buf.append(hostingType);
1977 if (hostingNameStr != null) {
1978 buf.append(" ");
1979 buf.append(hostingNameStr);
1980 }
1981 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001982 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 buf.append(" uid=");
1984 buf.append(uid);
1985 buf.append(" gids={");
1986 if (gids != null) {
1987 for (int gi=0; gi<gids.length; gi++) {
1988 if (gi != 0) buf.append(", ");
1989 buf.append(gids[gi]);
1990
1991 }
1992 }
1993 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001994 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001995 app.pid = startResult.pid;
1996 app.usingWrapper = startResult.usingWrapper;
1997 app.removed = false;
1998 synchronized (mPidsSelfLocked) {
1999 this.mPidsSelfLocked.put(startResult.pid, app);
2000 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2001 msg.obj = app;
2002 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2003 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 }
2005 } catch (RuntimeException e) {
2006 // XXX do better error recovery.
2007 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002008 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002009 }
2010 }
2011
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002012 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 if (resumed) {
2014 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2015 } else {
2016 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2017 }
2018 }
2019
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002020 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002021 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2022 && mTopAction == null) {
2023 // We are running in factory test mode, but unable to find
2024 // the factory test app, so just sit around displaying the
2025 // error message and don't try to start anything.
2026 return false;
2027 }
2028 Intent intent = new Intent(
2029 mTopAction,
2030 mTopData != null ? Uri.parse(mTopData) : null);
2031 intent.setComponent(mTopComponent);
2032 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2033 intent.addCategory(Intent.CATEGORY_HOME);
2034 }
2035 ActivityInfo aInfo =
2036 intent.resolveActivityInfo(mContext.getPackageManager(),
2037 STOCK_PM_FLAGS);
2038 if (aInfo != null) {
2039 intent.setComponent(new ComponentName(
2040 aInfo.applicationInfo.packageName, aInfo.name));
2041 // Don't do this if the home app is currently being
2042 // instrumented.
2043 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2044 aInfo.applicationInfo.uid);
2045 if (app == null || app.instrumentationClass == null) {
2046 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002047 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002048 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002049 }
2050 }
2051
2052
2053 return true;
2054 }
2055
2056 /**
2057 * Starts the "new version setup screen" if appropriate.
2058 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002059 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002060 // Only do this once per boot.
2061 if (mCheckedForSetup) {
2062 return;
2063 }
2064
2065 // We will show this screen if the current one is a different
2066 // version than the last one shown, and we are not running in
2067 // low-level factory test mode.
2068 final ContentResolver resolver = mContext.getContentResolver();
2069 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2070 Settings.Secure.getInt(resolver,
2071 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2072 mCheckedForSetup = true;
2073
2074 // See if we should be showing the platform update setup UI.
2075 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2076 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2077 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2078
2079 // We don't allow third party apps to replace this.
2080 ResolveInfo ri = null;
2081 for (int i=0; ris != null && i<ris.size(); i++) {
2082 if ((ris.get(i).activityInfo.applicationInfo.flags
2083 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2084 ri = ris.get(i);
2085 break;
2086 }
2087 }
2088
2089 if (ri != null) {
2090 String vers = ri.activityInfo.metaData != null
2091 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2092 : null;
2093 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2094 vers = ri.activityInfo.applicationInfo.metaData.getString(
2095 Intent.METADATA_SETUP_VERSION);
2096 }
2097 String lastVers = Settings.Secure.getString(
2098 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2099 if (vers != null && !vers.equals(lastVers)) {
2100 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2101 intent.setComponent(new ComponentName(
2102 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002103 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002104 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002105 }
2106 }
2107 }
2108 }
2109
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002110 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002111 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002112 }
2113
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002114 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002115 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002116 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2117 }
2118 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002119
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002120 public void setFrontActivityScreenCompatMode(int mode) {
2121 synchronized (this) {
2122 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2123 }
2124 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002125
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002126 public int getPackageScreenCompatMode(String packageName) {
2127 synchronized (this) {
2128 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2129 }
2130 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002131
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002132 public void setPackageScreenCompatMode(String packageName, int mode) {
2133 synchronized (this) {
2134 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002135 }
2136 }
2137
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002138 public boolean getPackageAskScreenCompat(String packageName) {
2139 synchronized (this) {
2140 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2141 }
2142 }
2143
2144 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2145 synchronized (this) {
2146 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2147 }
2148 }
2149
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002150 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002151 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002152
2153 final int identHash = System.identityHashCode(r);
2154 updateUsageStats(r, true);
2155
2156 int i = mWatchers.beginBroadcast();
2157 while (i > 0) {
2158 i--;
2159 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2160 if (w != null) {
2161 try {
2162 w.activityResuming(identHash);
2163 } catch (RemoteException e) {
2164 }
2165 }
2166 }
2167 mWatchers.finishBroadcast();
2168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169
Jeff Sharkeya4620792011-05-20 15:29:23 -07002170 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2171 int i = mProcessObservers.beginBroadcast();
2172 while (i > 0) {
2173 i--;
2174 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2175 if (observer != null) {
2176 try {
2177 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2178 } catch (RemoteException e) {
2179 }
2180 }
2181 }
2182 mProcessObservers.finishBroadcast();
2183 }
2184
2185 private void dispatchProcessDied(int pid, int uid) {
2186 int i = mProcessObservers.beginBroadcast();
2187 while (i > 0) {
2188 i--;
2189 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2190 if (observer != null) {
2191 try {
2192 observer.onProcessDied(pid, uid);
2193 } catch (RemoteException e) {
2194 }
2195 }
2196 }
2197 mProcessObservers.finishBroadcast();
2198 }
2199
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002200 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002201 final int N = mPendingActivityLaunches.size();
2202 if (N <= 0) {
2203 return;
2204 }
2205 for (int i=0; i<N; i++) {
2206 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002207 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002208 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2209 doResume && i == (N-1));
2210 }
2211 mPendingActivityLaunches.clear();
2212 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002213
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002214 public final int startActivity(IApplicationThread caller,
2215 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2216 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002217 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2218 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002219 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002220 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002221 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2222 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002223 }
2224
2225 public final WaitResult startActivityAndWait(IApplicationThread caller,
2226 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2227 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002228 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2229 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002230 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002231 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002232 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002233 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2234 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002235 return res;
2236 }
2237
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002238 public final int startActivityWithConfig(IApplicationThread caller,
2239 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2240 int grantedMode, IBinder resultTo,
2241 String resultWho, int requestCode, boolean onlyIfNeeded,
2242 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002243 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002244 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002245 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002246 }
2247
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002248 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002249 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002250 IBinder resultTo, String resultWho, int requestCode,
2251 int flagsMask, int flagsValues) {
2252 // Refuse possible leaked file descriptors
2253 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2254 throw new IllegalArgumentException("File descriptors passed in Intent");
2255 }
2256
2257 IIntentSender sender = intent.getTarget();
2258 if (!(sender instanceof PendingIntentRecord)) {
2259 throw new IllegalArgumentException("Bad PendingIntent object");
2260 }
2261
2262 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002263
2264 synchronized (this) {
2265 // If this is coming from the currently resumed activity, it is
2266 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002267 if (mMainStack.mResumedActivity != null
2268 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002269 Binder.getCallingUid()) {
2270 mAppSwitchesAllowedTime = 0;
2271 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002272 }
2273
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002274 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002275 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2276 }
2277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 public boolean startNextMatchingActivity(IBinder callingActivity,
2279 Intent intent) {
2280 // Refuse possible leaked file descriptors
2281 if (intent != null && intent.hasFileDescriptors() == true) {
2282 throw new IllegalArgumentException("File descriptors passed in Intent");
2283 }
2284
2285 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002286 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2287 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 return false;
2289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 if (r.app == null || r.app.thread == null) {
2291 // The caller is not running... d'oh!
2292 return false;
2293 }
2294 intent = new Intent(intent);
2295 // The caller is not allowed to change the data.
2296 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2297 // And we are resetting to find the next component...
2298 intent.setComponent(null);
2299
2300 ActivityInfo aInfo = null;
2301 try {
2302 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002303 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002305 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306
2307 // Look for the original activity in the list...
2308 final int N = resolves != null ? resolves.size() : 0;
2309 for (int i=0; i<N; i++) {
2310 ResolveInfo rInfo = resolves.get(i);
2311 if (rInfo.activityInfo.packageName.equals(r.packageName)
2312 && rInfo.activityInfo.name.equals(r.info.name)) {
2313 // We found the current one... the next matching is
2314 // after it.
2315 i++;
2316 if (i<N) {
2317 aInfo = resolves.get(i).activityInfo;
2318 }
2319 break;
2320 }
2321 }
2322 } catch (RemoteException e) {
2323 }
2324
2325 if (aInfo == null) {
2326 // Nobody who is next!
2327 return false;
2328 }
2329
2330 intent.setComponent(new ComponentName(
2331 aInfo.applicationInfo.packageName, aInfo.name));
2332 intent.setFlags(intent.getFlags()&~(
2333 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2334 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2335 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2336 Intent.FLAG_ACTIVITY_NEW_TASK));
2337
2338 // Okay now we need to start the new activity, replacing the
2339 // currently running activity. This is a little tricky because
2340 // we want to start the new one as if the current one is finished,
2341 // but not finish the current one first so that there is no flicker.
2342 // And thus...
2343 final boolean wasFinishing = r.finishing;
2344 r.finishing = true;
2345
2346 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002347 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 final String resultWho = r.resultWho;
2349 final int requestCode = r.requestCode;
2350 r.resultTo = null;
2351 if (resultTo != null) {
2352 resultTo.removeResultsLocked(r, resultWho, requestCode);
2353 }
2354
2355 final long origId = Binder.clearCallingIdentity();
2356 // XXX we are not dealing with propagating grantedUriPermissions...
2357 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002358 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002359 r.resolvedType, null, 0, aInfo,
2360 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002361 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002362 Binder.restoreCallingIdentity(origId);
2363
2364 r.finishing = wasFinishing;
2365 if (res != START_SUCCESS) {
2366 return false;
2367 }
2368 return true;
2369 }
2370 }
2371
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002372 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 Intent intent, String resolvedType, IBinder resultTo,
2374 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002375
2376 // This is so super not safe, that only the system (or okay root)
2377 // can do it.
2378 final int callingUid = Binder.getCallingUid();
2379 if (callingUid != 0 && callingUid != Process.myUid()) {
2380 throw new SecurityException(
2381 "startActivityInPackage only available to the system");
2382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002384 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002385 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2386 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002387 }
2388
2389 public final int startActivities(IApplicationThread caller,
2390 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2391 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2392 }
2393
2394 public final int startActivitiesInPackage(int uid,
2395 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2396
2397 // This is so super not safe, that only the system (or okay root)
2398 // can do it.
2399 final int callingUid = Binder.getCallingUid();
2400 if (callingUid != 0 && callingUid != Process.myUid()) {
2401 throw new SecurityException(
2402 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 }
2404
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002405 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 }
2407
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002408 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002410 // Quick case: check if the top-most recent task is the same.
2411 if (N > 0 && mRecentTasks.get(0) == task) {
2412 return;
2413 }
2414 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 for (int i=0; i<N; i++) {
2416 TaskRecord tr = mRecentTasks.get(i);
2417 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2418 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2419 mRecentTasks.remove(i);
2420 i--;
2421 N--;
2422 if (task.intent == null) {
2423 // If the new recent task we are adding is not fully
2424 // specified, then replace it with the existing recent task.
2425 task = tr;
2426 }
2427 }
2428 }
2429 if (N >= MAX_RECENT_TASKS) {
2430 mRecentTasks.remove(N-1);
2431 }
2432 mRecentTasks.add(0, task);
2433 }
2434
2435 public void setRequestedOrientation(IBinder token,
2436 int requestedOrientation) {
2437 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002438 ActivityRecord r = mMainStack.isInStackLocked(token);
2439 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 return;
2441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002443 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002445 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002446 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 if (config != null) {
2448 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002449 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002450 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 }
2452 }
2453 Binder.restoreCallingIdentity(origId);
2454 }
2455 }
2456
2457 public int getRequestedOrientation(IBinder token) {
2458 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002459 ActivityRecord r = mMainStack.isInStackLocked(token);
2460 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2462 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002463 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 }
2465 }
2466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002467 /**
2468 * This is the internal entry point for handling Activity.finish().
2469 *
2470 * @param token The Binder token referencing the Activity we want to finish.
2471 * @param resultCode Result code, if any, from this Activity.
2472 * @param resultData Result data (Intent), if any, from this Activity.
2473 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002474 * @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 -08002475 */
2476 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2477 // Refuse possible leaked file descriptors
2478 if (resultData != null && resultData.hasFileDescriptors() == true) {
2479 throw new IllegalArgumentException("File descriptors passed in Intent");
2480 }
2481
2482 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002483 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002485 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 if (next != null) {
2487 // ask watcher if this is allowed
2488 boolean resumeOK = true;
2489 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002490 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002492 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 }
2494
2495 if (!resumeOK) {
2496 return false;
2497 }
2498 }
2499 }
2500 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002501 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 resultData, "app-request");
2503 Binder.restoreCallingIdentity(origId);
2504 return res;
2505 }
2506 }
2507
Dianne Hackborn860755f2010-06-03 18:47:52 -07002508 public final void finishHeavyWeightApp() {
2509 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2510 != PackageManager.PERMISSION_GRANTED) {
2511 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2512 + Binder.getCallingPid()
2513 + ", uid=" + Binder.getCallingUid()
2514 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2515 Slog.w(TAG, msg);
2516 throw new SecurityException(msg);
2517 }
2518
2519 synchronized(this) {
2520 if (mHeavyWeightProcess == null) {
2521 return;
2522 }
2523
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002524 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002525 mHeavyWeightProcess.activities);
2526 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002527 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002528 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002529 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002530 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002531 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002532 null, "finish-heavy");
2533 }
2534 }
2535 }
2536
2537 mHeavyWeightProcess = null;
2538 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2539 }
2540 }
2541
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002542 public void crashApplication(int uid, int initialPid, String packageName,
2543 String message) {
2544 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2545 != PackageManager.PERMISSION_GRANTED) {
2546 String msg = "Permission Denial: crashApplication() from pid="
2547 + Binder.getCallingPid()
2548 + ", uid=" + Binder.getCallingUid()
2549 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2550 Slog.w(TAG, msg);
2551 throw new SecurityException(msg);
2552 }
2553
2554 synchronized(this) {
2555 ProcessRecord proc = null;
2556
2557 // Figure out which process to kill. We don't trust that initialPid
2558 // still has any relation to current pids, so must scan through the
2559 // list.
2560 synchronized (mPidsSelfLocked) {
2561 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2562 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2563 if (p.info.uid != uid) {
2564 continue;
2565 }
2566 if (p.pid == initialPid) {
2567 proc = p;
2568 break;
2569 }
2570 for (String str : p.pkgList) {
2571 if (str.equals(packageName)) {
2572 proc = p;
2573 }
2574 }
2575 }
2576 }
2577
2578 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002579 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002580 + " initialPid=" + initialPid
2581 + " packageName=" + packageName);
2582 return;
2583 }
2584
2585 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002586 if (proc.pid == Process.myPid()) {
2587 Log.w(TAG, "crashApplication: trying to crash self!");
2588 return;
2589 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002590 long ident = Binder.clearCallingIdentity();
2591 try {
2592 proc.thread.scheduleCrash(message);
2593 } catch (RemoteException e) {
2594 }
2595 Binder.restoreCallingIdentity(ident);
2596 }
2597 }
2598 }
2599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600 public final void finishSubActivity(IBinder token, String resultWho,
2601 int requestCode) {
2602 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002603 ActivityRecord self = mMainStack.isInStackLocked(token);
2604 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 return;
2606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607
2608 final long origId = Binder.clearCallingIdentity();
2609
2610 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002611 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2612 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 if (r.resultTo == self && r.requestCode == requestCode) {
2614 if ((r.resultWho == null && resultWho == null) ||
2615 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002616 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 Activity.RESULT_CANCELED, null, "request-sub");
2618 }
2619 }
2620 }
2621
2622 Binder.restoreCallingIdentity(origId);
2623 }
2624 }
2625
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002626 public boolean willActivityBeVisible(IBinder token) {
2627 synchronized(this) {
2628 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2630 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002631 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002632 return true;
2633 }
2634 if (r.fullscreen && !r.finishing) {
2635 return false;
2636 }
2637 }
2638 return true;
2639 }
2640 }
2641
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002642 public void overridePendingTransition(IBinder token, String packageName,
2643 int enterAnim, int exitAnim) {
2644 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002645 ActivityRecord self = mMainStack.isInStackLocked(token);
2646 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002647 return;
2648 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002649
2650 final long origId = Binder.clearCallingIdentity();
2651
2652 if (self.state == ActivityState.RESUMED
2653 || self.state == ActivityState.PAUSING) {
2654 mWindowManager.overridePendingAppTransition(packageName,
2655 enterAnim, exitAnim);
2656 }
2657
2658 Binder.restoreCallingIdentity(origId);
2659 }
2660 }
2661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 * Main function for removing an existing process from the activity manager
2664 * as a result of that process going away. Clears out all connections
2665 * to the process.
2666 */
2667 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002668 boolean restarting, boolean allowRestart) {
2669 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002671 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 }
2673
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002674 if (mProfileProc == app) {
2675 clearProfilerLocked();
2676 }
2677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002679 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2680 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2681 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002683 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2684 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 }
2686
2687 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002688 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689
2690 boolean atTop = true;
2691 boolean hasVisibleActivities = false;
2692
2693 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002694 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002695 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 TAG, "Removing app " + app + " from history with " + i + " entries");
2697 while (i > 0) {
2698 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002699 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002700 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2702 if (r.app == app) {
2703 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002704 if (ActivityStack.DEBUG_ADD_REMOVE) {
2705 RuntimeException here = new RuntimeException("here");
2706 here.fillInStackTrace();
2707 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2708 + ": haveState=" + r.haveState
2709 + " stateNotNeeded=" + r.stateNotNeeded
2710 + " finishing=" + r.finishing
2711 + " state=" + r.state, here);
2712 }
2713 if (!r.finishing) {
2714 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2715 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002716 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002717 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002718 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002719 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002721 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002723 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724
2725 } else {
2726 // We have the current state for this activity, so
2727 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 TAG, "Keeping entry, setting app to null");
2730 if (r.visible) {
2731 hasVisibleActivities = true;
2732 }
2733 r.app = null;
2734 r.nowVisible = false;
2735 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002736 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2737 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 r.icicle = null;
2739 }
2740 }
2741
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002742 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743 }
2744 atTop = false;
2745 }
2746
2747 app.activities.clear();
2748
2749 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002750 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 + " running instrumentation " + app.instrumentationClass);
2752 Bundle info = new Bundle();
2753 info.putString("shortMsg", "Process crashed.");
2754 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2755 }
2756
2757 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002758 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 // If there was nothing to resume, and we are not already
2760 // restarting this process, but there is a visible activity that
2761 // is hosted by the process... then make sure all visible
2762 // activities are running, taking care of restarting this
2763 // process.
2764 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002765 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002766 }
2767 }
2768 }
2769 }
2770
2771 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2772 IBinder threadBinder = thread.asBinder();
2773
2774 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002775 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2776 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2778 return i;
2779 }
2780 }
2781 return -1;
2782 }
2783
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002784 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 IApplicationThread thread) {
2786 if (thread == null) {
2787 return null;
2788 }
2789
2790 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002791 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 }
2793
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002794 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 IApplicationThread thread) {
2796
2797 mProcDeaths[0]++;
2798
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002799 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2800 synchronized (stats) {
2801 stats.noteProcessDiedLocked(app.info.uid, pid);
2802 }
2803
Magnus Edlund7bb25812010-02-24 15:45:06 +01002804 // Clean up already done if the process has been re-started.
2805 if (app.pid == pid && app.thread != null &&
2806 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002807 if (!app.killedBackground) {
2808 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2809 + ") has died.");
2810 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002811 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002812 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002813 TAG, "Dying app: " + app + ", pid: " + pid
2814 + ", thread: " + thread.asBinder());
2815 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002816 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817
2818 if (doLowMem) {
2819 // If there are no longer any background processes running,
2820 // and the app that died was not running instrumentation,
2821 // then tell everyone we are now low on memory.
2822 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002823 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2824 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002825 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 haveBg = true;
2827 break;
2828 }
2829 }
2830
2831 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002832 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002833 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002834 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2835 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002836 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002837 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2838 // The low memory report is overriding any current
2839 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002840 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002841 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002842 rec.lastRequestedGc = 0;
2843 } else {
2844 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002846 rec.reportLowMemory = true;
2847 rec.lastLowMemory = now;
2848 mProcessesToGc.remove(rec);
2849 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002850 }
2851 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002852 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002853 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854 }
2855 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002856 } else if (app.pid != pid) {
2857 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002858 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002859 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002860 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002861 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002862 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002863 + thread.asBinder());
2864 }
2865 }
2866
Dan Egnor42471dd2010-01-07 17:25:22 -08002867 /**
2868 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002869 * @param clearTraces causes the dump file to be erased prior to the new
2870 * traces being written, if true; when false, the new traces will be
2871 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002872 * @param firstPids of dalvik VM processes to dump stack traces for first
2873 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002874 * @return file containing stack traces, or null if no dump file is configured
2875 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002876 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2877 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002878 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2879 if (tracesPath == null || tracesPath.length() == 0) {
2880 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002881 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002882
2883 File tracesFile = new File(tracesPath);
2884 try {
2885 File tracesDir = tracesFile.getParentFile();
2886 if (!tracesDir.exists()) tracesFile.mkdirs();
2887 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2888
Christopher Tate6ee412d2010-05-28 12:01:56 -07002889 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002890 tracesFile.createNewFile();
2891 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2892 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002893 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002894 return null;
2895 }
2896
2897 // Use a FileObserver to detect when traces finish writing.
2898 // The order of traces is considered important to maintain for legibility.
2899 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2900 public synchronized void onEvent(int event, String path) { notify(); }
2901 };
2902
2903 try {
2904 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002905
2906 // First collect all of the stacks of the most important pids.
2907 try {
2908 int num = firstPids.size();
2909 for (int i = 0; i < num; i++) {
2910 synchronized (observer) {
2911 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2912 observer.wait(200); // Wait for write-close, give up after 200msec
2913 }
2914 }
2915 } catch (InterruptedException e) {
2916 Log.wtf(TAG, e);
2917 }
2918
2919 // Next measure CPU usage.
2920 if (processStats != null) {
2921 processStats.init();
2922 System.gc();
2923 processStats.update();
2924 try {
2925 synchronized (processStats) {
2926 processStats.wait(500); // measure over 1/2 second.
2927 }
2928 } catch (InterruptedException e) {
2929 }
2930 processStats.update();
2931
2932 // We'll take the stack crawls of just the top apps using CPU.
2933 final int N = processStats.countWorkingStats();
2934 int numProcs = 0;
2935 for (int i=0; i<N && numProcs<5; i++) {
2936 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2937 if (lastPids.indexOfKey(stats.pid) >= 0) {
2938 numProcs++;
2939 try {
2940 synchronized (observer) {
2941 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2942 observer.wait(200); // Wait for write-close, give up after 200msec
2943 }
2944 } catch (InterruptedException e) {
2945 Log.wtf(TAG, e);
2946 }
2947
2948 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002949 }
2950 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002951
2952 return tracesFile;
2953
Dan Egnor42471dd2010-01-07 17:25:22 -08002954 } finally {
2955 observer.stopWatching();
2956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 }
2958
Jeff Brown4d94a762010-09-23 11:33:28 -07002959 private final class AppNotResponding implements Runnable {
2960 private final ProcessRecord mApp;
2961 private final String mAnnotation;
2962
2963 public AppNotResponding(ProcessRecord app, String annotation) {
2964 mApp = app;
2965 mAnnotation = annotation;
2966 }
2967
2968 @Override
2969 public void run() {
2970 appNotResponding(mApp, null, null, mAnnotation);
2971 }
2972 }
2973
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002974 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2975 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002976 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2977 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2978
Dianne Hackborn287952c2010-09-22 22:34:31 -07002979 if (mController != null) {
2980 try {
2981 // 0 == continue, -1 = kill process immediately
2982 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2983 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2984 } catch (RemoteException e) {
2985 mController = null;
2986 }
2987 }
2988
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002989 long anrTime = SystemClock.uptimeMillis();
2990 if (MONITOR_CPU_USAGE) {
2991 updateCpuStatsNow();
2992 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002993
2994 synchronized (this) {
2995 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2996 if (mShuttingDown) {
2997 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2998 return;
2999 } else if (app.notResponding) {
3000 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3001 return;
3002 } else if (app.crashing) {
3003 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3004 return;
3005 }
3006
3007 // In case we come through here for the same app before completing
3008 // this one, mark as anring now so we will bail out.
3009 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003010
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003011 // Log the ANR to the event log.
3012 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3013 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003014
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003015 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003016 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003017
3018 int parentPid = app.pid;
3019 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003020 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003021
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003022 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003023
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003024 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3025 ProcessRecord r = mLruProcesses.get(i);
3026 if (r != null && r.thread != null) {
3027 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003028 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3029 if (r.persistent) {
3030 firstPids.add(pid);
3031 } else {
3032 lastPids.put(pid, Boolean.TRUE);
3033 }
3034 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 }
3037 }
3038
Dan Egnor42471dd2010-01-07 17:25:22 -08003039 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003040 StringBuilder info = mStringBuilder;
3041 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003042 info.append("ANR in ").append(app.processName);
3043 if (activity != null && activity.shortComponentName != null) {
3044 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003045 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003046 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003048 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003050 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003051 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053
Dianne Hackborn287952c2010-09-22 22:34:31 -07003054 final ProcessStats processStats = new ProcessStats(true);
3055
3056 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3057
Dan Egnor42471dd2010-01-07 17:25:22 -08003058 String cpuInfo = null;
3059 if (MONITOR_CPU_USAGE) {
3060 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003061 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003062 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003063 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003064 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003065 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 }
3067
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003068 info.append(processStats.printCurrentState(anrTime));
3069
Joe Onorato8a9b2202010-02-26 18:56:32 -08003070 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003071 if (tracesFile == null) {
3072 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3073 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3074 }
3075
Jeff Sharkeya353d262011-10-28 11:12:06 -07003076 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3077 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003078
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003079 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003080 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003081 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3082 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003083 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003084 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3085 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003086 }
3087 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003088 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003089 }
3090 }
3091
Dan Egnor42471dd2010-01-07 17:25:22 -08003092 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3093 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3094 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003095
3096 synchronized (this) {
3097 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003098 Slog.w(TAG, "Killing " + app + ": background ANR");
3099 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3100 app.processName, app.setAdj, "background ANR");
3101 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003102 return;
3103 }
3104
3105 // Set the app's notResponding state, and look up the errorReportReceiver
3106 makeAppNotRespondingLocked(app,
3107 activity != null ? activity.shortComponentName : null,
3108 annotation != null ? "ANR " + annotation : "ANR",
3109 info.toString());
3110
3111 // Bring up the infamous App Not Responding dialog
3112 Message msg = Message.obtain();
3113 HashMap map = new HashMap();
3114 msg.what = SHOW_NOT_RESPONDING_MSG;
3115 msg.obj = map;
3116 map.put("app", app);
3117 if (activity != null) {
3118 map.put("activity", activity);
3119 }
3120
3121 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 }
3124
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003125 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3126 if (!mLaunchWarningShown) {
3127 mLaunchWarningShown = true;
3128 mHandler.post(new Runnable() {
3129 @Override
3130 public void run() {
3131 synchronized (ActivityManagerService.this) {
3132 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3133 d.show();
3134 mHandler.postDelayed(new Runnable() {
3135 @Override
3136 public void run() {
3137 synchronized (ActivityManagerService.this) {
3138 d.dismiss();
3139 mLaunchWarningShown = false;
3140 }
3141 }
3142 }, 4000);
3143 }
3144 }
3145 });
3146 }
3147 }
3148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 public boolean clearApplicationUserData(final String packageName,
3150 final IPackageDataObserver observer) {
3151 int uid = Binder.getCallingUid();
3152 int pid = Binder.getCallingPid();
3153 long callingId = Binder.clearCallingIdentity();
3154 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003155 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 int pkgUid = -1;
3157 synchronized(this) {
3158 try {
3159 pkgUid = pm.getPackageUid(packageName);
3160 } catch (RemoteException e) {
3161 }
3162 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003163 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 return false;
3165 }
3166 if (uid == pkgUid || checkComponentPermission(
3167 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003168 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003170 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003171 } else {
3172 throw new SecurityException(pid+" does not have permission:"+
3173 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3174 "for process:"+packageName);
3175 }
3176 }
3177
3178 try {
3179 //clear application user data
3180 pm.clearApplicationUserData(packageName, observer);
3181 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3182 Uri.fromParts("package", packageName, null));
3183 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003184 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3185 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 } catch (RemoteException e) {
3187 }
3188 } finally {
3189 Binder.restoreCallingIdentity(callingId);
3190 }
3191 return true;
3192 }
3193
Dianne Hackborn03abb812010-01-04 18:43:19 -08003194 public void killBackgroundProcesses(final String packageName) {
3195 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3196 != PackageManager.PERMISSION_GRANTED &&
3197 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3198 != PackageManager.PERMISSION_GRANTED) {
3199 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003200 + Binder.getCallingPid()
3201 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003202 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003203 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003204 throw new SecurityException(msg);
3205 }
3206
3207 long callingId = Binder.clearCallingIdentity();
3208 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003209 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003210 int pkgUid = -1;
3211 synchronized(this) {
3212 try {
3213 pkgUid = pm.getPackageUid(packageName);
3214 } catch (RemoteException e) {
3215 }
3216 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003217 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 return;
3219 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003220 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003221 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3222 }
3223 } finally {
3224 Binder.restoreCallingIdentity(callingId);
3225 }
3226 }
3227
3228 public void killAllBackgroundProcesses() {
3229 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3230 != PackageManager.PERMISSION_GRANTED) {
3231 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3232 + Binder.getCallingPid()
3233 + ", uid=" + Binder.getCallingUid()
3234 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3235 Slog.w(TAG, msg);
3236 throw new SecurityException(msg);
3237 }
3238
3239 long callingId = Binder.clearCallingIdentity();
3240 try {
3241 synchronized(this) {
3242 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3243 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3244 final int NA = apps.size();
3245 for (int ia=0; ia<NA; ia++) {
3246 ProcessRecord app = apps.valueAt(ia);
3247 if (app.persistent) {
3248 // we don't kill persistent processes
3249 continue;
3250 }
3251 if (app.removed) {
3252 procs.add(app);
3253 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3254 app.removed = true;
3255 procs.add(app);
3256 }
3257 }
3258 }
3259
3260 int N = procs.size();
3261 for (int i=0; i<N; i++) {
3262 removeProcessLocked(procs.get(i), false, true, "kill all background");
3263 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003264 }
3265 } finally {
3266 Binder.restoreCallingIdentity(callingId);
3267 }
3268 }
3269
3270 public void forceStopPackage(final String packageName) {
3271 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3272 != PackageManager.PERMISSION_GRANTED) {
3273 String msg = "Permission Denial: forceStopPackage() from pid="
3274 + Binder.getCallingPid()
3275 + ", uid=" + Binder.getCallingUid()
3276 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003277 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003278 throw new SecurityException(msg);
3279 }
3280
3281 long callingId = Binder.clearCallingIdentity();
3282 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003283 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003284 int pkgUid = -1;
3285 synchronized(this) {
3286 try {
3287 pkgUid = pm.getPackageUid(packageName);
3288 } catch (RemoteException e) {
3289 }
3290 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003291 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003292 return;
3293 }
3294 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003295 try {
3296 pm.setPackageStoppedState(packageName, true);
3297 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003298 } catch (IllegalArgumentException e) {
3299 Slog.w(TAG, "Failed trying to unstop package "
3300 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003302 }
3303 } finally {
3304 Binder.restoreCallingIdentity(callingId);
3305 }
3306 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003307
3308 /*
3309 * The pkg name and uid have to be specified.
3310 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3311 */
3312 public void killApplicationWithUid(String pkg, int uid) {
3313 if (pkg == null) {
3314 return;
3315 }
3316 // Make sure the uid is valid.
3317 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003318 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003319 return;
3320 }
3321 int callerUid = Binder.getCallingUid();
3322 // Only the system server can kill an application
3323 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003324 // Post an aysnc message to kill the application
3325 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3326 msg.arg1 = uid;
3327 msg.arg2 = 0;
3328 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003329 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003330 } else {
3331 throw new SecurityException(callerUid + " cannot kill pkg: " +
3332 pkg);
3333 }
3334 }
3335
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003336 public void closeSystemDialogs(String reason) {
3337 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003338 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003339 if (reason != null) {
3340 intent.putExtra("reason", reason);
3341 }
3342
3343 final int uid = Binder.getCallingUid();
3344 final long origId = Binder.clearCallingIdentity();
3345 synchronized (this) {
3346 int i = mWatchers.beginBroadcast();
3347 while (i > 0) {
3348 i--;
3349 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3350 if (w != null) {
3351 try {
3352 w.closingSystemDialogs(reason);
3353 } catch (RemoteException e) {
3354 }
3355 }
3356 }
3357 mWatchers.finishBroadcast();
3358
Dianne Hackbornffa42482009-09-23 22:20:11 -07003359 mWindowManager.closeSystemDialogs(reason);
3360
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003361 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3362 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003363 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003364 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003365 Activity.RESULT_CANCELED, null, "close-sys");
3366 }
3367 }
3368
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003369 broadcastIntentLocked(null, null, intent, null,
3370 null, 0, null, null, null, false, false, -1, uid);
3371 }
3372 Binder.restoreCallingIdentity(origId);
3373 }
3374
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003375 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003376 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003377 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3378 for (int i=pids.length-1; i>=0; i--) {
3379 infos[i] = new Debug.MemoryInfo();
3380 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003381 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003382 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003383 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003384
Dianne Hackbornb437e092011-08-05 17:50:29 -07003385 public long[] getProcessPss(int[] pids) throws RemoteException {
3386 long[] pss = new long[pids.length];
3387 for (int i=pids.length-1; i>=0; i--) {
3388 pss[i] = Debug.getPss(pids[i]);
3389 }
3390 return pss;
3391 }
3392
Christopher Tate5e1ab332009-09-01 20:32:49 -07003393 public void killApplicationProcess(String processName, int uid) {
3394 if (processName == null) {
3395 return;
3396 }
3397
3398 int callerUid = Binder.getCallingUid();
3399 // Only the system server can kill an application
3400 if (callerUid == Process.SYSTEM_UID) {
3401 synchronized (this) {
3402 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003403 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003404 try {
3405 app.thread.scheduleSuicide();
3406 } catch (RemoteException e) {
3407 // If the other end already died, then our work here is done.
3408 }
3409 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003410 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003411 + processName + " / " + uid);
3412 }
3413 }
3414 } else {
3415 throw new SecurityException(callerUid + " cannot kill app process: " +
3416 processName);
3417 }
3418 }
3419
Dianne Hackborn03abb812010-01-04 18:43:19 -08003420 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003421 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003422 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3423 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003424 if (!mProcessesReady) {
3425 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003427 intent.putExtra(Intent.EXTRA_UID, uid);
3428 broadcastIntentLocked(null, null, intent,
3429 null, null, 0, null, null, null,
3430 false, false, MY_PID, Process.SYSTEM_UID);
3431 }
3432
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003433 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003434 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003435 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003436 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437
Dianne Hackborn03abb812010-01-04 18:43:19 -08003438 // Remove all processes this package may have touched: all with the
3439 // same UID (except for the system or root user), and all whose name
3440 // matches the package name.
3441 final String procNamePrefix = packageName + ":";
3442 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3443 final int NA = apps.size();
3444 for (int ia=0; ia<NA; ia++) {
3445 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003446 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003447 // we don't kill persistent processes
3448 continue;
3449 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003450 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003451 if (doit) {
3452 procs.add(app);
3453 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003454 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3455 || app.processName.equals(packageName)
3456 || app.processName.startsWith(procNamePrefix)) {
3457 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003458 if (!doit) {
3459 return true;
3460 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003461 app.removed = true;
3462 procs.add(app);
3463 }
3464 }
3465 }
3466 }
3467
3468 int N = procs.size();
3469 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003470 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003471 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003472 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003473 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003474
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003475 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003476 boolean callerWillRestart, boolean purgeCache, boolean doit,
3477 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003478 int i;
3479 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003481 if (uid < 0) {
3482 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003483 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 } catch (RemoteException e) {
3485 }
3486 }
3487
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003488 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003489 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003490
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003491 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3492 while (badApps.hasNext()) {
3493 SparseArray<Long> ba = badApps.next();
3494 if (ba.get(uid) != null) {
3495 badApps.remove();
3496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 }
3498 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003499
3500 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003501 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003502
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003503 TaskRecord lastTask = null;
3504 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003505 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003506 final boolean samePackage = r.packageName.equals(name);
3507 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003508 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003509 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003510 if (r.finishing) {
3511 // If this activity is just finishing, then it is not
3512 // interesting as far as something to stop.
3513 continue;
3514 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003515 return true;
3516 }
3517 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003518 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003519 if (samePackage) {
3520 if (r.app != null) {
3521 r.app.removed = true;
3522 }
3523 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003525 lastTask = r.task;
3526 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3527 null, "force-stop")) {
3528 i--;
3529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 }
3531 }
3532
3533 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3534 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003535 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003536 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003537 if (!doit) {
3538 return true;
3539 }
3540 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003541 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 if (service.app != null) {
3543 service.app.removed = true;
3544 }
3545 service.app = null;
3546 services.add(service);
3547 }
3548 }
3549
3550 N = services.size();
3551 for (i=0; i<N; i++) {
3552 bringDownServiceLocked(services.get(i), true);
3553 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003554
3555 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3556 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3557 if (provider.info.packageName.equals(name)
3558 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3559 if (!doit) {
3560 return true;
3561 }
3562 didSomething = true;
3563 providers.add(provider);
3564 }
3565 }
3566
3567 N = providers.size();
3568 for (i=0; i<N; i++) {
3569 removeDyingProviderLocked(null, providers.get(i));
3570 }
3571
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003572 if (doit) {
3573 if (purgeCache) {
3574 AttributeCache ac = AttributeCache.instance();
3575 if (ac != null) {
3576 ac.removePackage(name);
3577 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003578 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003579 if (mBooted) {
3580 mMainStack.resumeTopActivityLocked(null);
3581 mMainStack.scheduleIdleLocked();
3582 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003583 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003584
3585 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003586 }
3587
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003588 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003589 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003590 final String name = app.processName;
3591 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003592 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003593 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 + "/" + uid + ")");
3595
3596 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003597 if (mHeavyWeightProcess == app) {
3598 mHeavyWeightProcess = null;
3599 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3600 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 boolean needRestart = false;
3602 if (app.pid > 0 && app.pid != MY_PID) {
3603 int pid = app.pid;
3604 synchronized (mPidsSelfLocked) {
3605 mPidsSelfLocked.remove(pid);
3606 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3607 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003608 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003609 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003610 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003611 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612
3613 if (app.persistent) {
3614 if (!callerWillRestart) {
3615 addAppLocked(app.info);
3616 } else {
3617 needRestart = true;
3618 }
3619 }
3620 } else {
3621 mRemovedProcesses.add(app);
3622 }
3623
3624 return needRestart;
3625 }
3626
3627 private final void processStartTimedOutLocked(ProcessRecord app) {
3628 final int pid = app.pid;
3629 boolean gone = false;
3630 synchronized (mPidsSelfLocked) {
3631 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3632 if (knownApp != null && knownApp.thread == null) {
3633 mPidsSelfLocked.remove(pid);
3634 gone = true;
3635 }
3636 }
3637
3638 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003639 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003640 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003641 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003643 if (mHeavyWeightProcess == app) {
3644 mHeavyWeightProcess = null;
3645 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3646 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003647 // Take care of any launching providers waiting for this process.
3648 checkAppInLaunchingProvidersLocked(app, true);
3649 // Take care of any services that are waiting for the process.
3650 for (int i=0; i<mPendingServices.size(); i++) {
3651 ServiceRecord sr = mPendingServices.get(i);
3652 if (app.info.uid == sr.appInfo.uid
3653 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003654 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003655 mPendingServices.remove(i);
3656 i--;
3657 bringDownServiceLocked(sr, true);
3658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003660 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3661 app.processName, app.setAdj, "start timeout");
3662 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003663 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003664 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003665 try {
3666 IBackupManager bm = IBackupManager.Stub.asInterface(
3667 ServiceManager.getService(Context.BACKUP_SERVICE));
3668 bm.agentDisconnected(app.info.packageName);
3669 } catch (RemoteException e) {
3670 // Can't happen; the backup manager is local
3671 }
3672 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003673 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003674 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003675 mPendingBroadcast.state = BroadcastRecord.IDLE;
3676 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003677 mPendingBroadcast = null;
3678 scheduleBroadcastsLocked();
3679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003681 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 }
3683 }
3684
3685 private final boolean attachApplicationLocked(IApplicationThread thread,
3686 int pid) {
3687
3688 // Find the application record that is being attached... either via
3689 // the pid if we are running in multiple processes, or just pull the
3690 // next app record if we are emulating process with anonymous threads.
3691 ProcessRecord app;
3692 if (pid != MY_PID && pid >= 0) {
3693 synchronized (mPidsSelfLocked) {
3694 app = mPidsSelfLocked.get(pid);
3695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 } else {
3697 app = null;
3698 }
3699
3700 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003701 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003703 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003705 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 } else {
3707 try {
3708 thread.scheduleExit();
3709 } catch (Exception e) {
3710 // Ignore exceptions.
3711 }
3712 }
3713 return false;
3714 }
3715
3716 // If this application record is still attached to a previous
3717 // process, clean it up now.
3718 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003719 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 }
3721
3722 // Tell the process all about itself.
3723
Joe Onorato8a9b2202010-02-26 18:56:32 -08003724 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 TAG, "Binding process pid " + pid + " to record " + app);
3726
3727 String processName = app.processName;
3728 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003729 AppDeathRecipient adr = new AppDeathRecipient(
3730 app, pid, thread);
3731 thread.asBinder().linkToDeath(adr, 0);
3732 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 } catch (RemoteException e) {
3734 app.resetPackageList();
3735 startProcessLocked(app, "link fail", processName);
3736 return false;
3737 }
3738
Doug Zongker2bec3d42009-12-04 12:52:44 -08003739 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003740
3741 app.thread = thread;
3742 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003743 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3744 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 app.forcingToForeground = null;
3746 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003747 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 app.debugging = false;
3749
3750 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3751
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003752 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003753 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003754
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003755 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003756 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003757 }
3758
Joe Onorato8a9b2202010-02-26 18:56:32 -08003759 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003760 TAG, "New app record " + app
3761 + " thread=" + thread.asBinder() + " pid=" + pid);
3762 try {
3763 int testMode = IApplicationThread.DEBUG_OFF;
3764 if (mDebugApp != null && mDebugApp.equals(processName)) {
3765 testMode = mWaitForDebugger
3766 ? IApplicationThread.DEBUG_WAIT
3767 : IApplicationThread.DEBUG_ON;
3768 app.debugging = true;
3769 if (mDebugTransient) {
3770 mDebugApp = mOrigDebugApp;
3771 mWaitForDebugger = mOrigWaitForDebugger;
3772 }
3773 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003774 String profileFile = app.instrumentationProfileFile;
3775 ParcelFileDescriptor profileFd = null;
3776 boolean profileAutoStop = false;
3777 if (mProfileApp != null && mProfileApp.equals(processName)) {
3778 mProfileProc = app;
3779 profileFile = mProfileFile;
3780 profileFd = mProfileFd;
3781 profileAutoStop = mAutoStopProfiler;
3782 }
3783
Christopher Tate181fafa2009-05-14 11:12:14 -07003784 // If the app is being launched for restore or full backup, set it up specially
3785 boolean isRestrictedBackupMode = false;
3786 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3787 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003788 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003789 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3790 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003791
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003792 ensurePackageDexOpt(app.instrumentationInfo != null
3793 ? app.instrumentationInfo.packageName
3794 : app.info.packageName);
3795 if (app.instrumentationClass != null) {
3796 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003797 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003798 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003799 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003800 ApplicationInfo appInfo = app.instrumentationInfo != null
3801 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003802 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003803 if (profileFd != null) {
3804 profileFd = profileFd.dup();
3805 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003806 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003807 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003809 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003810 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003811 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003812 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003813 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 } catch (Exception e) {
3815 // todo: Yikes! What should we do? For now we will try to
3816 // start another process, but that could easily get us in
3817 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003818 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819
3820 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003821 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 startProcessLocked(app, "bind fail", processName);
3823 return false;
3824 }
3825
3826 // Remove this record from the list of starting applications.
3827 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003828 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3829 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 mProcessesOnHold.remove(app);
3831
3832 boolean badApp = false;
3833 boolean didSomething = false;
3834
3835 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003836 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003837 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3839 && processName.equals(hr.processName)) {
3840 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003841 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 didSomething = true;
3843 }
3844 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003845 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 + hr.intent.getComponent().flattenToShortString(), e);
3847 badApp = true;
3848 }
3849 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003850 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 }
3852 }
3853
3854 // Find any services that should be running in this process...
3855 if (!badApp && mPendingServices.size() > 0) {
3856 ServiceRecord sr = null;
3857 try {
3858 for (int i=0; i<mPendingServices.size(); i++) {
3859 sr = mPendingServices.get(i);
3860 if (app.info.uid != sr.appInfo.uid
3861 || !processName.equals(sr.processName)) {
3862 continue;
3863 }
3864
3865 mPendingServices.remove(i);
3866 i--;
3867 realStartServiceLocked(sr, app);
3868 didSomething = true;
3869 }
3870 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003871 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 + sr.shortName, e);
3873 badApp = true;
3874 }
3875 }
3876
3877 // Check if the next broadcast receiver is in this process...
3878 BroadcastRecord br = mPendingBroadcast;
3879 if (!badApp && br != null && br.curApp == app) {
3880 try {
3881 mPendingBroadcast = null;
3882 processCurBroadcastLocked(br, app);
3883 didSomething = true;
3884 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003885 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 + br.curComponent.flattenToShortString(), e);
3887 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003888 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3890 br.resultExtras, br.resultAbort, true);
3891 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003892 // We need to reset the state if we fails to start the receiver.
3893 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 }
3895 }
3896
Christopher Tate181fafa2009-05-14 11:12:14 -07003897 // Check whether the next backup agent is in this process...
3898 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003899 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003900 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003901 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003902 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3903 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3904 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003905 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003906 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003907 e.printStackTrace();
3908 }
3909 }
3910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 if (badApp) {
3912 // todo: Also need to kill application to deal with all
3913 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003914 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 return false;
3916 }
3917
3918 if (!didSomething) {
3919 updateOomAdjLocked();
3920 }
3921
3922 return true;
3923 }
3924
3925 public final void attachApplication(IApplicationThread thread) {
3926 synchronized (this) {
3927 int callingPid = Binder.getCallingPid();
3928 final long origId = Binder.clearCallingIdentity();
3929 attachApplicationLocked(thread, callingPid);
3930 Binder.restoreCallingIdentity(origId);
3931 }
3932 }
3933
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003934 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003936 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3937 if (stopProfiling) {
3938 synchronized (this) {
3939 if (mProfileProc == r.app) {
3940 if (mProfileFd != null) {
3941 try {
3942 mProfileFd.close();
3943 } catch (IOException e) {
3944 }
3945 clearProfilerLocked();
3946 }
3947 }
3948 }
3949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 Binder.restoreCallingIdentity(origId);
3951 }
3952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003954 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003955 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 mWindowManager.enableScreenAfterBoot();
3957 }
3958
Dianne Hackborn661cd522011-08-22 00:26:20 -07003959 public void showBootMessage(final CharSequence msg, final boolean always) {
3960 mWindowManager.showBootMessage(msg, always);
3961 }
3962
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003963 public void dismissKeyguardOnNextActivity() {
3964 synchronized (this) {
3965 mMainStack.dismissKeyguardOnNextActivityLocked();
3966 }
3967 }
3968
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003969 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003970 IntentFilter pkgFilter = new IntentFilter();
3971 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3972 pkgFilter.addDataScheme("package");
3973 mContext.registerReceiver(new BroadcastReceiver() {
3974 @Override
3975 public void onReceive(Context context, Intent intent) {
3976 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3977 if (pkgs != null) {
3978 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003979 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003980 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003981 setResultCode(Activity.RESULT_OK);
3982 return;
3983 }
3984 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003985 }
3986 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003987 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003988 }, pkgFilter);
3989
3990 synchronized (this) {
3991 // Ensure that any processes we had put on hold are now started
3992 // up.
3993 final int NP = mProcessesOnHold.size();
3994 if (NP > 0) {
3995 ArrayList<ProcessRecord> procs =
3996 new ArrayList<ProcessRecord>(mProcessesOnHold);
3997 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003998 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3999 + procs.get(ip));
4000 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004001 }
4002 }
4003
4004 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004005 // Start looking for apps that are abusing wake locks.
4006 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004007 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004008 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004009 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004010 broadcastIntentLocked(null, null,
4011 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4012 null, null, 0, null, null,
4013 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4014 false, false, MY_PID, Process.SYSTEM_UID);
4015 }
4016 }
4017 }
4018
4019 final void ensureBootCompleted() {
4020 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004021 boolean enableScreen;
4022 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004023 booting = mBooting;
4024 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004025 enableScreen = !mBooted;
4026 mBooted = true;
4027 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004028
4029 if (booting) {
4030 finishBooting();
4031 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004032
4033 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004034 enableScreenAfterBoot();
4035 }
4036 }
4037
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004038 public final void activityPaused(IBinder token) {
4039 final long origId = Binder.clearCallingIdentity();
4040 mMainStack.activityPaused(token, false);
4041 Binder.restoreCallingIdentity(origId);
4042 }
4043
4044 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4045 CharSequence description) {
4046 if (localLOGV) Slog.v(
4047 TAG, "Activity stopped: token=" + token);
4048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 // Refuse possible leaked file descriptors
4050 if (icicle != null && icicle.hasFileDescriptors()) {
4051 throw new IllegalArgumentException("File descriptors passed in Bundle");
4052 }
4053
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004054 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055
4056 final long origId = Binder.clearCallingIdentity();
4057
4058 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004059 r = mMainStack.isInStackLocked(token);
4060 if (r != null) {
4061 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004062 }
4063 }
4064
4065 if (r != null) {
4066 sendPendingThumbnail(r, null, null, null, false);
4067 }
4068
4069 trimApplications();
4070
4071 Binder.restoreCallingIdentity(origId);
4072 }
4073
4074 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004075 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004076 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004077 }
4078
4079 public String getCallingPackage(IBinder token) {
4080 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004081 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004082 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 }
4084 }
4085
4086 public ComponentName getCallingActivity(IBinder token) {
4087 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004088 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 return r != null ? r.intent.getComponent() : null;
4090 }
4091 }
4092
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004093 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004094 ActivityRecord r = mMainStack.isInStackLocked(token);
4095 if (r == null) {
4096 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004098 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004099 }
4100
4101 public ComponentName getActivityClassForToken(IBinder token) {
4102 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004103 ActivityRecord r = mMainStack.isInStackLocked(token);
4104 if (r == null) {
4105 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004106 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004107 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004108 }
4109 }
4110
4111 public String getPackageForToken(IBinder token) {
4112 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004113 ActivityRecord r = mMainStack.isInStackLocked(token);
4114 if (r == null) {
4115 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004117 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118 }
4119 }
4120
4121 public IIntentSender getIntentSender(int type,
4122 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004123 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004124 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004125 if (intents != null) {
4126 if (intents.length < 1) {
4127 throw new IllegalArgumentException("Intents array length must be >= 1");
4128 }
4129 for (int i=0; i<intents.length; i++) {
4130 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004131 if (intent != null) {
4132 if (intent.hasFileDescriptors()) {
4133 throw new IllegalArgumentException("File descriptors passed in Intent");
4134 }
4135 if (type == INTENT_SENDER_BROADCAST &&
4136 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4137 throw new IllegalArgumentException(
4138 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4139 }
4140 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004141 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004142 }
4143 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004144 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004145 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004146 }
4147 }
4148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149 synchronized(this) {
4150 int callingUid = Binder.getCallingUid();
4151 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004152 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004153 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004154 .getPackageUid(packageName);
4155 if (uid != Binder.getCallingUid()) {
4156 String msg = "Permission Denial: getIntentSender() from pid="
4157 + Binder.getCallingPid()
4158 + ", uid=" + Binder.getCallingUid()
4159 + ", (need uid=" + uid + ")"
4160 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004161 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004162 throw new SecurityException(msg);
4163 }
4164 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004165
4166 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004167 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 } catch (RemoteException e) {
4170 throw new SecurityException(e);
4171 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004172 }
4173 }
4174
4175 IIntentSender getIntentSenderLocked(int type,
4176 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004177 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004178 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004179 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004180 activity = mMainStack.isInStackLocked(token);
4181 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004182 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004184 if (activity.finishing) {
4185 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004186 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004187 }
4188
4189 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4190 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4191 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4192 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4193 |PendingIntent.FLAG_UPDATE_CURRENT);
4194
4195 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4196 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004197 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004198 WeakReference<PendingIntentRecord> ref;
4199 ref = mIntentSenderRecords.get(key);
4200 PendingIntentRecord rec = ref != null ? ref.get() : null;
4201 if (rec != null) {
4202 if (!cancelCurrent) {
4203 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004204 if (rec.key.requestIntent != null) {
4205 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4206 }
4207 if (intents != null) {
4208 intents[intents.length-1] = rec.key.requestIntent;
4209 rec.key.allIntents = intents;
4210 rec.key.allResolvedTypes = resolvedTypes;
4211 } else {
4212 rec.key.allIntents = null;
4213 rec.key.allResolvedTypes = null;
4214 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 return rec;
4217 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004218 rec.canceled = true;
4219 mIntentSenderRecords.remove(key);
4220 }
4221 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 return rec;
4223 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004224 rec = new PendingIntentRecord(this, key, callingUid);
4225 mIntentSenderRecords.put(key, rec.ref);
4226 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4227 if (activity.pendingResults == null) {
4228 activity.pendingResults
4229 = new HashSet<WeakReference<PendingIntentRecord>>();
4230 }
4231 activity.pendingResults.add(rec.ref);
4232 }
4233 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 }
4235
4236 public void cancelIntentSender(IIntentSender sender) {
4237 if (!(sender instanceof PendingIntentRecord)) {
4238 return;
4239 }
4240 synchronized(this) {
4241 PendingIntentRecord rec = (PendingIntentRecord)sender;
4242 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004243 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 .getPackageUid(rec.key.packageName);
4245 if (uid != Binder.getCallingUid()) {
4246 String msg = "Permission Denial: cancelIntentSender() from pid="
4247 + Binder.getCallingPid()
4248 + ", uid=" + Binder.getCallingUid()
4249 + " is not allowed to cancel packges "
4250 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004251 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 throw new SecurityException(msg);
4253 }
4254 } catch (RemoteException e) {
4255 throw new SecurityException(e);
4256 }
4257 cancelIntentSenderLocked(rec, true);
4258 }
4259 }
4260
4261 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4262 rec.canceled = true;
4263 mIntentSenderRecords.remove(rec.key);
4264 if (cleanActivity && rec.key.activity != null) {
4265 rec.key.activity.pendingResults.remove(rec.ref);
4266 }
4267 }
4268
4269 public String getPackageForIntentSender(IIntentSender pendingResult) {
4270 if (!(pendingResult instanceof PendingIntentRecord)) {
4271 return null;
4272 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004273 try {
4274 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4275 return res.key.packageName;
4276 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 }
4278 return null;
4279 }
4280
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004281 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4282 if (!(pendingResult instanceof PendingIntentRecord)) {
4283 return false;
4284 }
4285 try {
4286 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4287 if (res.key.allIntents == null) {
4288 return false;
4289 }
4290 for (int i=0; i<res.key.allIntents.length; i++) {
4291 Intent intent = res.key.allIntents[i];
4292 if (intent.getPackage() != null && intent.getComponent() != null) {
4293 return false;
4294 }
4295 }
4296 return true;
4297 } catch (ClassCastException e) {
4298 }
4299 return false;
4300 }
4301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 public void setProcessLimit(int max) {
4303 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4304 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004305 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004306 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004307 mProcessLimitOverride = max;
4308 }
4309 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004310 }
4311
4312 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004313 synchronized (this) {
4314 return mProcessLimitOverride;
4315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 }
4317
4318 void foregroundTokenDied(ForegroundToken token) {
4319 synchronized (ActivityManagerService.this) {
4320 synchronized (mPidsSelfLocked) {
4321 ForegroundToken cur
4322 = mForegroundProcesses.get(token.pid);
4323 if (cur != token) {
4324 return;
4325 }
4326 mForegroundProcesses.remove(token.pid);
4327 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4328 if (pr == null) {
4329 return;
4330 }
4331 pr.forcingToForeground = null;
4332 pr.foregroundServices = false;
4333 }
4334 updateOomAdjLocked();
4335 }
4336 }
4337
4338 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4339 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4340 "setProcessForeground()");
4341 synchronized(this) {
4342 boolean changed = false;
4343
4344 synchronized (mPidsSelfLocked) {
4345 ProcessRecord pr = mPidsSelfLocked.get(pid);
4346 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004347 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 return;
4349 }
4350 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4351 if (oldToken != null) {
4352 oldToken.token.unlinkToDeath(oldToken, 0);
4353 mForegroundProcesses.remove(pid);
4354 pr.forcingToForeground = null;
4355 changed = true;
4356 }
4357 if (isForeground && token != null) {
4358 ForegroundToken newToken = new ForegroundToken() {
4359 public void binderDied() {
4360 foregroundTokenDied(this);
4361 }
4362 };
4363 newToken.pid = pid;
4364 newToken.token = token;
4365 try {
4366 token.linkToDeath(newToken, 0);
4367 mForegroundProcesses.put(pid, newToken);
4368 pr.forcingToForeground = token;
4369 changed = true;
4370 } catch (RemoteException e) {
4371 // If the process died while doing this, we will later
4372 // do the cleanup with the process death link.
4373 }
4374 }
4375 }
4376
4377 if (changed) {
4378 updateOomAdjLocked();
4379 }
4380 }
4381 }
4382
4383 // =========================================================
4384 // PERMISSIONS
4385 // =========================================================
4386
4387 static class PermissionController extends IPermissionController.Stub {
4388 ActivityManagerService mActivityManagerService;
4389 PermissionController(ActivityManagerService activityManagerService) {
4390 mActivityManagerService = activityManagerService;
4391 }
4392
4393 public boolean checkPermission(String permission, int pid, int uid) {
4394 return mActivityManagerService.checkPermission(permission, pid,
4395 uid) == PackageManager.PERMISSION_GRANTED;
4396 }
4397 }
4398
4399 /**
4400 * This can be called with or without the global lock held.
4401 */
4402 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004403 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 // We might be performing an operation on behalf of an indirect binder
4405 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4406 // client identity accordingly before proceeding.
4407 Identity tlsIdentity = sCallerIdentity.get();
4408 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004409 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4411 uid = tlsIdentity.uid;
4412 pid = tlsIdentity.pid;
4413 }
4414
4415 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004416 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 return PackageManager.PERMISSION_GRANTED;
4418 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004419 // If there is a uid that owns whatever is being accessed, it has
4420 // blanket access to it regardless of the permissions it requires.
4421 if (owningUid >= 0 && uid == owningUid) {
4422 return PackageManager.PERMISSION_GRANTED;
4423 }
4424 // If the target is not exported, then nobody else can get to it.
4425 if (!exported) {
4426 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 return PackageManager.PERMISSION_DENIED;
4428 }
4429 if (permission == null) {
4430 return PackageManager.PERMISSION_GRANTED;
4431 }
4432 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004433 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 .checkUidPermission(permission, uid);
4435 } catch (RemoteException e) {
4436 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004437 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 }
4439 return PackageManager.PERMISSION_DENIED;
4440 }
4441
4442 /**
4443 * As the only public entry point for permissions checking, this method
4444 * can enforce the semantic that requesting a check on a null global
4445 * permission is automatically denied. (Internally a null permission
4446 * string is used when calling {@link #checkComponentPermission} in cases
4447 * when only uid-based security is needed.)
4448 *
4449 * This can be called with or without the global lock held.
4450 */
4451 public int checkPermission(String permission, int pid, int uid) {
4452 if (permission == null) {
4453 return PackageManager.PERMISSION_DENIED;
4454 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004455 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004456 }
4457
4458 /**
4459 * Binder IPC calls go through the public entry point.
4460 * This can be called with or without the global lock held.
4461 */
4462 int checkCallingPermission(String permission) {
4463 return checkPermission(permission,
4464 Binder.getCallingPid(),
4465 Binder.getCallingUid());
4466 }
4467
4468 /**
4469 * This can be called with or without the global lock held.
4470 */
4471 void enforceCallingPermission(String permission, String func) {
4472 if (checkCallingPermission(permission)
4473 == PackageManager.PERMISSION_GRANTED) {
4474 return;
4475 }
4476
4477 String msg = "Permission Denial: " + func + " from pid="
4478 + Binder.getCallingPid()
4479 + ", uid=" + Binder.getCallingUid()
4480 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004481 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 throw new SecurityException(msg);
4483 }
4484
4485 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004486 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4487 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4488 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4489 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4490 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004492 // Is the component private from the target uid?
4493 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4494
4495 // Acceptable if the there is no read permission needed from the
4496 // target or the target is holding the read permission.
4497 if (!readPerm) {
4498 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004500 == PackageManager.PERMISSION_GRANTED)) {
4501 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 }
4503 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004504
4505 // Acceptable if the there is no write permission needed from the
4506 // target or the target is holding the read permission.
4507 if (!writePerm) {
4508 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004510 == PackageManager.PERMISSION_GRANTED)) {
4511 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 }
4513 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004514
4515 // Acceptable if there is a path permission matching the URI that
4516 // the target holds the permission on.
4517 PathPermission[] pps = pi.pathPermissions;
4518 if (pps != null && (!readPerm || !writePerm)) {
4519 final String path = uri.getPath();
4520 int i = pps.length;
4521 while (i > 0 && (!readPerm || !writePerm)) {
4522 i--;
4523 PathPermission pp = pps[i];
4524 if (!readPerm) {
4525 final String pprperm = pp.getReadPermission();
4526 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4527 + pprperm + " for " + pp.getPath()
4528 + ": match=" + pp.match(path)
4529 + " check=" + pm.checkUidPermission(pprperm, uid));
4530 if (pprperm != null && pp.match(path) &&
4531 (pm.checkUidPermission(pprperm, uid)
4532 == PackageManager.PERMISSION_GRANTED)) {
4533 readPerm = true;
4534 }
4535 }
4536 if (!writePerm) {
4537 final String ppwperm = pp.getWritePermission();
4538 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4539 + ppwperm + " for " + pp.getPath()
4540 + ": match=" + pp.match(path)
4541 + " check=" + pm.checkUidPermission(ppwperm, uid));
4542 if (ppwperm != null && pp.match(path) &&
4543 (pm.checkUidPermission(ppwperm, uid)
4544 == PackageManager.PERMISSION_GRANTED)) {
4545 writePerm = true;
4546 }
4547 }
4548 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 } catch (RemoteException e) {
4551 return false;
4552 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004553
4554 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004555 }
4556
4557 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4558 int modeFlags) {
4559 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004560 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 return true;
4562 }
4563 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4564 if (perms == null) return false;
4565 UriPermission perm = perms.get(uri);
4566 if (perm == null) return false;
4567 return (modeFlags&perm.modeFlags) == modeFlags;
4568 }
4569
4570 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4571 // Another redirected-binder-call permissions check as in
4572 // {@link checkComponentPermission}.
4573 Identity tlsIdentity = sCallerIdentity.get();
4574 if (tlsIdentity != null) {
4575 uid = tlsIdentity.uid;
4576 pid = tlsIdentity.pid;
4577 }
4578
4579 // Our own process gets to do everything.
4580 if (pid == MY_PID) {
4581 return PackageManager.PERMISSION_GRANTED;
4582 }
4583 synchronized(this) {
4584 return checkUriPermissionLocked(uri, uid, modeFlags)
4585 ? PackageManager.PERMISSION_GRANTED
4586 : PackageManager.PERMISSION_DENIED;
4587 }
4588 }
4589
Dianne Hackborn39792d22010-08-19 18:01:52 -07004590 /**
4591 * Check if the targetPkg can be granted permission to access uri by
4592 * the callingUid using the given modeFlags. Throws a security exception
4593 * if callingUid is not allowed to do this. Returns the uid of the target
4594 * if the URI permission grant should be performed; returns -1 if it is not
4595 * needed (for example targetPkg already has permission to access the URI).
4596 */
4597 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4598 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4600 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4601 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004602 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 }
4604
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004605 if (targetPkg != null) {
4606 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4607 "Checking grant " + targetPkg + " permission to " + uri);
4608 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004609
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004610 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611
4612 // If this is not a content: uri, we can't do anything with it.
4613 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004614 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004615 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004616 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617 }
4618
4619 String name = uri.getAuthority();
4620 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004621 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 if (cpr != null) {
4623 pi = cpr.info;
4624 } else {
4625 try {
4626 pi = pm.resolveContentProvider(name,
4627 PackageManager.GET_URI_PERMISSION_PATTERNS);
4628 } catch (RemoteException ex) {
4629 }
4630 }
4631 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004632 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004633 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 }
4635
4636 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004637 if (targetPkg != null) {
4638 try {
4639 targetUid = pm.getPackageUid(targetPkg);
4640 if (targetUid < 0) {
4641 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4642 "Can't grant URI permission no uid for: " + targetPkg);
4643 return -1;
4644 }
4645 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004646 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004648 } else {
4649 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 }
4651
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004652 if (targetUid >= 0) {
4653 // First... does the target actually need this permission?
4654 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4655 // No need to grant the target this permission.
4656 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4657 "Target " + targetPkg + " already has full permission to " + uri);
4658 return -1;
4659 }
4660 } else {
4661 // First... there is no target package, so can anyone access it?
4662 boolean allowed = pi.exported;
4663 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4664 if (pi.readPermission != null) {
4665 allowed = false;
4666 }
4667 }
4668 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4669 if (pi.writePermission != null) {
4670 allowed = false;
4671 }
4672 }
4673 if (allowed) {
4674 return -1;
4675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 }
4677
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004678 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 if (!pi.grantUriPermissions) {
4680 throw new SecurityException("Provider " + pi.packageName
4681 + "/" + pi.name
4682 + " does not allow granting of Uri permissions (uri "
4683 + uri + ")");
4684 }
4685 if (pi.uriPermissionPatterns != null) {
4686 final int N = pi.uriPermissionPatterns.length;
4687 boolean allowed = false;
4688 for (int i=0; i<N; i++) {
4689 if (pi.uriPermissionPatterns[i] != null
4690 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4691 allowed = true;
4692 break;
4693 }
4694 }
4695 if (!allowed) {
4696 throw new SecurityException("Provider " + pi.packageName
4697 + "/" + pi.name
4698 + " does not allow granting of permission to path of Uri "
4699 + uri);
4700 }
4701 }
4702
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004703 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004705 if (callingUid != Process.myUid()) {
4706 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4707 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4708 throw new SecurityException("Uid " + callingUid
4709 + " does not have permission to uri " + uri);
4710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 }
4712 }
4713
Dianne Hackborn39792d22010-08-19 18:01:52 -07004714 return targetUid;
4715 }
4716
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004717 public int checkGrantUriPermission(int callingUid, String targetPkg,
4718 Uri uri, int modeFlags) {
4719 synchronized(this) {
4720 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4721 }
4722 }
4723
Dianne Hackborn39792d22010-08-19 18:01:52 -07004724 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4725 Uri uri, int modeFlags, UriPermissionOwner owner) {
4726 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4727 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4728 if (modeFlags == 0) {
4729 return;
4730 }
4731
4732 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 // to the uri, and the target doesn't. Let's now give this to
4734 // the target.
4735
Joe Onorato8a9b2202010-02-26 18:56:32 -08004736 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004737 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 HashMap<Uri, UriPermission> targetUris
4740 = mGrantedUriPermissions.get(targetUid);
4741 if (targetUris == null) {
4742 targetUris = new HashMap<Uri, UriPermission>();
4743 mGrantedUriPermissions.put(targetUid, targetUris);
4744 }
4745
4746 UriPermission perm = targetUris.get(uri);
4747 if (perm == null) {
4748 perm = new UriPermission(targetUid, uri);
4749 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004753 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004755 } else {
4756 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4757 perm.readOwners.add(owner);
4758 owner.addReadPermission(perm);
4759 }
4760 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4761 perm.writeOwners.add(owner);
4762 owner.addWritePermission(perm);
4763 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 }
4765 }
4766
Dianne Hackborn39792d22010-08-19 18:01:52 -07004767 void grantUriPermissionLocked(int callingUid,
4768 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004769 if (targetPkg == null) {
4770 throw new NullPointerException("targetPkg");
4771 }
4772
Dianne Hackborn39792d22010-08-19 18:01:52 -07004773 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4774 if (targetUid < 0) {
4775 return;
4776 }
4777
4778 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4779 }
4780
4781 /**
4782 * Like checkGrantUriPermissionLocked, but takes an Intent.
4783 */
4784 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4785 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004786 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004787 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004788 + " from " + intent + "; flags=0x"
4789 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4790
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004791 if (targetPkg == null) {
4792 throw new NullPointerException("targetPkg");
4793 }
4794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004796 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004797 }
4798 Uri data = intent.getData();
4799 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004800 return -1;
4801 }
4802 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4803 intent.getFlags());
4804 }
4805
4806 /**
4807 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4808 */
4809 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4810 String targetPkg, Intent intent, UriPermissionOwner owner) {
4811 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4812 intent.getFlags(), owner);
4813 }
4814
4815 void grantUriPermissionFromIntentLocked(int callingUid,
4816 String targetPkg, Intent intent, UriPermissionOwner owner) {
4817 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4818 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004819 return;
4820 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004821
4822 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823 }
4824
4825 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4826 Uri uri, int modeFlags) {
4827 synchronized(this) {
4828 final ProcessRecord r = getRecordForAppLocked(caller);
4829 if (r == null) {
4830 throw new SecurityException("Unable to find app for caller "
4831 + caller
4832 + " when granting permission to uri " + uri);
4833 }
4834 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004835 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 }
4837 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004838 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004839 }
4840
4841 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4842 null);
4843 }
4844 }
4845
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004846 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4848 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4849 HashMap<Uri, UriPermission> perms
4850 = mGrantedUriPermissions.get(perm.uid);
4851 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004852 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004853 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 perms.remove(perm.uri);
4855 if (perms.size() == 0) {
4856 mGrantedUriPermissions.remove(perm.uid);
4857 }
4858 }
4859 }
4860 }
4861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4863 int modeFlags) {
4864 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4865 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4866 if (modeFlags == 0) {
4867 return;
4868 }
4869
Joe Onorato8a9b2202010-02-26 18:56:32 -08004870 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004871 "Revoking all granted permissions to " + uri);
4872
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004873 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874
4875 final String authority = uri.getAuthority();
4876 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004877 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 if (cpr != null) {
4879 pi = cpr.info;
4880 } else {
4881 try {
4882 pi = pm.resolveContentProvider(authority,
4883 PackageManager.GET_URI_PERMISSION_PATTERNS);
4884 } catch (RemoteException ex) {
4885 }
4886 }
4887 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004888 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 return;
4890 }
4891
4892 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004893 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 // Right now, if you are not the original owner of the permission,
4895 // you are not allowed to revoke it.
4896 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4897 throw new SecurityException("Uid " + callingUid
4898 + " does not have permission to uri " + uri);
4899 //}
4900 }
4901
4902 // Go through all of the permissions and remove any that match.
4903 final List<String> SEGMENTS = uri.getPathSegments();
4904 if (SEGMENTS != null) {
4905 final int NS = SEGMENTS.size();
4906 int N = mGrantedUriPermissions.size();
4907 for (int i=0; i<N; i++) {
4908 HashMap<Uri, UriPermission> perms
4909 = mGrantedUriPermissions.valueAt(i);
4910 Iterator<UriPermission> it = perms.values().iterator();
4911 toploop:
4912 while (it.hasNext()) {
4913 UriPermission perm = it.next();
4914 Uri targetUri = perm.uri;
4915 if (!authority.equals(targetUri.getAuthority())) {
4916 continue;
4917 }
4918 List<String> targetSegments = targetUri.getPathSegments();
4919 if (targetSegments == null) {
4920 continue;
4921 }
4922 if (targetSegments.size() < NS) {
4923 continue;
4924 }
4925 for (int j=0; j<NS; j++) {
4926 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4927 continue toploop;
4928 }
4929 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004930 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004931 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 perm.clearModes(modeFlags);
4933 if (perm.modeFlags == 0) {
4934 it.remove();
4935 }
4936 }
4937 if (perms.size() == 0) {
4938 mGrantedUriPermissions.remove(
4939 mGrantedUriPermissions.keyAt(i));
4940 N--;
4941 i--;
4942 }
4943 }
4944 }
4945 }
4946
4947 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4948 int modeFlags) {
4949 synchronized(this) {
4950 final ProcessRecord r = getRecordForAppLocked(caller);
4951 if (r == null) {
4952 throw new SecurityException("Unable to find app for caller "
4953 + caller
4954 + " when revoking permission to uri " + uri);
4955 }
4956 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004957 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 return;
4959 }
4960
4961 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4962 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4963 if (modeFlags == 0) {
4964 return;
4965 }
4966
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004967 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004968
4969 final String authority = uri.getAuthority();
4970 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004971 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972 if (cpr != null) {
4973 pi = cpr.info;
4974 } else {
4975 try {
4976 pi = pm.resolveContentProvider(authority,
4977 PackageManager.GET_URI_PERMISSION_PATTERNS);
4978 } catch (RemoteException ex) {
4979 }
4980 }
4981 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004982 Slog.w(TAG, "No content provider found for permission revoke: "
4983 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004984 return;
4985 }
4986
4987 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4988 }
4989 }
4990
Dianne Hackborn7e269642010-08-25 19:50:20 -07004991 @Override
4992 public IBinder newUriPermissionOwner(String name) {
4993 synchronized(this) {
4994 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4995 return owner.getExternalTokenLocked();
4996 }
4997 }
4998
4999 @Override
5000 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5001 Uri uri, int modeFlags) {
5002 synchronized(this) {
5003 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5004 if (owner == null) {
5005 throw new IllegalArgumentException("Unknown owner: " + token);
5006 }
5007 if (fromUid != Binder.getCallingUid()) {
5008 if (Binder.getCallingUid() != Process.myUid()) {
5009 // Only system code can grant URI permissions on behalf
5010 // of other users.
5011 throw new SecurityException("nice try");
5012 }
5013 }
5014 if (targetPkg == null) {
5015 throw new IllegalArgumentException("null target");
5016 }
5017 if (uri == null) {
5018 throw new IllegalArgumentException("null uri");
5019 }
5020
5021 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5022 }
5023 }
5024
5025 @Override
5026 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5027 synchronized(this) {
5028 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5029 if (owner == null) {
5030 throw new IllegalArgumentException("Unknown owner: " + token);
5031 }
5032
5033 if (uri == null) {
5034 owner.removeUriPermissionsLocked(mode);
5035 } else {
5036 owner.removeUriPermissionLocked(uri, mode);
5037 }
5038 }
5039 }
5040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5042 synchronized (this) {
5043 ProcessRecord app =
5044 who != null ? getRecordForAppLocked(who) : null;
5045 if (app == null) return;
5046
5047 Message msg = Message.obtain();
5048 msg.what = WAIT_FOR_DEBUGGER_MSG;
5049 msg.obj = app;
5050 msg.arg1 = waiting ? 1 : 0;
5051 mHandler.sendMessage(msg);
5052 }
5053 }
5054
5055 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005056 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5057 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005059 outInfo.threshold = homeAppMem;
5060 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5061 outInfo.hiddenAppThreshold = hiddenAppMem;
5062 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005063 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005064 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5065 ProcessList.VISIBLE_APP_ADJ);
5066 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5067 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005068 }
5069
5070 // =========================================================
5071 // TASK MANAGEMENT
5072 // =========================================================
5073
5074 public List getTasks(int maxNum, int flags,
5075 IThumbnailReceiver receiver) {
5076 ArrayList list = new ArrayList();
5077
5078 PendingThumbnailsRecord pending = null;
5079 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005080 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005081
5082 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005083 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005084 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5085 + ", receiver=" + receiver);
5086
5087 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5088 != PackageManager.PERMISSION_GRANTED) {
5089 if (receiver != null) {
5090 // If the caller wants to wait for pending thumbnails,
5091 // it ain't gonna get them.
5092 try {
5093 receiver.finished();
5094 } catch (RemoteException ex) {
5095 }
5096 }
5097 String msg = "Permission Denial: getTasks() from pid="
5098 + Binder.getCallingPid()
5099 + ", uid=" + Binder.getCallingUid()
5100 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005101 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005102 throw new SecurityException(msg);
5103 }
5104
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005105 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005106 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005107 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005108 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005109 TaskRecord curTask = null;
5110 int numActivities = 0;
5111 int numRunning = 0;
5112 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005113 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005115 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005116
5117 // Initialize state for next task if needed.
5118 if (top == null ||
5119 (top.state == ActivityState.INITIALIZING
5120 && top.task == r.task)) {
5121 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005122 curTask = r.task;
5123 numActivities = numRunning = 0;
5124 }
5125
5126 // Add 'r' into the current task.
5127 numActivities++;
5128 if (r.app != null && r.app.thread != null) {
5129 numRunning++;
5130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005131
Joe Onorato8a9b2202010-02-26 18:56:32 -08005132 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133 TAG, r.intent.getComponent().flattenToShortString()
5134 + ": task=" + r.task);
5135
5136 // If the next one is a different task, generate a new
5137 // TaskInfo entry for what we have.
5138 if (next == null || next.task != curTask) {
5139 ActivityManager.RunningTaskInfo ci
5140 = new ActivityManager.RunningTaskInfo();
5141 ci.id = curTask.taskId;
5142 ci.baseActivity = r.intent.getComponent();
5143 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005144 if (top.thumbHolder != null) {
5145 ci.description = top.thumbHolder.lastDescription;
5146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005147 ci.numActivities = numActivities;
5148 ci.numRunning = numRunning;
5149 //System.out.println(
5150 // "#" + maxNum + ": " + " descr=" + ci.description);
5151 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005152 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153 TAG, "State=" + top.state + "Idle=" + top.idle
5154 + " app=" + top.app
5155 + " thr=" + (top.app != null ? top.app.thread : null));
5156 if (top.state == ActivityState.RESUMED
5157 || top.state == ActivityState.PAUSING) {
5158 if (top.idle && top.app != null
5159 && top.app.thread != null) {
5160 topRecord = top;
5161 topThumbnail = top.app.thread;
5162 } else {
5163 top.thumbnailNeeded = true;
5164 }
5165 }
5166 if (pending == null) {
5167 pending = new PendingThumbnailsRecord(receiver);
5168 }
5169 pending.pendingRecords.add(top);
5170 }
5171 list.add(ci);
5172 maxNum--;
5173 top = null;
5174 }
5175 }
5176
5177 if (pending != null) {
5178 mPendingThumbnails.add(pending);
5179 }
5180 }
5181
Joe Onorato8a9b2202010-02-26 18:56:32 -08005182 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183
5184 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005185 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005186 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005187 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005189 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005190 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005191 }
5192 }
5193
5194 if (pending == null && receiver != null) {
5195 // In this case all thumbnails were available and the client
5196 // is being asked to be told when the remaining ones come in...
5197 // which is unusually, since the top-most currently running
5198 // activity should never have a canned thumbnail! Oh well.
5199 try {
5200 receiver.finished();
5201 } catch (RemoteException ex) {
5202 }
5203 }
5204
5205 return list;
5206 }
5207
5208 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5209 int flags) {
5210 synchronized (this) {
5211 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5212 "getRecentTasks()");
5213
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005214 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005216 final int N = mRecentTasks.size();
5217 ArrayList<ActivityManager.RecentTaskInfo> res
5218 = new ArrayList<ActivityManager.RecentTaskInfo>(
5219 maxNum < N ? maxNum : N);
5220 for (int i=0; i<N && maxNum > 0; i++) {
5221 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005222 // Return the entry if desired by the caller. We always return
5223 // the first entry, because callers always expect this to be the
5224 // forground app. We may filter others if the caller has
5225 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5226 // we should exclude the entry.
5227 if (i == 0
5228 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 || (tr.intent == null)
5230 || ((tr.intent.getFlags()
5231 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5232 ActivityManager.RecentTaskInfo rti
5233 = new ActivityManager.RecentTaskInfo();
5234 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005235 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236 rti.baseIntent = new Intent(
5237 tr.intent != null ? tr.intent : tr.affinityIntent);
5238 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005239 rti.description = tr.lastDescription;
5240
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005241 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5242 // Check whether this activity is currently available.
5243 try {
5244 if (rti.origActivity != null) {
5245 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5246 continue;
5247 }
5248 } else if (rti.baseIntent != null) {
5249 if (pm.queryIntentActivities(rti.baseIntent,
5250 null, 0) == null) {
5251 continue;
5252 }
5253 }
5254 } catch (RemoteException e) {
5255 // Will never happen.
5256 }
5257 }
5258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 res.add(rti);
5260 maxNum--;
5261 }
5262 }
5263 return res;
5264 }
5265 }
5266
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005267 private TaskRecord taskForIdLocked(int id) {
5268 final int N = mRecentTasks.size();
5269 for (int i=0; i<N; i++) {
5270 TaskRecord tr = mRecentTasks.get(i);
5271 if (tr.taskId == id) {
5272 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005273 }
5274 }
5275 return null;
5276 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005277
5278 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5279 synchronized (this) {
5280 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5281 "getTaskThumbnails()");
5282 TaskRecord tr = taskForIdLocked(id);
5283 if (tr != null) {
5284 return mMainStack.getTaskThumbnailsLocked(tr);
5285 }
5286 }
5287 return null;
5288 }
5289
5290 public boolean removeSubTask(int taskId, int subTaskIndex) {
5291 synchronized (this) {
5292 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5293 "removeSubTask()");
5294 long ident = Binder.clearCallingIdentity();
5295 try {
5296 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5297 } finally {
5298 Binder.restoreCallingIdentity(ident);
5299 }
5300 }
5301 }
5302
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005303 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005304 TaskRecord tr = root.task;
5305 Intent baseIntent = new Intent(
5306 tr.intent != null ? tr.intent : tr.affinityIntent);
5307 ComponentName component = baseIntent.getComponent();
5308 if (component == null) {
5309 Slog.w(TAG, "Now component for base intent of task: " + tr);
5310 return;
5311 }
5312
5313 // Find any running services associated with this app.
5314 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5315 for (ServiceRecord sr : mServices.values()) {
5316 if (sr.packageName.equals(component.getPackageName())) {
5317 services.add(sr);
5318 }
5319 }
5320
5321 // Take care of any running services associated with the app.
5322 for (int i=0; i<services.size(); i++) {
5323 ServiceRecord sr = services.get(i);
5324 if (sr.startRequested) {
5325 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005326 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005327 stopServiceLocked(sr);
5328 } else {
5329 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5330 sr.makeNextStartId(), baseIntent, -1));
5331 if (sr.app != null && sr.app.thread != null) {
5332 sendServiceArgsLocked(sr, false);
5333 }
5334 }
5335 }
5336 }
5337
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005338 if (killProcesses) {
5339 // Find any running processes associated with this app.
5340 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5341 SparseArray<ProcessRecord> appProcs
5342 = mProcessNames.getMap().get(component.getPackageName());
5343 if (appProcs != null) {
5344 for (int i=0; i<appProcs.size(); i++) {
5345 procs.add(appProcs.valueAt(i));
5346 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005347 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005348
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005349 // Kill the running processes.
5350 for (int i=0; i<procs.size(); i++) {
5351 ProcessRecord pr = procs.get(i);
5352 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5353 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5354 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5355 pr.processName, pr.setAdj, "remove task");
5356 Process.killProcessQuiet(pr.pid);
5357 } else {
5358 pr.waitingToKill = "remove task";
5359 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005360 }
5361 }
5362 }
5363
5364 public boolean removeTask(int taskId, int flags) {
5365 synchronized (this) {
5366 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5367 "removeTask()");
5368 long ident = Binder.clearCallingIdentity();
5369 try {
5370 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5371 if (r != null) {
5372 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005373 cleanUpRemovedTaskLocked(r,
5374 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005375 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005376 } else {
5377 TaskRecord tr = null;
5378 int i=0;
5379 while (i < mRecentTasks.size()) {
5380 TaskRecord t = mRecentTasks.get(i);
5381 if (t.taskId == taskId) {
5382 tr = t;
5383 break;
5384 }
5385 i++;
5386 }
5387 if (tr != null) {
5388 if (tr.numActivities <= 0) {
5389 // Caller is just removing a recent task that is
5390 // not actively running. That is easy!
5391 mRecentTasks.remove(i);
5392 } else {
5393 Slog.w(TAG, "removeTask: task " + taskId
5394 + " does not have activities to remove, "
5395 + " but numActivities=" + tr.numActivities
5396 + ": " + tr);
5397 }
5398 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005399 }
5400 } finally {
5401 Binder.restoreCallingIdentity(ident);
5402 }
5403 }
5404 return false;
5405 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5408 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005409 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 TaskRecord jt = startTask;
5411
5412 // First look backwards
5413 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005414 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 if (r.task != jt) {
5416 jt = r.task;
5417 if (affinity.equals(jt.affinity)) {
5418 return j;
5419 }
5420 }
5421 }
5422
5423 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005424 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 jt = startTask;
5426 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005427 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 if (r.task != jt) {
5429 if (affinity.equals(jt.affinity)) {
5430 return j;
5431 }
5432 jt = r.task;
5433 }
5434 }
5435
5436 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005437 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005438 return N-1;
5439 }
5440
5441 return -1;
5442 }
5443
5444 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005445 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005447 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5449 "moveTaskToFront()");
5450
5451 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005452 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5453 Binder.getCallingUid(), "Task to front")) {
5454 return;
5455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 final long origId = Binder.clearCallingIdentity();
5457 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005458 TaskRecord tr = taskForIdLocked(task);
5459 if (tr != null) {
5460 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5461 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005463 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5464 // Caller wants the home activity moved with it. To accomplish this,
5465 // we'll just move the home task to the top first.
5466 mMainStack.moveHomeToFrontLocked();
5467 }
5468 mMainStack.moveTaskToFrontLocked(tr, null);
5469 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005471 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5472 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005474 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5475 mMainStack.mUserLeaving = true;
5476 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005477 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5478 // Caller wants the home activity moved with it. To accomplish this,
5479 // we'll just move the home task to the top first.
5480 mMainStack.moveHomeToFrontLocked();
5481 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005482 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005483 return;
5484 }
5485 }
5486 } finally {
5487 Binder.restoreCallingIdentity(origId);
5488 }
5489 }
5490 }
5491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005492 public void moveTaskToBack(int task) {
5493 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5494 "moveTaskToBack()");
5495
5496 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005497 if (mMainStack.mResumedActivity != null
5498 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005499 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5500 Binder.getCallingUid(), "Task to back")) {
5501 return;
5502 }
5503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005505 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506 Binder.restoreCallingIdentity(origId);
5507 }
5508 }
5509
5510 /**
5511 * Moves an activity, and all of the other activities within the same task, to the bottom
5512 * of the history stack. The activity's order within the task is unchanged.
5513 *
5514 * @param token A reference to the activity we wish to move
5515 * @param nonRoot If false then this only works if the activity is the root
5516 * of a task; if true it will work for any activity in a task.
5517 * @return Returns true if the move completed, false if not.
5518 */
5519 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5520 synchronized(this) {
5521 final long origId = Binder.clearCallingIdentity();
5522 int taskId = getTaskForActivityLocked(token, !nonRoot);
5523 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005524 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005525 }
5526 Binder.restoreCallingIdentity(origId);
5527 }
5528 return false;
5529 }
5530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 public void moveTaskBackwards(int task) {
5532 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5533 "moveTaskBackwards()");
5534
5535 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005536 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5537 Binder.getCallingUid(), "Task backwards")) {
5538 return;
5539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005540 final long origId = Binder.clearCallingIdentity();
5541 moveTaskBackwardsLocked(task);
5542 Binder.restoreCallingIdentity(origId);
5543 }
5544 }
5545
5546 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005547 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005548 }
5549
5550 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5551 synchronized(this) {
5552 return getTaskForActivityLocked(token, onlyRoot);
5553 }
5554 }
5555
5556 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005557 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558 TaskRecord lastTask = null;
5559 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005560 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005561 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 if (!onlyRoot || lastTask != r.task) {
5563 return r.task.taskId;
5564 }
5565 return -1;
5566 }
5567 lastTask = r.task;
5568 }
5569
5570 return -1;
5571 }
5572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 public void finishOtherInstances(IBinder token, ComponentName className) {
5574 synchronized(this) {
5575 final long origId = Binder.clearCallingIdentity();
5576
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005577 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005578 TaskRecord lastTask = null;
5579 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005580 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005582 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005583 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005584 null, "others")) {
5585 i--;
5586 N--;
5587 }
5588 }
5589 lastTask = r.task;
5590 }
5591
5592 Binder.restoreCallingIdentity(origId);
5593 }
5594 }
5595
5596 // =========================================================
5597 // THUMBNAILS
5598 // =========================================================
5599
5600 public void reportThumbnail(IBinder token,
5601 Bitmap thumbnail, CharSequence description) {
5602 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5603 final long origId = Binder.clearCallingIdentity();
5604 sendPendingThumbnail(null, token, thumbnail, description, true);
5605 Binder.restoreCallingIdentity(origId);
5606 }
5607
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005608 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005609 Bitmap thumbnail, CharSequence description, boolean always) {
5610 TaskRecord task = null;
5611 ArrayList receivers = null;
5612
5613 //System.out.println("Send pending thumbnail: " + r);
5614
5615 synchronized(this) {
5616 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005617 r = mMainStack.isInStackLocked(token);
5618 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005619 return;
5620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005621 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005622 if (thumbnail == null && r.thumbHolder != null) {
5623 thumbnail = r.thumbHolder.lastThumbnail;
5624 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005625 }
5626 if (thumbnail == null && !always) {
5627 // If there is no thumbnail, and this entry is not actually
5628 // going away, then abort for now and pick up the next
5629 // thumbnail we get.
5630 return;
5631 }
5632 task = r.task;
5633
5634 int N = mPendingThumbnails.size();
5635 int i=0;
5636 while (i<N) {
5637 PendingThumbnailsRecord pr =
5638 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5639 //System.out.println("Looking in " + pr.pendingRecords);
5640 if (pr.pendingRecords.remove(r)) {
5641 if (receivers == null) {
5642 receivers = new ArrayList();
5643 }
5644 receivers.add(pr);
5645 if (pr.pendingRecords.size() == 0) {
5646 pr.finished = true;
5647 mPendingThumbnails.remove(i);
5648 N--;
5649 continue;
5650 }
5651 }
5652 i++;
5653 }
5654 }
5655
5656 if (receivers != null) {
5657 final int N = receivers.size();
5658 for (int i=0; i<N; i++) {
5659 try {
5660 PendingThumbnailsRecord pr =
5661 (PendingThumbnailsRecord)receivers.get(i);
5662 pr.receiver.newThumbnail(
5663 task != null ? task.taskId : -1, thumbnail, description);
5664 if (pr.finished) {
5665 pr.receiver.finished();
5666 }
5667 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005668 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005669 }
5670 }
5671 }
5672 }
5673
5674 // =========================================================
5675 // CONTENT PROVIDERS
5676 // =========================================================
5677
Jeff Brown10e89712011-07-08 18:52:57 -07005678 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5679 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005680 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005681 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005682 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005683 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005684 } catch (RemoteException ex) {
5685 }
5686 if (providers != null) {
5687 final int N = providers.size();
5688 for (int i=0; i<N; i++) {
5689 ProviderInfo cpi =
5690 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005691 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5692 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005693 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005694 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005695 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 }
5697 app.pubProviders.put(cpi.name, cpr);
5698 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005699 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005700 }
5701 }
5702 return providers;
5703 }
5704
5705 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005706 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005707 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5708 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5709 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005710 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005711 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 return null;
5713 }
5714 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005715 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 == PackageManager.PERMISSION_GRANTED) {
5717 return null;
5718 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005719
5720 PathPermission[] pps = cpi.pathPermissions;
5721 if (pps != null) {
5722 int i = pps.length;
5723 while (i > 0) {
5724 i--;
5725 PathPermission pp = pps[i];
5726 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005727 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005728 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005729 return null;
5730 }
5731 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005732 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005733 == PackageManager.PERMISSION_GRANTED) {
5734 return null;
5735 }
5736 }
5737 }
5738
Dianne Hackbornb424b632010-08-18 15:59:05 -07005739 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5740 if (perms != null) {
5741 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5742 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5743 return null;
5744 }
5745 }
5746 }
5747
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005748 String msg;
5749 if (!cpi.exported) {
5750 msg = "Permission Denial: opening provider " + cpi.name
5751 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5752 + ", uid=" + callingUid + ") that is not exported from uid "
5753 + cpi.applicationInfo.uid;
5754 } else {
5755 msg = "Permission Denial: opening provider " + cpi.name
5756 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5757 + ", uid=" + callingUid + ") requires "
5758 + cpi.readPermission + " or " + cpi.writePermission;
5759 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005760 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 return msg;
5762 }
5763
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005764 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5765 if (r != null) {
5766 Integer cnt = r.conProviders.get(cpr);
5767 if (DEBUG_PROVIDER) Slog.v(TAG,
5768 "Adding provider requested by "
5769 + r.processName + " from process "
5770 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5771 + " cnt=" + (cnt == null ? 1 : cnt));
5772 if (cnt == null) {
5773 cpr.clients.add(r);
5774 r.conProviders.put(cpr, new Integer(1));
5775 return true;
5776 } else {
5777 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5778 }
5779 } else {
5780 cpr.externals++;
5781 }
5782 return false;
5783 }
5784
5785 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5786 if (r != null) {
5787 Integer cnt = r.conProviders.get(cpr);
5788 if (DEBUG_PROVIDER) Slog.v(TAG,
5789 "Removing provider requested by "
5790 + r.processName + " from process "
5791 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5792 + " cnt=" + cnt);
5793 if (cnt == null || cnt.intValue() <= 1) {
5794 cpr.clients.remove(r);
5795 r.conProviders.remove(cpr);
5796 return true;
5797 } else {
5798 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5799 }
5800 } else {
5801 cpr.externals++;
5802 }
5803 return false;
5804 }
5805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 private final ContentProviderHolder getContentProviderImpl(
5807 IApplicationThread caller, String name) {
5808 ContentProviderRecord cpr;
5809 ProviderInfo cpi = null;
5810
5811 synchronized(this) {
5812 ProcessRecord r = null;
5813 if (caller != null) {
5814 r = getRecordForAppLocked(caller);
5815 if (r == null) {
5816 throw new SecurityException(
5817 "Unable to find app for caller " + caller
5818 + " (pid=" + Binder.getCallingPid()
5819 + ") when getting content provider " + name);
5820 }
5821 }
5822
5823 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005824 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005825 boolean providerRunning = cpr != null;
5826 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005828 String msg;
5829 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5830 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 }
5832
5833 if (r != null && cpr.canRunHere(r)) {
5834 // This provider has been published or is in the process
5835 // of being published... but it is also allowed to run
5836 // in the caller's process, so don't make a connection
5837 // and just let the caller instantiate its own instance.
5838 if (cpr.provider != null) {
5839 // don't give caller the provider object, it needs
5840 // to make its own.
5841 cpr = new ContentProviderRecord(cpr);
5842 }
5843 return cpr;
5844 }
5845
5846 final long origId = Binder.clearCallingIdentity();
5847
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005848 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005849 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005850 final boolean countChanged = incProviderCount(r, cpr);
5851 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005852 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005853 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005854 // make sure to count it as being accessed and thus
5855 // back up on the LRU list. This is good because
5856 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005857 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005858 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005859 }
5860
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005861 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005862 if (false) {
5863 if (cpr.name.flattenToShortString().equals(
5864 "com.android.providers.calendar/.CalendarProvider2")) {
5865 Slog.v(TAG, "****************** KILLING "
5866 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005867 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005868 }
5869 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005870 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005871 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5872 // NOTE: there is still a race here where a signal could be
5873 // pending on the process even though we managed to update its
5874 // adj level. Not sure what to do about this, but at least
5875 // the race is now smaller.
5876 if (!success) {
5877 // Uh oh... it looks like the provider's process
5878 // has been killed on us. We need to wait for a new
5879 // process to be started, and make sure its death
5880 // doesn't kill our process.
5881 Slog.i(TAG,
5882 "Existing provider " + cpr.name.flattenToShortString()
5883 + " is crashing; detaching " + r);
5884 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005885 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005886 if (!lastRef) {
5887 // This wasn't the last ref our process had on
5888 // the provider... we have now been killed, bail.
5889 return null;
5890 }
5891 providerRunning = false;
5892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005893 }
5894
5895 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005898 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005899 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005900 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005901 resolveContentProvider(name,
5902 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 } catch (RemoteException ex) {
5904 }
5905 if (cpi == null) {
5906 return null;
5907 }
5908
Dianne Hackbornb424b632010-08-18 15:59:05 -07005909 String msg;
5910 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5911 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 }
5913
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005914 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005915 && !cpi.processName.equals("system")) {
5916 // If this content provider does not run in the system
5917 // process, and the system is not yet ready to run other
5918 // processes, then fail fast instead of hanging.
5919 throw new IllegalArgumentException(
5920 "Attempt to launch content provider before system ready");
5921 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005922
5923 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5924 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005925 final boolean firstClass = cpr == null;
5926 if (firstClass) {
5927 try {
5928 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005929 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005930 getApplicationInfo(
5931 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005932 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005934 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005935 + cpi.name);
5936 return null;
5937 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005938 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 } catch (RemoteException ex) {
5940 // pm is in same process, this will never happen.
5941 }
5942 }
5943
5944 if (r != null && cpr.canRunHere(r)) {
5945 // If this is a multiprocess provider, then just return its
5946 // info and allow the caller to instantiate it. Only do
5947 // this if the provider is the same user as the caller's
5948 // process, or can run as root (so can be in any process).
5949 return cpr;
5950 }
5951
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005952 if (DEBUG_PROVIDER) {
5953 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005954 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005955 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005956 }
5957
5958 // This is single process, and our app is now connecting to it.
5959 // See if we are already in the process of launching this
5960 // provider.
5961 final int N = mLaunchingProviders.size();
5962 int i;
5963 for (i=0; i<N; i++) {
5964 if (mLaunchingProviders.get(i) == cpr) {
5965 break;
5966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005967 }
5968
5969 // If the provider is not already being launched, then get it
5970 // started.
5971 if (i >= N) {
5972 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005973
5974 try {
5975 // Content provider is now in use, its package can't be stopped.
5976 try {
5977 AppGlobals.getPackageManager().setPackageStoppedState(
5978 cpr.appInfo.packageName, false);
5979 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005980 } catch (IllegalArgumentException e) {
5981 Slog.w(TAG, "Failed trying to unstop package "
5982 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005983 }
5984
5985 ProcessRecord proc = startProcessLocked(cpi.processName,
5986 cpr.appInfo, false, 0, "content provider",
5987 new ComponentName(cpi.applicationInfo.packageName,
5988 cpi.name), false);
5989 if (proc == null) {
5990 Slog.w(TAG, "Unable to launch app "
5991 + cpi.applicationInfo.packageName + "/"
5992 + cpi.applicationInfo.uid + " for provider "
5993 + name + ": process is bad");
5994 return null;
5995 }
5996 cpr.launchingApp = proc;
5997 mLaunchingProviders.add(cpr);
5998 } finally {
5999 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006001 }
6002
6003 // Make sure the provider is published (the same provider class
6004 // may be published under multiple names).
6005 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006006 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006007 }
6008 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006009 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006010 }
6011 }
6012
6013 // Wait for the provider to be published...
6014 synchronized (cpr) {
6015 while (cpr.provider == null) {
6016 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006017 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006018 + cpi.applicationInfo.packageName + "/"
6019 + cpi.applicationInfo.uid + " for provider "
6020 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006021 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006022 cpi.applicationInfo.packageName,
6023 cpi.applicationInfo.uid, name);
6024 return null;
6025 }
6026 try {
6027 cpr.wait();
6028 } catch (InterruptedException ex) {
6029 }
6030 }
6031 }
6032 return cpr;
6033 }
6034
6035 public final ContentProviderHolder getContentProvider(
6036 IApplicationThread caller, String name) {
6037 if (caller == null) {
6038 String msg = "null IApplicationThread when getting content provider "
6039 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006040 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 throw new SecurityException(msg);
6042 }
6043
6044 return getContentProviderImpl(caller, name);
6045 }
6046
6047 private ContentProviderHolder getContentProviderExternal(String name) {
6048 return getContentProviderImpl(null, name);
6049 }
6050
6051 /**
6052 * Drop a content provider from a ProcessRecord's bookkeeping
6053 * @param cpr
6054 */
6055 public void removeContentProvider(IApplicationThread caller, String name) {
6056 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006057 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006059 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006060 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006061 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006062 return;
6063 }
6064 final ProcessRecord r = getRecordForAppLocked(caller);
6065 if (r == null) {
6066 throw new SecurityException(
6067 "Unable to find app for caller " + caller +
6068 " when removing content provider " + name);
6069 }
6070 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006071 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6072 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006073 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006075 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006076 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006077 return;
6078 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006079 if (decProviderCount(r, localCpr)) {
6080 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 }
6084 }
6085
6086 private void removeContentProviderExternal(String name) {
6087 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006088 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 if(cpr == null) {
6090 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006091 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 return;
6093 }
6094
6095 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006096 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6097 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 localCpr.externals--;
6099 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006100 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 }
6102 updateOomAdjLocked();
6103 }
6104 }
6105
6106 public final void publishContentProviders(IApplicationThread caller,
6107 List<ContentProviderHolder> providers) {
6108 if (providers == null) {
6109 return;
6110 }
6111
6112 synchronized(this) {
6113 final ProcessRecord r = getRecordForAppLocked(caller);
6114 if (r == null) {
6115 throw new SecurityException(
6116 "Unable to find app for caller " + caller
6117 + " (pid=" + Binder.getCallingPid()
6118 + ") when publishing content providers");
6119 }
6120
6121 final long origId = Binder.clearCallingIdentity();
6122
6123 final int N = providers.size();
6124 for (int i=0; i<N; i++) {
6125 ContentProviderHolder src = providers.get(i);
6126 if (src == null || src.info == null || src.provider == null) {
6127 continue;
6128 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006129 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006130 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006131 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6132 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 String names[] = dst.info.authority.split(";");
6134 for (int j = 0; j < names.length; j++) {
6135 mProvidersByName.put(names[j], dst);
6136 }
6137
6138 int NL = mLaunchingProviders.size();
6139 int j;
6140 for (j=0; j<NL; j++) {
6141 if (mLaunchingProviders.get(j) == dst) {
6142 mLaunchingProviders.remove(j);
6143 j--;
6144 NL--;
6145 }
6146 }
6147 synchronized (dst) {
6148 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006149 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 dst.notifyAll();
6151 }
6152 updateOomAdjLocked(r);
6153 }
6154 }
6155
6156 Binder.restoreCallingIdentity(origId);
6157 }
6158 }
6159
6160 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006161 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006162 synchronized (mSelf) {
6163 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6164 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006165 if (providers != null) {
6166 for (int i=providers.size()-1; i>=0; i--) {
6167 ProviderInfo pi = (ProviderInfo)providers.get(i);
6168 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6169 Slog.w(TAG, "Not installing system proc provider " + pi.name
6170 + ": not system .apk");
6171 providers.remove(i);
6172 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006173 }
6174 }
6175 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006176 if (providers != null) {
6177 mSystemThread.installSystemProviders(providers);
6178 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006179
6180 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006181
6182 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 }
6184
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006185 /**
6186 * Allows app to retrieve the MIME type of a URI without having permission
6187 * to access its content provider.
6188 *
6189 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6190 *
6191 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6192 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6193 */
6194 public String getProviderMimeType(Uri uri) {
6195 final String name = uri.getAuthority();
6196 final long ident = Binder.clearCallingIdentity();
6197 ContentProviderHolder holder = null;
6198
6199 try {
6200 holder = getContentProviderExternal(name);
6201 if (holder != null) {
6202 return holder.provider.getType(uri);
6203 }
6204 } catch (RemoteException e) {
6205 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6206 return null;
6207 } finally {
6208 if (holder != null) {
6209 removeContentProviderExternal(name);
6210 }
6211 Binder.restoreCallingIdentity(ident);
6212 }
6213
6214 return null;
6215 }
6216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006217 // =========================================================
6218 // GLOBAL MANAGEMENT
6219 // =========================================================
6220
6221 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6222 ApplicationInfo info, String customProcess) {
6223 String proc = customProcess != null ? customProcess : info.processName;
6224 BatteryStatsImpl.Uid.Proc ps = null;
6225 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6226 synchronized (stats) {
6227 ps = stats.getProcessStatsLocked(info.uid, proc);
6228 }
6229 return new ProcessRecord(ps, thread, info, proc);
6230 }
6231
6232 final ProcessRecord addAppLocked(ApplicationInfo info) {
6233 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6234
6235 if (app == null) {
6236 app = newProcessRecordLocked(null, info, null);
6237 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006238 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006239 }
6240
Dianne Hackborne7f97212011-02-24 14:40:20 -08006241 // This package really, really can not be stopped.
6242 try {
6243 AppGlobals.getPackageManager().setPackageStoppedState(
6244 info.packageName, false);
6245 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006246 } catch (IllegalArgumentException e) {
6247 Slog.w(TAG, "Failed trying to unstop package "
6248 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006249 }
6250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006251 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6252 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6253 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006254 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 }
6256 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6257 mPersistentStartingProcesses.add(app);
6258 startProcessLocked(app, "added application", app.processName);
6259 }
6260
6261 return app;
6262 }
6263
6264 public void unhandledBack() {
6265 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6266 "unhandledBack()");
6267
6268 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006269 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006270 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006271 TAG, "Performing unhandledBack(): stack size = " + count);
6272 if (count > 1) {
6273 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006274 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6276 Binder.restoreCallingIdentity(origId);
6277 }
6278 }
6279 }
6280
6281 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6282 String name = uri.getAuthority();
6283 ContentProviderHolder cph = getContentProviderExternal(name);
6284 ParcelFileDescriptor pfd = null;
6285 if (cph != null) {
6286 // We record the binder invoker's uid in thread-local storage before
6287 // going to the content provider to open the file. Later, in the code
6288 // that handles all permissions checks, we look for this uid and use
6289 // that rather than the Activity Manager's own uid. The effect is that
6290 // we do the check against the caller's permissions even though it looks
6291 // to the content provider like the Activity Manager itself is making
6292 // the request.
6293 sCallerIdentity.set(new Identity(
6294 Binder.getCallingPid(), Binder.getCallingUid()));
6295 try {
6296 pfd = cph.provider.openFile(uri, "r");
6297 } catch (FileNotFoundException e) {
6298 // do nothing; pfd will be returned null
6299 } finally {
6300 // Ensure that whatever happens, we clean up the identity state
6301 sCallerIdentity.remove();
6302 }
6303
6304 // We've got the fd now, so we're done with the provider.
6305 removeContentProviderExternal(name);
6306 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006307 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 }
6309 return pfd;
6310 }
6311
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006312 // Actually is sleeping or shutting down or whatever else in the future
6313 // is an inactive state.
6314 public boolean isSleeping() {
6315 return mSleeping || mShuttingDown;
6316 }
6317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006318 public void goingToSleep() {
6319 synchronized(this) {
6320 mSleeping = true;
6321 mWindowManager.setEventDispatching(false);
6322
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006323 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006324
6325 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006326 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006327 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6328 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006329 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006330 }
6331 }
6332
Dianne Hackborn55280a92009-05-07 15:53:46 -07006333 public boolean shutdown(int timeout) {
6334 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6335 != PackageManager.PERMISSION_GRANTED) {
6336 throw new SecurityException("Requires permission "
6337 + android.Manifest.permission.SHUTDOWN);
6338 }
6339
6340 boolean timedout = false;
6341
6342 synchronized(this) {
6343 mShuttingDown = true;
6344 mWindowManager.setEventDispatching(false);
6345
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006346 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006347 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006348 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006349 while (mMainStack.mResumedActivity != null
6350 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006351 long delay = endTime - System.currentTimeMillis();
6352 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006353 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006354 timedout = true;
6355 break;
6356 }
6357 try {
6358 this.wait();
6359 } catch (InterruptedException e) {
6360 }
6361 }
6362 }
6363 }
6364
6365 mUsageStatsService.shutdown();
6366 mBatteryStatsService.shutdown();
6367
6368 return timedout;
6369 }
6370
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006371 public final void activitySlept(IBinder token) {
6372 if (localLOGV) Slog.v(
6373 TAG, "Activity slept: token=" + token);
6374
6375 ActivityRecord r = null;
6376
6377 final long origId = Binder.clearCallingIdentity();
6378
6379 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006380 r = mMainStack.isInStackLocked(token);
6381 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006382 mMainStack.activitySleptLocked(r);
6383 }
6384 }
6385
6386 Binder.restoreCallingIdentity(origId);
6387 }
6388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 public void wakingUp() {
6390 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006391 mWindowManager.setEventDispatching(true);
6392 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006393 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006394 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 }
6396 }
6397
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006398 public void stopAppSwitches() {
6399 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6400 != PackageManager.PERMISSION_GRANTED) {
6401 throw new SecurityException("Requires permission "
6402 + android.Manifest.permission.STOP_APP_SWITCHES);
6403 }
6404
6405 synchronized(this) {
6406 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6407 + APP_SWITCH_DELAY_TIME;
6408 mDidAppSwitch = false;
6409 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6410 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6411 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6412 }
6413 }
6414
6415 public void resumeAppSwitches() {
6416 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6417 != PackageManager.PERMISSION_GRANTED) {
6418 throw new SecurityException("Requires permission "
6419 + android.Manifest.permission.STOP_APP_SWITCHES);
6420 }
6421
6422 synchronized(this) {
6423 // Note that we don't execute any pending app switches... we will
6424 // let those wait until either the timeout, or the next start
6425 // activity request.
6426 mAppSwitchesAllowedTime = 0;
6427 }
6428 }
6429
6430 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6431 String name) {
6432 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6433 return true;
6434 }
6435
6436 final int perm = checkComponentPermission(
6437 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006438 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006439 if (perm == PackageManager.PERMISSION_GRANTED) {
6440 return true;
6441 }
6442
Joe Onorato8a9b2202010-02-26 18:56:32 -08006443 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006444 return false;
6445 }
6446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 public void setDebugApp(String packageName, boolean waitForDebugger,
6448 boolean persistent) {
6449 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6450 "setDebugApp()");
6451
6452 // Note that this is not really thread safe if there are multiple
6453 // callers into it at the same time, but that's not a situation we
6454 // care about.
6455 if (persistent) {
6456 final ContentResolver resolver = mContext.getContentResolver();
6457 Settings.System.putString(
6458 resolver, Settings.System.DEBUG_APP,
6459 packageName);
6460 Settings.System.putInt(
6461 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6462 waitForDebugger ? 1 : 0);
6463 }
6464
6465 synchronized (this) {
6466 if (!persistent) {
6467 mOrigDebugApp = mDebugApp;
6468 mOrigWaitForDebugger = mWaitForDebugger;
6469 }
6470 mDebugApp = packageName;
6471 mWaitForDebugger = waitForDebugger;
6472 mDebugTransient = !persistent;
6473 if (packageName != null) {
6474 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006475 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006476 Binder.restoreCallingIdentity(origId);
6477 }
6478 }
6479 }
6480
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006481 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6482 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6483 synchronized (this) {
6484 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6485 if (!isDebuggable) {
6486 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6487 throw new SecurityException("Process not debuggable: " + app.packageName);
6488 }
6489 }
6490 mProfileApp = processName;
6491 mProfileFile = profileFile;
6492 if (mProfileFd != null) {
6493 try {
6494 mProfileFd.close();
6495 } catch (IOException e) {
6496 }
6497 mProfileFd = null;
6498 }
6499 mProfileFd = profileFd;
6500 mProfileType = 0;
6501 mAutoStopProfiler = autoStopProfiler;
6502 }
6503 }
6504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006505 public void setAlwaysFinish(boolean enabled) {
6506 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6507 "setAlwaysFinish()");
6508
6509 Settings.System.putInt(
6510 mContext.getContentResolver(),
6511 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6512
6513 synchronized (this) {
6514 mAlwaysFinishActivities = enabled;
6515 }
6516 }
6517
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006518 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006519 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006520 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006521 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006522 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006523 }
6524 }
6525
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006526 public boolean isUserAMonkey() {
6527 // For now the fact that there is a controller implies
6528 // we have a monkey.
6529 synchronized (this) {
6530 return mController != null;
6531 }
6532 }
6533
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006534 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006535 synchronized (this) {
6536 mWatchers.register(watcher);
6537 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006538 }
6539
6540 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006541 synchronized (this) {
6542 mWatchers.unregister(watcher);
6543 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006544 }
6545
Jeff Sharkeya4620792011-05-20 15:29:23 -07006546 public void registerProcessObserver(IProcessObserver observer) {
6547 mProcessObservers.register(observer);
6548 }
6549
6550 public void unregisterProcessObserver(IProcessObserver observer) {
6551 mProcessObservers.unregister(observer);
6552 }
6553
Daniel Sandler69a48172010-06-23 16:29:36 -04006554 public void setImmersive(IBinder token, boolean immersive) {
6555 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006556 ActivityRecord r = mMainStack.isInStackLocked(token);
6557 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006558 throw new IllegalArgumentException();
6559 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006560 r.immersive = immersive;
6561 }
6562 }
6563
6564 public boolean isImmersive(IBinder token) {
6565 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006566 ActivityRecord r = mMainStack.isInStackLocked(token);
6567 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006568 throw new IllegalArgumentException();
6569 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006570 return r.immersive;
6571 }
6572 }
6573
6574 public boolean isTopActivityImmersive() {
6575 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006576 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006577 return (r != null) ? r.immersive : false;
6578 }
6579 }
6580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006581 public final void enterSafeMode() {
6582 synchronized(this) {
6583 // It only makes sense to do this before the system is ready
6584 // and started launching other packages.
6585 if (!mSystemReady) {
6586 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006587 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006588 } catch (RemoteException e) {
6589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006590 }
6591 }
6592 }
6593
Jeff Brownb09abc12011-01-13 21:08:27 -08006594 public final void showSafeModeOverlay() {
6595 View v = LayoutInflater.from(mContext).inflate(
6596 com.android.internal.R.layout.safe_mode, null);
6597 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6598 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6599 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6600 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6601 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6602 lp.format = v.getBackground().getOpacity();
6603 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6604 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6605 ((WindowManager)mContext.getSystemService(
6606 Context.WINDOW_SERVICE)).addView(v, lp);
6607 }
6608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609 public void noteWakeupAlarm(IIntentSender sender) {
6610 if (!(sender instanceof PendingIntentRecord)) {
6611 return;
6612 }
6613 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6614 synchronized (stats) {
6615 if (mBatteryStatsService.isOnBattery()) {
6616 mBatteryStatsService.enforceCallingPermission();
6617 PendingIntentRecord rec = (PendingIntentRecord)sender;
6618 int MY_UID = Binder.getCallingUid();
6619 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6620 BatteryStatsImpl.Uid.Pkg pkg =
6621 stats.getPackageStatsLocked(uid, rec.key.packageName);
6622 pkg.incWakeupsLocked();
6623 }
6624 }
6625 }
6626
Dianne Hackborn64825172011-03-02 21:32:58 -08006627 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006629 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006631 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006632 // XXX Note: don't acquire main activity lock here, because the window
6633 // manager calls in with its locks held.
6634
6635 boolean killed = false;
6636 synchronized (mPidsSelfLocked) {
6637 int[] types = new int[pids.length];
6638 int worstType = 0;
6639 for (int i=0; i<pids.length; i++) {
6640 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6641 if (proc != null) {
6642 int type = proc.setAdj;
6643 types[i] = type;
6644 if (type > worstType) {
6645 worstType = type;
6646 }
6647 }
6648 }
6649
Dianne Hackborn64825172011-03-02 21:32:58 -08006650 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006652 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6653 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006654 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006655 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006656
6657 // If this is not a secure call, don't let it kill processes that
6658 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006659 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6660 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006661 }
6662
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006663 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664 for (int i=0; i<pids.length; i++) {
6665 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6666 if (proc == null) {
6667 continue;
6668 }
6669 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006670 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006671 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006672 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6673 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006674 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006675 proc.killedBackground = true;
6676 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006677 }
6678 }
6679 }
6680 return killed;
6681 }
6682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006683 public final void startRunning(String pkg, String cls, String action,
6684 String data) {
6685 synchronized(this) {
6686 if (mStartRunning) {
6687 return;
6688 }
6689 mStartRunning = true;
6690 mTopComponent = pkg != null && cls != null
6691 ? new ComponentName(pkg, cls) : null;
6692 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6693 mTopData = data;
6694 if (!mSystemReady) {
6695 return;
6696 }
6697 }
6698
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006699 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 }
6701
6702 private void retrieveSettings() {
6703 final ContentResolver resolver = mContext.getContentResolver();
6704 String debugApp = Settings.System.getString(
6705 resolver, Settings.System.DEBUG_APP);
6706 boolean waitForDebugger = Settings.System.getInt(
6707 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6708 boolean alwaysFinishActivities = Settings.System.getInt(
6709 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6710
6711 Configuration configuration = new Configuration();
6712 Settings.System.getConfiguration(resolver, configuration);
6713
6714 synchronized (this) {
6715 mDebugApp = mOrigDebugApp = debugApp;
6716 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6717 mAlwaysFinishActivities = alwaysFinishActivities;
6718 // This happens before any activities are started, so we can
6719 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006720 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006721 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006722 }
6723 }
6724
6725 public boolean testIsSystemReady() {
6726 // no need to synchronize(this) just to read & return the value
6727 return mSystemReady;
6728 }
6729
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006730 private static File getCalledPreBootReceiversFile() {
6731 File dataDir = Environment.getDataDirectory();
6732 File systemDir = new File(dataDir, "system");
6733 File fname = new File(systemDir, "called_pre_boots.dat");
6734 return fname;
6735 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006736
6737 static final int LAST_DONE_VERSION = 10000;
6738
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006739 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6740 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6741 File file = getCalledPreBootReceiversFile();
6742 FileInputStream fis = null;
6743 try {
6744 fis = new FileInputStream(file);
6745 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006746 int fvers = dis.readInt();
6747 if (fvers == LAST_DONE_VERSION) {
6748 String vers = dis.readUTF();
6749 String codename = dis.readUTF();
6750 String build = dis.readUTF();
6751 if (android.os.Build.VERSION.RELEASE.equals(vers)
6752 && android.os.Build.VERSION.CODENAME.equals(codename)
6753 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6754 int num = dis.readInt();
6755 while (num > 0) {
6756 num--;
6757 String pkg = dis.readUTF();
6758 String cls = dis.readUTF();
6759 lastDoneReceivers.add(new ComponentName(pkg, cls));
6760 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006761 }
6762 }
6763 } catch (FileNotFoundException e) {
6764 } catch (IOException e) {
6765 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6766 } finally {
6767 if (fis != null) {
6768 try {
6769 fis.close();
6770 } catch (IOException e) {
6771 }
6772 }
6773 }
6774 return lastDoneReceivers;
6775 }
6776
6777 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6778 File file = getCalledPreBootReceiversFile();
6779 FileOutputStream fos = null;
6780 DataOutputStream dos = null;
6781 try {
6782 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6783 fos = new FileOutputStream(file);
6784 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006785 dos.writeInt(LAST_DONE_VERSION);
6786 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006787 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006788 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006789 dos.writeInt(list.size());
6790 for (int i=0; i<list.size(); i++) {
6791 dos.writeUTF(list.get(i).getPackageName());
6792 dos.writeUTF(list.get(i).getClassName());
6793 }
6794 } catch (IOException e) {
6795 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6796 file.delete();
6797 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006798 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006799 if (dos != null) {
6800 try {
6801 dos.close();
6802 } catch (IOException e) {
6803 // TODO Auto-generated catch block
6804 e.printStackTrace();
6805 }
6806 }
6807 }
6808 }
6809
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006810 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 synchronized(this) {
6812 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006813 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 return;
6815 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006816
6817 // Check to see if there are any update receivers to run.
6818 if (!mDidUpdate) {
6819 if (mWaitingUpdate) {
6820 return;
6821 }
6822 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6823 List<ResolveInfo> ris = null;
6824 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006825 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006826 intent, null, 0);
6827 } catch (RemoteException e) {
6828 }
6829 if (ris != null) {
6830 for (int i=ris.size()-1; i>=0; i--) {
6831 if ((ris.get(i).activityInfo.applicationInfo.flags
6832 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6833 ris.remove(i);
6834 }
6835 }
6836 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006837
6838 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6839
6840 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006841 for (int i=0; i<ris.size(); i++) {
6842 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006843 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6844 if (lastDoneReceivers.contains(comp)) {
6845 ris.remove(i);
6846 i--;
6847 }
6848 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006849
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006850 for (int i=0; i<ris.size(); i++) {
6851 ActivityInfo ai = ris.get(i).activityInfo;
6852 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6853 doneReceivers.add(comp);
6854 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006855 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006856 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006857 finisher = new IIntentReceiver.Stub() {
6858 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006859 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006860 boolean sticky) {
6861 // The raw IIntentReceiver interface is called
6862 // with the AM lock held, so redispatch to
6863 // execute our code without the lock.
6864 mHandler.post(new Runnable() {
6865 public void run() {
6866 synchronized (ActivityManagerService.this) {
6867 mDidUpdate = true;
6868 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006869 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006870 showBootMessage(mContext.getText(
6871 R.string.android_upgrading_complete),
6872 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006873 systemReady(goingCallback);
6874 }
6875 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006876 }
6877 };
6878 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006879 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006880 broadcastIntentLocked(null, null, intent, null, finisher,
6881 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006882 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006883 mWaitingUpdate = true;
6884 }
6885 }
6886 }
6887 if (mWaitingUpdate) {
6888 return;
6889 }
6890 mDidUpdate = true;
6891 }
6892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006893 mSystemReady = true;
6894 if (!mStartRunning) {
6895 return;
6896 }
6897 }
6898
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006899 ArrayList<ProcessRecord> procsToKill = null;
6900 synchronized(mPidsSelfLocked) {
6901 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6902 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6903 if (!isAllowedWhileBooting(proc.info)){
6904 if (procsToKill == null) {
6905 procsToKill = new ArrayList<ProcessRecord>();
6906 }
6907 procsToKill.add(proc);
6908 }
6909 }
6910 }
6911
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006912 synchronized(this) {
6913 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006914 for (int i=procsToKill.size()-1; i>=0; i--) {
6915 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006916 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006917 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006918 }
6919 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006920
6921 // Now that we have cleaned up any update processes, we
6922 // are ready to start launching real processes and know that
6923 // we won't trample on them any more.
6924 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006925 }
6926
Joe Onorato8a9b2202010-02-26 18:56:32 -08006927 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006928 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 SystemClock.uptimeMillis());
6930
6931 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006932 // Make sure we have no pre-ready processes sitting around.
6933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006934 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6935 ResolveInfo ri = mContext.getPackageManager()
6936 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006937 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006938 CharSequence errorMsg = null;
6939 if (ri != null) {
6940 ActivityInfo ai = ri.activityInfo;
6941 ApplicationInfo app = ai.applicationInfo;
6942 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6943 mTopAction = Intent.ACTION_FACTORY_TEST;
6944 mTopData = null;
6945 mTopComponent = new ComponentName(app.packageName,
6946 ai.name);
6947 } else {
6948 errorMsg = mContext.getResources().getText(
6949 com.android.internal.R.string.factorytest_not_system);
6950 }
6951 } else {
6952 errorMsg = mContext.getResources().getText(
6953 com.android.internal.R.string.factorytest_no_action);
6954 }
6955 if (errorMsg != null) {
6956 mTopAction = null;
6957 mTopData = null;
6958 mTopComponent = null;
6959 Message msg = Message.obtain();
6960 msg.what = SHOW_FACTORY_ERROR_MSG;
6961 msg.getData().putCharSequence("msg", errorMsg);
6962 mHandler.sendMessage(msg);
6963 }
6964 }
6965 }
6966
6967 retrieveSettings();
6968
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006969 if (goingCallback != null) goingCallback.run();
6970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006971 synchronized (this) {
6972 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6973 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006974 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006975 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006976 if (apps != null) {
6977 int N = apps.size();
6978 int i;
6979 for (i=0; i<N; i++) {
6980 ApplicationInfo info
6981 = (ApplicationInfo)apps.get(i);
6982 if (info != null &&
6983 !info.packageName.equals("android")) {
6984 addAppLocked(info);
6985 }
6986 }
6987 }
6988 } catch (RemoteException ex) {
6989 // pm is in same process, this will never happen.
6990 }
6991 }
6992
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006993 // Start up initial activity.
6994 mBooting = true;
6995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006996 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006997 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006998 Message msg = Message.obtain();
6999 msg.what = SHOW_UID_ERROR_MSG;
7000 mHandler.sendMessage(msg);
7001 }
7002 } catch (RemoteException e) {
7003 }
7004
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007005 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007006 }
7007 }
7008
Dan Egnorb7f03672009-12-09 16:22:32 -08007009 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007010 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007011 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007012 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007013 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007014 startAppProblemLocked(app);
7015 app.stopFreezingAllLocked();
7016 return handleAppCrashLocked(app);
7017 }
7018
Dan Egnorb7f03672009-12-09 16:22:32 -08007019 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007020 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007021 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007022 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007023 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7024 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 startAppProblemLocked(app);
7026 app.stopFreezingAllLocked();
7027 }
7028
7029 /**
7030 * Generate a process error record, suitable for attachment to a ProcessRecord.
7031 *
7032 * @param app The ProcessRecord in which the error occurred.
7033 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7034 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007035 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007036 * @param shortMsg Short message describing the crash.
7037 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007038 * @param stackTrace Full crash stack trace, may be null.
7039 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 * @return Returns a fully-formed AppErrorStateInfo record.
7041 */
7042 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007043 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007044 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007046 report.condition = condition;
7047 report.processName = app.processName;
7048 report.pid = app.pid;
7049 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007050 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007051 report.shortMsg = shortMsg;
7052 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007053 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007054
7055 return report;
7056 }
7057
Dan Egnor42471dd2010-01-07 17:25:22 -08007058 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059 synchronized (this) {
7060 app.crashing = false;
7061 app.crashingReport = null;
7062 app.notResponding = false;
7063 app.notRespondingReport = null;
7064 if (app.anrDialog == fromDialog) {
7065 app.anrDialog = null;
7066 }
7067 if (app.waitDialog == fromDialog) {
7068 app.waitDialog = null;
7069 }
7070 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007071 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007072 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007073 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7074 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007075 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007077 }
7078 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007079
Dan Egnorb7f03672009-12-09 16:22:32 -08007080 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 long now = SystemClock.uptimeMillis();
7082
7083 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7084 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007085 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007086 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007087 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007089 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007090 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007091 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7092 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007094 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007095 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007096 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007097 }
7098 }
7099 if (!app.persistent) {
7100 // We don't want to start this process again until the user
7101 // explicitly does so... but for persistent process, we really
7102 // need to keep it running. If a persistent process is actually
7103 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007104 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007105 app.info.processName);
7106 mBadProcesses.put(app.info.processName, app.info.uid, now);
7107 app.bad = true;
7108 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7109 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007110 // Don't let services in this process be restarted and potentially
7111 // annoy the user repeatedly. Unless it is persistent, since those
7112 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007113 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007114 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007115 return false;
7116 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007117 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007118 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007119 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007120 if (r.app == app) {
7121 // If the top running activity is from this crashing
7122 // process, then terminate it to avoid getting in a loop.
7123 Slog.w(TAG, " Force finishing activity "
7124 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007125 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007126 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007127 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007128 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007129 // stopped, to avoid a situation where one will get
7130 // re-start our crashing activity once it gets resumed again.
7131 index--;
7132 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007133 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007134 if (r.state == ActivityState.RESUMED
7135 || r.state == ActivityState.PAUSING
7136 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007137 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007138 Slog.w(TAG, " Force finishing activity "
7139 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007140 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007141 Activity.RESULT_CANCELED, null, "crashed");
7142 }
7143 }
7144 }
7145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007146 }
7147
7148 // Bump up the crash count of any services currently running in the proc.
7149 if (app.services.size() != 0) {
7150 // Any services running in the application need to be placed
7151 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007152 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007153 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007154 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007155 sr.crashCount++;
7156 }
7157 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007158
7159 // If the crashing process is what we consider to be the "home process" and it has been
7160 // replaced by a third-party app, clear the package preferred activities from packages
7161 // with a home activity running in the process to prevent a repeatedly crashing app
7162 // from blocking the user to manually clear the list.
7163 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7164 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7165 Iterator it = mHomeProcess.activities.iterator();
7166 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007167 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007168 if (r.isHomeActivity) {
7169 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7170 try {
7171 ActivityThread.getPackageManager()
7172 .clearPackagePreferredActivities(r.packageName);
7173 } catch (RemoteException c) {
7174 // pm is in same process, this will never happen.
7175 }
7176 }
7177 }
7178 }
7179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007180 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7181 return true;
7182 }
7183
7184 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007185 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7186 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 skipCurrentReceiverLocked(app);
7188 }
7189
7190 void skipCurrentReceiverLocked(ProcessRecord app) {
7191 boolean reschedule = false;
7192 BroadcastRecord r = app.curReceiver;
7193 if (r != null) {
7194 // The current broadcast is waiting for this app's receiver
7195 // to be finished. Looks like that's not going to happen, so
7196 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007197 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7199 r.resultExtras, r.resultAbort, true);
7200 reschedule = true;
7201 }
7202 r = mPendingBroadcast;
7203 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007204 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007206 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007207 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7208 r.resultExtras, r.resultAbort, true);
7209 reschedule = true;
7210 }
7211 if (reschedule) {
7212 scheduleBroadcastsLocked();
7213 }
7214 }
7215
Dan Egnor60d87622009-12-16 16:32:58 -08007216 /**
7217 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7218 * The application process will exit immediately after this call returns.
7219 * @param app object of the crashing app, null for the system server
7220 * @param crashInfo describing the exception
7221 */
7222 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007223 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007224 final String processName = app == null ? "system_server"
7225 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007226
7227 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007228 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007229 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007230 crashInfo.exceptionClassName,
7231 crashInfo.exceptionMessage,
7232 crashInfo.throwFileName,
7233 crashInfo.throwLineNumber);
7234
Jeff Sharkeya353d262011-10-28 11:12:06 -07007235 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007236
7237 crashApplication(r, crashInfo);
7238 }
7239
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007240 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007241 IBinder app,
7242 int violationMask,
7243 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007244 ProcessRecord r = findAppProcess(app, "StrictMode");
7245 if (r == null) {
7246 return;
7247 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007248
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007249 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007250 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007251 boolean logIt = true;
7252 synchronized (mAlreadyLoggedViolatedStacks) {
7253 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7254 logIt = false;
7255 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007256 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007257 // the relative pain numbers, without logging all
7258 // the stack traces repeatedly. We'd want to do
7259 // likewise in the client code, which also does
7260 // dup suppression, before the Binder call.
7261 } else {
7262 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7263 mAlreadyLoggedViolatedStacks.clear();
7264 }
7265 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7266 }
7267 }
7268 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007269 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007270 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007271 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007272
7273 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7274 AppErrorResult result = new AppErrorResult();
7275 synchronized (this) {
7276 final long origId = Binder.clearCallingIdentity();
7277
7278 Message msg = Message.obtain();
7279 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7280 HashMap<String, Object> data = new HashMap<String, Object>();
7281 data.put("result", result);
7282 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007283 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007284 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007285 msg.obj = data;
7286 mHandler.sendMessage(msg);
7287
7288 Binder.restoreCallingIdentity(origId);
7289 }
7290 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007291 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007292 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007293 }
7294
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007295 // Depending on the policy in effect, there could be a bunch of
7296 // these in quick succession so we try to batch these together to
7297 // minimize disk writes, number of dropbox entries, and maximize
7298 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007299 private void logStrictModeViolationToDropBox(
7300 ProcessRecord process,
7301 StrictMode.ViolationInfo info) {
7302 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007303 return;
7304 }
7305 final boolean isSystemApp = process == null ||
7306 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7307 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007308 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007309 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7310 final DropBoxManager dbox = (DropBoxManager)
7311 mContext.getSystemService(Context.DROPBOX_SERVICE);
7312
7313 // Exit early if the dropbox isn't configured to accept this report type.
7314 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7315
7316 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007317 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007318 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7319 synchronized (sb) {
7320 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007321 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007322 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7323 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007324 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7325 if (info.violationNumThisLoop != 0) {
7326 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7327 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007328 if (info.numAnimationsRunning != 0) {
7329 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7330 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007331 if (info.broadcastIntentAction != null) {
7332 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7333 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007334 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007335 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007336 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007337 if (info.numInstances != -1) {
7338 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7339 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007340 if (info.tags != null) {
7341 for (String tag : info.tags) {
7342 sb.append("Span-Tag: ").append(tag).append("\n");
7343 }
7344 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007345 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007346 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7347 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007348 }
7349 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007350
7351 // Only buffer up to ~64k. Various logging bits truncate
7352 // things at 128k.
7353 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007354 }
7355
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007356 // Flush immediately if the buffer's grown too large, or this
7357 // is a non-system app. Non-system apps are isolated with a
7358 // different tag & policy and not batched.
7359 //
7360 // Batching is useful during internal testing with
7361 // StrictMode settings turned up high. Without batching,
7362 // thousands of separate files could be created on boot.
7363 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007364 new Thread("Error dump: " + dropboxTag) {
7365 @Override
7366 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007367 String report;
7368 synchronized (sb) {
7369 report = sb.toString();
7370 sb.delete(0, sb.length());
7371 sb.trimToSize();
7372 }
7373 if (report.length() != 0) {
7374 dbox.addText(dropboxTag, report);
7375 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007376 }
7377 }.start();
7378 return;
7379 }
7380
7381 // System app batching:
7382 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007383 // An existing dropbox-writing thread is outstanding, so
7384 // we don't need to start it up. The existing thread will
7385 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007386 return;
7387 }
7388
7389 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7390 // (After this point, we shouldn't access AMS internal data structures.)
7391 new Thread("Error dump: " + dropboxTag) {
7392 @Override
7393 public void run() {
7394 // 5 second sleep to let stacks arrive and be batched together
7395 try {
7396 Thread.sleep(5000); // 5 seconds
7397 } catch (InterruptedException e) {}
7398
7399 String errorReport;
7400 synchronized (mStrictModeBuffer) {
7401 errorReport = mStrictModeBuffer.toString();
7402 if (errorReport.length() == 0) {
7403 return;
7404 }
7405 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7406 mStrictModeBuffer.trimToSize();
7407 }
7408 dbox.addText(dropboxTag, errorReport);
7409 }
7410 }.start();
7411 }
7412
Dan Egnor60d87622009-12-16 16:32:58 -08007413 /**
7414 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7415 * @param app object of the crashing app, null for the system server
7416 * @param tag reported by the caller
7417 * @param crashInfo describing the context of the error
7418 * @return true if the process should exit immediately (WTF is fatal)
7419 */
7420 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007421 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007422 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007423 final String processName = app == null ? "system_server"
7424 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007425
7426 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007427 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007428 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007429 tag, crashInfo.exceptionMessage);
7430
Jeff Sharkeya353d262011-10-28 11:12:06 -07007431 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007432
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007433 if (r != null && r.pid != Process.myPid() &&
7434 Settings.Secure.getInt(mContext.getContentResolver(),
7435 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007436 crashApplication(r, crashInfo);
7437 return true;
7438 } else {
7439 return false;
7440 }
7441 }
7442
7443 /**
7444 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7445 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7446 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007447 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007448 if (app == null) {
7449 return null;
7450 }
7451
7452 synchronized (this) {
7453 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7454 final int NA = apps.size();
7455 for (int ia=0; ia<NA; ia++) {
7456 ProcessRecord p = apps.valueAt(ia);
7457 if (p.thread != null && p.thread.asBinder() == app) {
7458 return p;
7459 }
7460 }
7461 }
7462
Dianne Hackborncb44d962011-03-10 17:02:27 -08007463 Slog.w(TAG, "Can't find mystery application for " + reason
7464 + " from pid=" + Binder.getCallingPid()
7465 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007466 return null;
7467 }
7468 }
7469
7470 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007471 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7472 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007473 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007474 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7475 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007476 // Watchdog thread ends up invoking this function (with
7477 // a null ProcessRecord) to add the stack file to dropbox.
7478 // Do not acquire a lock on this (am) in such cases, as it
7479 // could cause a potential deadlock, if and when watchdog
7480 // is invoked due to unavailability of lock on am and it
7481 // would prevent watchdog from killing system_server.
7482 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007483 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007484 return;
7485 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007486 // Note: ProcessRecord 'process' is guarded by the service
7487 // instance. (notably process.pkgList, which could otherwise change
7488 // concurrently during execution of this method)
7489 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007490 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007491 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007492 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007493 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7494 for (String pkg : process.pkgList) {
7495 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007496 try {
Dan Egnora455d192010-03-12 08:52:28 -08007497 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7498 if (pi != null) {
7499 sb.append(" v").append(pi.versionCode);
7500 if (pi.versionName != null) {
7501 sb.append(" (").append(pi.versionName).append(")");
7502 }
7503 }
7504 } catch (RemoteException e) {
7505 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007506 }
Dan Egnora455d192010-03-12 08:52:28 -08007507 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007508 }
Dan Egnora455d192010-03-12 08:52:28 -08007509 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007510 }
7511
7512 private static String processClass(ProcessRecord process) {
7513 if (process == null || process.pid == MY_PID) {
7514 return "system_server";
7515 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7516 return "system_app";
7517 } else {
7518 return "data_app";
7519 }
7520 }
7521
7522 /**
7523 * Write a description of an error (crash, WTF, ANR) to the drop box.
7524 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7525 * @param process which caused the error, null means the system server
7526 * @param activity which triggered the error, null if unknown
7527 * @param parent activity related to the error, null if unknown
7528 * @param subject line related to the error, null if absent
7529 * @param report in long form describing the error, null if absent
7530 * @param logFile to include in the report, null if none
7531 * @param crashInfo giving an application stack trace, null if absent
7532 */
7533 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007534 ProcessRecord process, String processName, ActivityRecord activity,
7535 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007536 final String report, final File logFile,
7537 final ApplicationErrorReport.CrashInfo crashInfo) {
7538 // NOTE -- this must never acquire the ActivityManagerService lock,
7539 // otherwise the watchdog may be prevented from resetting the system.
7540
7541 final String dropboxTag = processClass(process) + "_" + eventType;
7542 final DropBoxManager dbox = (DropBoxManager)
7543 mContext.getSystemService(Context.DROPBOX_SERVICE);
7544
7545 // Exit early if the dropbox isn't configured to accept this report type.
7546 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7547
7548 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007549 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007550 if (activity != null) {
7551 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7552 }
7553 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7554 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7555 }
7556 if (parent != null && parent != activity) {
7557 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7558 }
7559 if (subject != null) {
7560 sb.append("Subject: ").append(subject).append("\n");
7561 }
7562 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007563 if (Debug.isDebuggerConnected()) {
7564 sb.append("Debugger: Connected\n");
7565 }
Dan Egnora455d192010-03-12 08:52:28 -08007566 sb.append("\n");
7567
7568 // Do the rest in a worker thread to avoid blocking the caller on I/O
7569 // (After this point, we shouldn't access AMS internal data structures.)
7570 Thread worker = new Thread("Error dump: " + dropboxTag) {
7571 @Override
7572 public void run() {
7573 if (report != null) {
7574 sb.append(report);
7575 }
7576 if (logFile != null) {
7577 try {
7578 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7579 } catch (IOException e) {
7580 Slog.e(TAG, "Error reading " + logFile, e);
7581 }
7582 }
7583 if (crashInfo != null && crashInfo.stackTrace != null) {
7584 sb.append(crashInfo.stackTrace);
7585 }
7586
7587 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7588 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7589 if (lines > 0) {
7590 sb.append("\n");
7591
7592 // Merge several logcat streams, and take the last N lines
7593 InputStreamReader input = null;
7594 try {
7595 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7596 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7597 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7598
7599 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7600 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7601 input = new InputStreamReader(logcat.getInputStream());
7602
7603 int num;
7604 char[] buf = new char[8192];
7605 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7606 } catch (IOException e) {
7607 Slog.e(TAG, "Error running logcat", e);
7608 } finally {
7609 if (input != null) try { input.close(); } catch (IOException e) {}
7610 }
7611 }
7612
7613 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007614 }
Dan Egnora455d192010-03-12 08:52:28 -08007615 };
7616
7617 if (process == null || process.pid == MY_PID) {
7618 worker.run(); // We may be about to die -- need to run this synchronously
7619 } else {
7620 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007621 }
7622 }
7623
7624 /**
7625 * Bring up the "unexpected error" dialog box for a crashing app.
7626 * Deal with edge cases (intercepts from instrumented applications,
7627 * ActivityController, error intent receivers, that sort of thing).
7628 * @param r the application crashing
7629 * @param crashInfo describing the failure
7630 */
7631 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007632 long timeMillis = System.currentTimeMillis();
7633 String shortMsg = crashInfo.exceptionClassName;
7634 String longMsg = crashInfo.exceptionMessage;
7635 String stackTrace = crashInfo.stackTrace;
7636 if (shortMsg != null && longMsg != null) {
7637 longMsg = shortMsg + ": " + longMsg;
7638 } else if (shortMsg != null) {
7639 longMsg = shortMsg;
7640 }
7641
Dan Egnor60d87622009-12-16 16:32:58 -08007642 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007643 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007644 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007645 try {
7646 String name = r != null ? r.processName : null;
7647 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007648 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007649 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007650 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007651 + " at watcher's request");
7652 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007653 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007654 }
7655 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007656 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 }
7658 }
7659
7660 final long origId = Binder.clearCallingIdentity();
7661
7662 // If this process is running instrumentation, finish it.
7663 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007664 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007666 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7667 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007668 Bundle info = new Bundle();
7669 info.putString("shortMsg", shortMsg);
7670 info.putString("longMsg", longMsg);
7671 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7672 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007673 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007674 }
7675
Dan Egnor60d87622009-12-16 16:32:58 -08007676 // If we can't identify the process or it's already exceeded its crash quota,
7677 // quit right away without showing a crash dialog.
7678 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007679 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007680 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007681 }
7682
7683 Message msg = Message.obtain();
7684 msg.what = SHOW_ERROR_MSG;
7685 HashMap data = new HashMap();
7686 data.put("result", result);
7687 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007688 msg.obj = data;
7689 mHandler.sendMessage(msg);
7690
7691 Binder.restoreCallingIdentity(origId);
7692 }
7693
7694 int res = result.get();
7695
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007696 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007697 synchronized (this) {
7698 if (r != null) {
7699 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7700 SystemClock.uptimeMillis());
7701 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007702 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007703 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007704 }
7705 }
7706
7707 if (appErrorIntent != null) {
7708 try {
7709 mContext.startActivity(appErrorIntent);
7710 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007711 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007712 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007713 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007715
7716 Intent createAppErrorIntentLocked(ProcessRecord r,
7717 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7718 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007719 if (report == null) {
7720 return null;
7721 }
7722 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7723 result.setComponent(r.errorReportReceiver);
7724 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7725 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7726 return result;
7727 }
7728
Dan Egnorb7f03672009-12-09 16:22:32 -08007729 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7730 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007731 if (r.errorReportReceiver == null) {
7732 return null;
7733 }
7734
7735 if (!r.crashing && !r.notResponding) {
7736 return null;
7737 }
7738
Dan Egnorb7f03672009-12-09 16:22:32 -08007739 ApplicationErrorReport report = new ApplicationErrorReport();
7740 report.packageName = r.info.packageName;
7741 report.installerPackageName = r.errorReportReceiver.getPackageName();
7742 report.processName = r.processName;
7743 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007744 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007745
Dan Egnorb7f03672009-12-09 16:22:32 -08007746 if (r.crashing) {
7747 report.type = ApplicationErrorReport.TYPE_CRASH;
7748 report.crashInfo = crashInfo;
7749 } else if (r.notResponding) {
7750 report.type = ApplicationErrorReport.TYPE_ANR;
7751 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007752
Dan Egnorb7f03672009-12-09 16:22:32 -08007753 report.anrInfo.activity = r.notRespondingReport.tag;
7754 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7755 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007756 }
7757
Dan Egnorb7f03672009-12-09 16:22:32 -08007758 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007759 }
7760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007761 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7762 // assume our apps are happy - lazy create the list
7763 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7764
7765 synchronized (this) {
7766
7767 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007768 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7769 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7771 // This one's in trouble, so we'll generate a report for it
7772 // crashes are higher priority (in case there's a crash *and* an anr)
7773 ActivityManager.ProcessErrorStateInfo report = null;
7774 if (app.crashing) {
7775 report = app.crashingReport;
7776 } else if (app.notResponding) {
7777 report = app.notRespondingReport;
7778 }
7779
7780 if (report != null) {
7781 if (errList == null) {
7782 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7783 }
7784 errList.add(report);
7785 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007786 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007787 " crashing = " + app.crashing +
7788 " notResponding = " + app.notResponding);
7789 }
7790 }
7791 }
7792 }
7793
7794 return errList;
7795 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007796
7797 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007798 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007799 if (currApp != null) {
7800 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7801 }
7802 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007803 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7804 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007805 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7806 if (currApp != null) {
7807 currApp.lru = 0;
7808 }
7809 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007810 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007811 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7812 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7813 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7814 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7815 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7816 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7817 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7818 } else {
7819 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7820 }
7821 }
7822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7824 // Lazy instantiation of list
7825 List<ActivityManager.RunningAppProcessInfo> runList = null;
7826 synchronized (this) {
7827 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007828 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7829 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007830 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7831 // Generate process state info for running application
7832 ActivityManager.RunningAppProcessInfo currApp =
7833 new ActivityManager.RunningAppProcessInfo(app.processName,
7834 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007835 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007836 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007837 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007838 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007839 if (app.persistent) {
7840 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007842 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007843 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007844 currApp.importanceReasonCode = app.adjTypeCode;
7845 if (app.adjSource instanceof ProcessRecord) {
7846 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007847 currApp.importanceReasonImportance = oomAdjToImportance(
7848 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007849 } else if (app.adjSource instanceof ActivityRecord) {
7850 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007851 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7852 }
7853 if (app.adjTarget instanceof ComponentName) {
7854 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7855 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007856 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 // + " lru=" + currApp.lru);
7858 if (runList == null) {
7859 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7860 }
7861 runList.add(currApp);
7862 }
7863 }
7864 }
7865 return runList;
7866 }
7867
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007868 public List<ApplicationInfo> getRunningExternalApplications() {
7869 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7870 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7871 if (runningApps != null && runningApps.size() > 0) {
7872 Set<String> extList = new HashSet<String>();
7873 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7874 if (app.pkgList != null) {
7875 for (String pkg : app.pkgList) {
7876 extList.add(pkg);
7877 }
7878 }
7879 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007880 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007881 for (String pkg : extList) {
7882 try {
7883 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7884 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7885 retList.add(info);
7886 }
7887 } catch (RemoteException e) {
7888 }
7889 }
7890 }
7891 return retList;
7892 }
7893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 @Override
7895 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007896 if (checkCallingPermission(android.Manifest.permission.DUMP)
7897 != PackageManager.PERMISSION_GRANTED) {
7898 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7899 + Binder.getCallingPid()
7900 + ", uid=" + Binder.getCallingUid()
7901 + " without permission "
7902 + android.Manifest.permission.DUMP);
7903 return;
7904 }
7905
7906 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007907 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007908
7909 int opti = 0;
7910 while (opti < args.length) {
7911 String opt = args[opti];
7912 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7913 break;
7914 }
7915 opti++;
7916 if ("-a".equals(opt)) {
7917 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007918 } else if ("-c".equals(opt)) {
7919 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007920 } else if ("-h".equals(opt)) {
7921 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007922 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007923 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007924 pw.println(" a[ctivities]: activity stack state");
7925 pw.println(" b[roadcasts]: broadcast state");
7926 pw.println(" i[ntents]: pending intent state");
7927 pw.println(" p[rocesses]: process state");
7928 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007929 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7930 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007931 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007932 pw.println(" all: dump all activities");
7933 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007934 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007935 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7936 pw.println(" a partial substring in a component name, a");
7937 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007938 pw.println(" -a: include all available server state.");
7939 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007940 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007941 } else {
7942 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007944 }
7945
7946 // Is the caller requesting to dump a particular piece of data?
7947 if (opti < args.length) {
7948 String cmd = args[opti];
7949 opti++;
7950 if ("activities".equals(cmd) || "a".equals(cmd)) {
7951 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007952 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007954 return;
7955 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7956 synchronized (this) {
7957 dumpBroadcastsLocked(fd, pw, args, opti, true);
7958 }
7959 return;
7960 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7961 synchronized (this) {
7962 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7963 }
7964 return;
7965 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7966 synchronized (this) {
7967 dumpProcessesLocked(fd, pw, args, opti, true);
7968 }
7969 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007970 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7971 synchronized (this) {
7972 dumpOomLocked(fd, pw, args, opti, true);
7973 }
7974 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007975 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7976 synchronized (this) {
7977 dumpProvidersLocked(fd, pw, args, opti, true);
7978 }
7979 return;
7980 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007981 String[] newArgs;
7982 String name;
7983 if (opti >= args.length) {
7984 name = null;
7985 newArgs = EMPTY_STRING_ARRAY;
7986 } else {
7987 name = args[opti];
7988 opti++;
7989 newArgs = new String[args.length - opti];
7990 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7991 }
7992 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7993 pw.println("No services match: " + name);
7994 pw.println("Use -h for help.");
7995 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007996 return;
7997 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7998 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007999 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008000 }
8001 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008002 } else {
8003 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008004 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8005 pw.println("Bad activity command, or no activities match: " + cmd);
8006 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008007 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008008 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008009 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008010 }
8011
8012 // No piece of data specified, dump everything.
8013 synchronized (this) {
8014 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008015 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008016 if (needSep) {
8017 pw.println(" ");
8018 }
8019 if (dumpAll) {
8020 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008021 }
8022 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
8023 if (needSep) {
8024 pw.println(" ");
8025 }
8026 if (dumpAll) {
8027 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008028 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008029 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008030 if (needSep) {
8031 pw.println(" ");
8032 }
8033 if (dumpAll) {
8034 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008035 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008036 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008037 if (needSep) {
8038 pw.println(" ");
8039 }
8040 if (dumpAll) {
8041 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008042 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008043 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008044 if (needSep) {
8045 pw.println(" ");
8046 }
8047 if (dumpAll) {
8048 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008049 }
8050 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
8051 }
8052 }
8053
8054 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008055 int opti, boolean dumpAll, boolean dumpClient) {
8056 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8057 pw.println(" Main stack:");
8058 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008059 pw.println(" ");
8060 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008061 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008062 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008063 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008064 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008065 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
8066 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008067 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008068 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008069 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008071 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
8072 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008073 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008074 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8075 pw.println(" ");
8076 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008077 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
8078 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008079 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008080 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008081 pw.println(" ");
8082 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008083 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
8084 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008087 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008088 if (mMainStack.mPausingActivity != null) {
8089 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8090 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008091 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008092 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008093 if (dumpAll) {
8094 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8095 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008096 pw.println(" mDismissKeyguardOnNextActivity: "
8097 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008098 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008099
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008100 if (mRecentTasks.size() > 0) {
8101 pw.println();
8102 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008103
8104 final int N = mRecentTasks.size();
8105 for (int i=0; i<N; i++) {
8106 TaskRecord tr = mRecentTasks.get(i);
8107 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8108 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008109 if (dumpAll) {
8110 mRecentTasks.get(i).dump(pw, " ");
8111 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008112 }
8113 }
8114
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008115 if (dumpAll) {
8116 pw.println(" ");
8117 pw.println(" mCurTask: " + mCurTask);
8118 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008119
8120 return true;
8121 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008122
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008123 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8124 int opti, boolean dumpAll) {
8125 boolean needSep = false;
8126 int numPers = 0;
8127
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008128 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8129
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008130 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8132 final int NA = procs.size();
8133 for (int ia=0; ia<NA; ia++) {
8134 if (!needSep) {
8135 pw.println(" All known processes:");
8136 needSep = true;
8137 }
8138 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008139 pw.print(r.persistent ? " *PERS*" : " *APP*");
8140 pw.print(" UID "); pw.print(procs.keyAt(ia));
8141 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008142 r.dump(pw, " ");
8143 if (r.persistent) {
8144 numPers++;
8145 }
8146 }
8147 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008148 }
8149
8150 if (mLruProcesses.size() > 0) {
8151 if (needSep) pw.println(" ");
8152 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008153 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008154 dumpProcessOomList(pw, this, mLruProcesses, " ",
8155 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008156 needSep = true;
8157 }
8158
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008159 if (dumpAll) {
8160 synchronized (mPidsSelfLocked) {
8161 if (mPidsSelfLocked.size() > 0) {
8162 if (needSep) pw.println(" ");
8163 needSep = true;
8164 pw.println(" PID mappings:");
8165 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8166 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8167 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008169 }
8170 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008171 }
8172
8173 if (mForegroundProcesses.size() > 0) {
8174 if (needSep) pw.println(" ");
8175 needSep = true;
8176 pw.println(" Foreground Processes:");
8177 for (int i=0; i<mForegroundProcesses.size(); i++) {
8178 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8179 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008180 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008181 }
8182
8183 if (mPersistentStartingProcesses.size() > 0) {
8184 if (needSep) pw.println(" ");
8185 needSep = true;
8186 pw.println(" Persisent processes that are starting:");
8187 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008188 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008190
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008191 if (mRemovedProcesses.size() > 0) {
8192 if (needSep) pw.println(" ");
8193 needSep = true;
8194 pw.println(" Processes that are being removed:");
8195 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008196 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008197 }
8198
8199 if (mProcessesOnHold.size() > 0) {
8200 if (needSep) pw.println(" ");
8201 needSep = true;
8202 pw.println(" Processes that are on old until the system is ready:");
8203 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008204 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008206
Dianne Hackborn287952c2010-09-22 22:34:31 -07008207 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008208
8209 if (mProcessCrashTimes.getMap().size() > 0) {
8210 if (needSep) pw.println(" ");
8211 needSep = true;
8212 pw.println(" Time since processes crashed:");
8213 long now = SystemClock.uptimeMillis();
8214 for (Map.Entry<String, SparseArray<Long>> procs
8215 : mProcessCrashTimes.getMap().entrySet()) {
8216 SparseArray<Long> uids = procs.getValue();
8217 final int N = uids.size();
8218 for (int i=0; i<N; i++) {
8219 pw.print(" Process "); pw.print(procs.getKey());
8220 pw.print(" uid "); pw.print(uids.keyAt(i));
8221 pw.print(": last crashed ");
8222 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008223 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008224 }
8225 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008228 if (mBadProcesses.getMap().size() > 0) {
8229 if (needSep) pw.println(" ");
8230 needSep = true;
8231 pw.println(" Bad processes:");
8232 for (Map.Entry<String, SparseArray<Long>> procs
8233 : mBadProcesses.getMap().entrySet()) {
8234 SparseArray<Long> uids = procs.getValue();
8235 final int N = uids.size();
8236 for (int i=0; i<N; i++) {
8237 pw.print(" Bad process "); pw.print(procs.getKey());
8238 pw.print(" uid "); pw.print(uids.keyAt(i));
8239 pw.print(": crashed at time ");
8240 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241 }
8242 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008244
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008245 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008246 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008247 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008248 if (mHeavyWeightProcess != null) {
8249 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8250 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008251 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008252 if (dumpAll) {
8253 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008254 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008255 pw.println(" mScreenCompatPackages:");
8256 for (Map.Entry<String, Integer> entry
8257 : mCompatModePackages.getPackages().entrySet()) {
8258 String pkg = entry.getKey();
8259 int mode = entry.getValue();
8260 pw.print(" "); pw.print(pkg); pw.print(": ");
8261 pw.print(mode); pw.println();
8262 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008263 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008264 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008265 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8266 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8267 || mOrigWaitForDebugger) {
8268 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8269 + " mDebugTransient=" + mDebugTransient
8270 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8271 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008272 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8273 || mProfileFd != null) {
8274 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8275 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8276 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8277 + mAutoStopProfiler);
8278 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008279 if (mAlwaysFinishActivities || mController != null) {
8280 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8281 + " mController=" + mController);
8282 }
8283 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008284 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008286 + " mProcessesReady=" + mProcessesReady
8287 + " mSystemReady=" + mSystemReady);
8288 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289 + " mBooted=" + mBooted
8290 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008291 pw.print(" mLastPowerCheckRealtime=");
8292 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8293 pw.println("");
8294 pw.print(" mLastPowerCheckUptime=");
8295 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8296 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008297 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8298 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008299 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008300 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8301 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008303
8304 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008305 }
8306
Dianne Hackborn287952c2010-09-22 22:34:31 -07008307 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8308 int opti, boolean needSep, boolean dumpAll) {
8309 if (mProcessesToGc.size() > 0) {
8310 if (needSep) pw.println(" ");
8311 needSep = true;
8312 pw.println(" Processes that are waiting to GC:");
8313 long now = SystemClock.uptimeMillis();
8314 for (int i=0; i<mProcessesToGc.size(); i++) {
8315 ProcessRecord proc = mProcessesToGc.get(i);
8316 pw.print(" Process "); pw.println(proc);
8317 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8318 pw.print(", last gced=");
8319 pw.print(now-proc.lastRequestedGc);
8320 pw.print(" ms ago, last lowMem=");
8321 pw.print(now-proc.lastLowMemory);
8322 pw.println(" ms ago");
8323
8324 }
8325 }
8326 return needSep;
8327 }
8328
8329 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8330 int opti, boolean dumpAll) {
8331 boolean needSep = false;
8332
8333 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008334 if (needSep) pw.println(" ");
8335 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008336 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008337 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008338 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008339 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8340 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8341 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8342 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8343 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008344 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008345 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008346 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008347 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008348 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008349 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008350
8351 if (needSep) pw.println(" ");
8352 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008353 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008354 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008355 "Proc", "PERS", true);
8356 needSep = true;
8357 }
8358
8359 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8360
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008361 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008362 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008363 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008364 if (mHeavyWeightProcess != null) {
8365 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8366 }
8367
8368 return true;
8369 }
8370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 /**
8372 * There are three ways to call this:
8373 * - no service specified: dump all the services
8374 * - a flattened component name that matched an existing service was specified as the
8375 * first arg: dump that one service
8376 * - the first arg isn't the flattened component name of an existing service:
8377 * dump all services whose component contains the first arg as a substring
8378 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008379 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8380 int opti, boolean dumpAll) {
8381 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008382
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008383 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008384 synchronized (this) {
8385 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008386 services.add(r1);
8387 }
8388 }
8389 } else {
8390 ComponentName componentName = name != null
8391 ? ComponentName.unflattenFromString(name) : null;
8392 int objectId = 0;
8393 if (componentName == null) {
8394 // Not a '/' separated full component name; maybe an object ID?
8395 try {
8396 objectId = Integer.parseInt(name, 16);
8397 name = null;
8398 componentName = null;
8399 } catch (RuntimeException e) {
8400 }
8401 }
8402
8403 synchronized (this) {
8404 for (ServiceRecord r1 : mServices.values()) {
8405 if (componentName != null) {
8406 if (r1.name.equals(componentName)) {
8407 services.add(r1);
8408 }
8409 } else if (name != null) {
8410 if (r1.name.flattenToString().contains(name)) {
8411 services.add(r1);
8412 }
8413 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008414 services.add(r1);
8415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008416 }
8417 }
8418 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008419
8420 if (services.size() <= 0) {
8421 return false;
8422 }
8423
8424 boolean needSep = false;
8425 for (int i=0; i<services.size(); i++) {
8426 if (needSep) {
8427 pw.println();
8428 }
8429 needSep = true;
8430 dumpService("", fd, pw, services.get(i), args, dumpAll);
8431 }
8432 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 }
8434
8435 /**
8436 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8437 * there is a thread associated with the service.
8438 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008439 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8440 final ServiceRecord r, String[] args, boolean dumpAll) {
8441 String innerPrefix = prefix + " ";
8442 synchronized (this) {
8443 pw.print(prefix); pw.print("SERVICE ");
8444 pw.print(r.shortName); pw.print(" ");
8445 pw.print(Integer.toHexString(System.identityHashCode(r)));
8446 pw.print(" pid=");
8447 if (r.app != null) pw.println(r.app.pid);
8448 else pw.println("(not running)");
8449 if (dumpAll) {
8450 r.dump(pw, innerPrefix);
8451 }
8452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008454 pw.print(prefix); pw.println(" Client:");
8455 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008456 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008457 TransferPipe tp = new TransferPipe();
8458 try {
8459 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8460 tp.setBufferPrefix(prefix + " ");
8461 tp.go(fd);
8462 } finally {
8463 tp.kill();
8464 }
8465 } catch (IOException e) {
8466 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008467 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008468 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008469 }
8470 }
8471 }
8472
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008473 static class ItemMatcher {
8474 ArrayList<ComponentName> components;
8475 ArrayList<String> strings;
8476 ArrayList<Integer> objects;
8477 boolean all;
8478
8479 ItemMatcher() {
8480 all = true;
8481 }
8482
8483 void build(String name) {
8484 ComponentName componentName = ComponentName.unflattenFromString(name);
8485 if (componentName != null) {
8486 if (components == null) {
8487 components = new ArrayList<ComponentName>();
8488 }
8489 components.add(componentName);
8490 all = false;
8491 } else {
8492 int objectId = 0;
8493 // Not a '/' separated full component name; maybe an object ID?
8494 try {
8495 objectId = Integer.parseInt(name, 16);
8496 if (objects == null) {
8497 objects = new ArrayList<Integer>();
8498 }
8499 objects.add(objectId);
8500 all = false;
8501 } catch (RuntimeException e) {
8502 // Not an integer; just do string match.
8503 if (strings == null) {
8504 strings = new ArrayList<String>();
8505 }
8506 strings.add(name);
8507 all = false;
8508 }
8509 }
8510 }
8511
8512 int build(String[] args, int opti) {
8513 for (; opti<args.length; opti++) {
8514 String name = args[opti];
8515 if ("--".equals(name)) {
8516 return opti+1;
8517 }
8518 build(name);
8519 }
8520 return opti;
8521 }
8522
8523 boolean match(Object object, ComponentName comp) {
8524 if (all) {
8525 return true;
8526 }
8527 if (components != null) {
8528 for (int i=0; i<components.size(); i++) {
8529 if (components.get(i).equals(comp)) {
8530 return true;
8531 }
8532 }
8533 }
8534 if (objects != null) {
8535 for (int i=0; i<objects.size(); i++) {
8536 if (System.identityHashCode(object) == objects.get(i)) {
8537 return true;
8538 }
8539 }
8540 }
8541 if (strings != null) {
8542 String flat = comp.flattenToString();
8543 for (int i=0; i<strings.size(); i++) {
8544 if (flat.contains(strings.get(i))) {
8545 return true;
8546 }
8547 }
8548 }
8549 return false;
8550 }
8551 }
8552
Dianne Hackborn625ac272010-09-17 18:29:22 -07008553 /**
8554 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008555 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008556 * - the cmd arg isn't the flattened component name of an existing activity:
8557 * dump all activity whose component contains the cmd as a substring
8558 * - A hex number of the ActivityRecord object instance.
8559 */
8560 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8561 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008562 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008563
8564 if ("all".equals(name)) {
8565 synchronized (this) {
8566 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008567 activities.add(r1);
8568 }
8569 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008570 } else if ("top".equals(name)) {
8571 synchronized (this) {
8572 final int N = mMainStack.mHistory.size();
8573 if (N > 0) {
8574 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8575 }
8576 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008577 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008578 ItemMatcher matcher = new ItemMatcher();
8579 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008580
8581 synchronized (this) {
8582 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008583 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008584 activities.add(r1);
8585 }
8586 }
8587 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008588 }
8589
8590 if (activities.size() <= 0) {
8591 return false;
8592 }
8593
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008594 String[] newArgs = new String[args.length - opti];
8595 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8596
Dianne Hackborn30d71892010-12-11 10:37:55 -08008597 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008598 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008599 for (int i=activities.size()-1; i>=0; i--) {
8600 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008601 if (needSep) {
8602 pw.println();
8603 }
8604 needSep = true;
8605 synchronized (this) {
8606 if (lastTask != r.task) {
8607 lastTask = r.task;
8608 pw.print("TASK "); pw.print(lastTask.affinity);
8609 pw.print(" id="); pw.println(lastTask.taskId);
8610 if (dumpAll) {
8611 lastTask.dump(pw, " ");
8612 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008613 }
8614 }
8615 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008616 }
8617 return true;
8618 }
8619
8620 /**
8621 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8622 * there is a thread associated with the activity.
8623 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008624 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008625 final ActivityRecord r, String[] args, boolean dumpAll) {
8626 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008627 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008628 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8629 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8630 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008631 if (r.app != null) pw.println(r.app.pid);
8632 else pw.println("(not running)");
8633 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008634 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008635 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008636 }
8637 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008638 // flush anything that is already in the PrintWriter since the thread is going
8639 // to write to the file descriptor directly
8640 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008641 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008642 TransferPipe tp = new TransferPipe();
8643 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008644 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8645 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008646 tp.go(fd);
8647 } finally {
8648 tp.kill();
8649 }
8650 } catch (IOException e) {
8651 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008652 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008653 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008654 }
8655 }
8656 }
8657
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008658 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8659 int opti, boolean dumpAll) {
8660 boolean needSep = false;
8661
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008662 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008663 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008664 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008665 pw.println(" Registered Receivers:");
8666 Iterator it = mRegisteredReceivers.values().iterator();
8667 while (it.hasNext()) {
8668 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008669 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008670 r.dump(pw, " ");
8671 }
8672 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008673
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008674 pw.println();
8675 pw.println(" Receiver Resolver Table:");
8676 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008677 needSep = true;
8678 }
8679
8680 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8681 || mPendingBroadcast != null) {
8682 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008683 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008684 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008685 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008686 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8687 pw.println(" Broadcast #" + i + ":");
8688 mParallelBroadcasts.get(i).dump(pw, " ");
8689 }
8690 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008691 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008692 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008693 }
8694 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8695 pw.println(" Serialized Broadcast #" + i + ":");
8696 mOrderedBroadcasts.get(i).dump(pw, " ");
8697 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008698 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008699 pw.println(" Pending broadcast:");
8700 if (mPendingBroadcast != null) {
8701 mPendingBroadcast.dump(pw, " ");
8702 } else {
8703 pw.println(" (null)");
8704 }
8705 needSep = true;
8706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008707
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008708 if (needSep) {
8709 pw.println();
8710 }
8711 pw.println(" Historical broadcasts:");
8712 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8713 BroadcastRecord r = mBroadcastHistory[i];
8714 if (r == null) {
8715 break;
8716 }
8717 if (dumpAll) {
8718 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8719 r.dump(pw, " ");
8720 } else {
8721 if (i >= 50) {
8722 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008723 break;
8724 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008725 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008726 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008727 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008728 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008729
8730 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008731 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008732 pw.println(" Sticky broadcasts:");
8733 StringBuilder sb = new StringBuilder(128);
8734 for (Map.Entry<String, ArrayList<Intent>> ent
8735 : mStickyBroadcasts.entrySet()) {
8736 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008737 if (dumpAll) {
8738 pw.println(":");
8739 ArrayList<Intent> intents = ent.getValue();
8740 final int N = intents.size();
8741 for (int i=0; i<N; i++) {
8742 sb.setLength(0);
8743 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008744 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008745 pw.println(sb.toString());
8746 Bundle bundle = intents.get(i).getExtras();
8747 if (bundle != null) {
8748 pw.print(" ");
8749 pw.println(bundle.toString());
8750 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008751 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008752 } else {
8753 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008754 }
8755 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008756 needSep = true;
8757 }
8758
8759 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008760 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008761 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008762 pw.println(" mHandler:");
8763 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008764 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008765 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008766
8767 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008768 }
8769
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008770 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008771 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008772 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008773
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008774 ItemMatcher matcher = new ItemMatcher();
8775 matcher.build(args, opti);
8776
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008777 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8778 if (mServices.size() > 0) {
8779 pw.println(" Active services:");
8780 long nowReal = SystemClock.elapsedRealtime();
8781 Iterator<ServiceRecord> it = mServices.values().iterator();
8782 needSep = false;
8783 while (it.hasNext()) {
8784 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008785 if (!matcher.match(r, r.name)) {
8786 continue;
8787 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008788 if (needSep) {
8789 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008791 pw.print(" * "); pw.println(r);
8792 if (dumpAll) {
8793 r.dump(pw, " ");
8794 needSep = true;
8795 } else {
8796 pw.print(" app="); pw.println(r.app);
8797 pw.print(" created=");
8798 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8799 pw.print(" started="); pw.print(r.startRequested);
8800 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08008801 if (r.connections.size() > 0) {
8802 pw.println(" Connections:");
8803 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
8804 for (int i=0; i<clist.size(); i++) {
8805 ConnectionRecord conn = clist.get(i);
8806 pw.print(" ");
8807 pw.print(conn.binding.intent.intent.getIntent().toShortString(
8808 false, false, false));
8809 pw.print(" -> ");
8810 ProcessRecord proc = conn.binding.client;
8811 pw.println(proc != null ? proc.toShortString() : "null");
8812 }
8813 }
8814 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008815 }
8816 if (dumpClient && r.app != null && r.app.thread != null) {
8817 pw.println(" Client:");
8818 pw.flush();
8819 try {
8820 TransferPipe tp = new TransferPipe();
8821 try {
8822 r.app.thread.dumpService(
8823 tp.getWriteFd().getFileDescriptor(), r, args);
8824 tp.setBufferPrefix(" ");
8825 // Short timeout, since blocking here can
8826 // deadlock with the application.
8827 tp.go(fd, 2000);
8828 } finally {
8829 tp.kill();
8830 }
8831 } catch (IOException e) {
8832 pw.println(" Failure while dumping the service: " + e);
8833 } catch (RemoteException e) {
8834 pw.println(" Got a RemoteException while dumping the service");
8835 }
8836 needSep = true;
8837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008838 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008839 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008842 if (mPendingServices.size() > 0) {
8843 if (needSep) pw.println(" ");
8844 pw.println(" Pending services:");
8845 for (int i=0; i<mPendingServices.size(); i++) {
8846 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008847 if (!matcher.match(r, r.name)) {
8848 continue;
8849 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008850 pw.print(" * Pending "); pw.println(r);
8851 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008852 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008853 needSep = true;
8854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008855
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008856 if (mRestartingServices.size() > 0) {
8857 if (needSep) pw.println(" ");
8858 pw.println(" Restarting services:");
8859 for (int i=0; i<mRestartingServices.size(); i++) {
8860 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008861 if (!matcher.match(r, r.name)) {
8862 continue;
8863 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008864 pw.print(" * Restarting "); pw.println(r);
8865 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008867 needSep = true;
8868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008869
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008870 if (mStoppingServices.size() > 0) {
8871 if (needSep) pw.println(" ");
8872 pw.println(" Stopping services:");
8873 for (int i=0; i<mStoppingServices.size(); i++) {
8874 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008875 if (!matcher.match(r, r.name)) {
8876 continue;
8877 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008878 pw.print(" * Stopping "); pw.println(r);
8879 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008880 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008881 needSep = true;
8882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008884 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008885 if (mServiceConnections.size() > 0) {
8886 if (needSep) pw.println(" ");
8887 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008888 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008889 = mServiceConnections.values().iterator();
8890 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008891 ArrayList<ConnectionRecord> r = it.next();
8892 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008893 ConnectionRecord cr = r.get(i);
8894 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8895 continue;
8896 }
8897 pw.print(" * "); pw.println(cr);
8898 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008900 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008901 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008902 }
8903 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008904
8905 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008906 }
8907
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008908 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8909 int opti, boolean dumpAll) {
8910 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008912 ItemMatcher matcher = new ItemMatcher();
8913 matcher.build(args, opti);
8914
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008915 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8916 if (mProvidersByClass.size() > 0) {
8917 if (needSep) pw.println(" ");
8918 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008919 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008920 = mProvidersByClass.entrySet().iterator();
8921 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008922 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008923 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008924 ComponentName comp = e.getKey();
8925 String cls = comp.getClassName();
8926 int end = cls.lastIndexOf('.');
8927 if (end > 0 && end < (cls.length()-2)) {
8928 cls = cls.substring(end+1);
8929 }
8930 if (!matcher.match(r, comp)) {
8931 continue;
8932 }
8933 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08008934 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008935 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008936 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008937 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008938 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008939 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008940 } else {
8941 pw.println();
8942 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08008943 if (r.clients.size() > 0) {
8944 pw.println(" Clients:");
8945 for (ProcessRecord cproc : r.clients) {
8946 pw.print(" - "); pw.println(cproc);
8947 }
8948 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008950 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008951 needSep = true;
8952 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008953
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008954 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008955 if (mProvidersByName.size() > 0) {
8956 pw.println(" ");
8957 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008958 Iterator<Map.Entry<String, ContentProviderRecord>> it
8959 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008960 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008961 Map.Entry<String, ContentProviderRecord> e = it.next();
8962 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008963 if (!matcher.match(r, r.name)) {
8964 continue;
8965 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08008966 pw.print(" "); pw.print(e.getKey()); pw.println(":");
8967 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008968 }
8969 needSep = true;
8970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008971 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008972
8973 if (mLaunchingProviders.size() > 0) {
8974 if (needSep) pw.println(" ");
8975 pw.println(" Launching content providers:");
8976 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8977 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8978 pw.println(mLaunchingProviders.get(i));
8979 }
8980 needSep = true;
8981 }
8982
8983 if (mGrantedUriPermissions.size() > 0) {
8984 pw.println();
8985 pw.println("Granted Uri Permissions:");
8986 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8987 int uid = mGrantedUriPermissions.keyAt(i);
8988 HashMap<Uri, UriPermission> perms
8989 = mGrantedUriPermissions.valueAt(i);
8990 pw.print(" * UID "); pw.print(uid);
8991 pw.println(" holds:");
8992 for (UriPermission perm : perms.values()) {
8993 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008994 if (dumpAll) {
8995 perm.dump(pw, " ");
8996 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008997 }
8998 }
8999 needSep = true;
9000 }
9001
9002 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009003 }
9004
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009005 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9006 int opti, boolean dumpAll) {
9007 boolean needSep = false;
9008
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009009 if (this.mIntentSenderRecords.size() > 0) {
9010 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9011 Iterator<WeakReference<PendingIntentRecord>> it
9012 = mIntentSenderRecords.values().iterator();
9013 while (it.hasNext()) {
9014 WeakReference<PendingIntentRecord> ref = it.next();
9015 PendingIntentRecord rec = ref != null ? ref.get(): null;
9016 needSep = true;
9017 if (rec != null) {
9018 pw.print(" * "); pw.println(rec);
9019 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009021 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009022 } else {
9023 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009024 }
9025 }
9026 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009027
9028 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009029 }
9030
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009031 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9032 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009033 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009034 boolean needNL = false;
9035 final String innerPrefix = prefix + " ";
9036 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009038 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009039 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009040 if (needNL) {
9041 pw.println(" ");
9042 needNL = false;
9043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 if (lastTask != r.task) {
9045 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009046 pw.print(prefix);
9047 pw.print(full ? "* " : " ");
9048 pw.println(lastTask);
9049 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009050 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009051 } else if (complete) {
9052 // Complete + brief == give a summary. Isn't that obvious?!?
9053 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009054 pw.print(prefix); pw.print(" ");
9055 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009056 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009058 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009059 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9060 pw.print(" #"); pw.print(i); pw.print(": ");
9061 pw.println(r);
9062 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009063 r.dump(pw, innerPrefix);
9064 } else if (complete) {
9065 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009066 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009067 if (r.app != null) {
9068 pw.print(innerPrefix); pw.println(r.app);
9069 }
9070 }
9071 if (client && r.app != null && r.app.thread != null) {
9072 // flush anything that is already in the PrintWriter since the thread is going
9073 // to write to the file descriptor directly
9074 pw.flush();
9075 try {
9076 TransferPipe tp = new TransferPipe();
9077 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009078 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9079 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009080 // Short timeout, since blocking here can
9081 // deadlock with the application.
9082 tp.go(fd, 2000);
9083 } finally {
9084 tp.kill();
9085 }
9086 } catch (IOException e) {
9087 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9088 } catch (RemoteException e) {
9089 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9090 }
9091 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009092 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009093 }
9094 }
9095
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009096 private static String buildOomTag(String prefix, String space, int val, int base) {
9097 if (val == base) {
9098 if (space == null) return prefix;
9099 return prefix + " ";
9100 }
9101 return prefix + "+" + Integer.toString(val-base);
9102 }
9103
9104 private static final int dumpProcessList(PrintWriter pw,
9105 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009106 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009107 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009108 final int N = list.size()-1;
9109 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009110 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009111 pw.println(String.format("%s%s #%2d: %s",
9112 prefix, (r.persistent ? persistentLabel : normalLabel),
9113 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009114 if (r.persistent) {
9115 numPers++;
9116 }
9117 }
9118 return numPers;
9119 }
9120
Dianne Hackborn287952c2010-09-22 22:34:31 -07009121 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009122 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009123 String prefix, String normalLabel, String persistentLabel,
9124 boolean inclDetails) {
9125
Dianne Hackborn905577f2011-09-07 18:31:28 -07009126 ArrayList<Pair<ProcessRecord, Integer>> list
9127 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9128 for (int i=0; i<origList.size(); i++) {
9129 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9130 }
9131
9132 Comparator<Pair<ProcessRecord, Integer>> comparator
9133 = new Comparator<Pair<ProcessRecord, Integer>>() {
9134 @Override
9135 public int compare(Pair<ProcessRecord, Integer> object1,
9136 Pair<ProcessRecord, Integer> object2) {
9137 if (object1.first.setAdj != object2.first.setAdj) {
9138 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9139 }
9140 if (object1.second.intValue() != object2.second.intValue()) {
9141 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9142 }
9143 return 0;
9144 }
9145 };
9146
9147 Collections.sort(list, comparator);
9148
Dianne Hackborn287952c2010-09-22 22:34:31 -07009149 final long curRealtime = SystemClock.elapsedRealtime();
9150 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9151 final long curUptime = SystemClock.uptimeMillis();
9152 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9153
9154 final int N = list.size()-1;
9155 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009156 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009157 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009158 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009159 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009160 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9161 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009162 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9163 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009164 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9165 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009166 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9167 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009168 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9169 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9170 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9171 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9172 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9173 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9174 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9175 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9176 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9177 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009178 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9179 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009180 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9181 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009182 } else {
9183 oomAdj = Integer.toString(r.setAdj);
9184 }
9185 String schedGroup;
9186 switch (r.setSchedGroup) {
9187 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9188 schedGroup = "B";
9189 break;
9190 case Process.THREAD_GROUP_DEFAULT:
9191 schedGroup = "F";
9192 break;
9193 default:
9194 schedGroup = Integer.toString(r.setSchedGroup);
9195 break;
9196 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009197 String foreground;
9198 if (r.foregroundActivities) {
9199 foreground = "A";
9200 } else if (r.foregroundServices) {
9201 foreground = "S";
9202 } else {
9203 foreground = " ";
9204 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009205 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009206 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009207 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009208 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009209 if (r.adjSource != null || r.adjTarget != null) {
9210 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009211 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009212 if (r.adjTarget instanceof ComponentName) {
9213 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9214 } else if (r.adjTarget != null) {
9215 pw.print(r.adjTarget.toString());
9216 } else {
9217 pw.print("{null}");
9218 }
9219 pw.print("<=");
9220 if (r.adjSource instanceof ProcessRecord) {
9221 pw.print("Proc{");
9222 pw.print(((ProcessRecord)r.adjSource).toShortString());
9223 pw.println("}");
9224 } else if (r.adjSource != null) {
9225 pw.println(r.adjSource.toString());
9226 } else {
9227 pw.println("{null}");
9228 }
9229 }
9230 if (inclDetails) {
9231 pw.print(prefix);
9232 pw.print(" ");
9233 pw.print("oom: max="); pw.print(r.maxAdj);
9234 pw.print(" hidden="); pw.print(r.hiddenAdj);
9235 pw.print(" curRaw="); pw.print(r.curRawAdj);
9236 pw.print(" setRaw="); pw.print(r.setRawAdj);
9237 pw.print(" cur="); pw.print(r.curAdj);
9238 pw.print(" set="); pw.println(r.setAdj);
9239 pw.print(prefix);
9240 pw.print(" ");
9241 pw.print("keeping="); pw.print(r.keeping);
9242 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009243 pw.print(" empty="); pw.print(r.empty);
9244 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009245
9246 if (!r.keeping) {
9247 if (r.lastWakeTime != 0) {
9248 long wtime;
9249 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9250 synchronized (stats) {
9251 wtime = stats.getProcessWakeTime(r.info.uid,
9252 r.pid, curRealtime);
9253 }
9254 long timeUsed = wtime - r.lastWakeTime;
9255 pw.print(prefix);
9256 pw.print(" ");
9257 pw.print("keep awake over ");
9258 TimeUtils.formatDuration(realtimeSince, pw);
9259 pw.print(" used ");
9260 TimeUtils.formatDuration(timeUsed, pw);
9261 pw.print(" (");
9262 pw.print((timeUsed*100)/realtimeSince);
9263 pw.println("%)");
9264 }
9265 if (r.lastCpuTime != 0) {
9266 long timeUsed = r.curCpuTime - r.lastCpuTime;
9267 pw.print(prefix);
9268 pw.print(" ");
9269 pw.print("run cpu over ");
9270 TimeUtils.formatDuration(uptimeSince, pw);
9271 pw.print(" used ");
9272 TimeUtils.formatDuration(timeUsed, pw);
9273 pw.print(" (");
9274 pw.print((timeUsed*100)/uptimeSince);
9275 pw.println("%)");
9276 }
9277 }
9278 }
9279 }
9280 }
9281
Dianne Hackbornb437e092011-08-05 17:50:29 -07009282 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009283 ArrayList<ProcessRecord> procs;
9284 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009285 if (args != null && args.length > start
9286 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009287 procs = new ArrayList<ProcessRecord>();
9288 int pid = -1;
9289 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009290 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009291 } catch (NumberFormatException e) {
9292
9293 }
9294 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9295 ProcessRecord proc = mLruProcesses.get(i);
9296 if (proc.pid == pid) {
9297 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009298 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009299 procs.add(proc);
9300 }
9301 }
9302 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009303 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009304 return null;
9305 }
9306 } else {
9307 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9308 }
9309 }
9310 return procs;
9311 }
9312
9313 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9314 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009315 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009316 if (procs == null) {
9317 return;
9318 }
9319
9320 long uptime = SystemClock.uptimeMillis();
9321 long realtime = SystemClock.elapsedRealtime();
9322 pw.println("Applications Graphics Acceleration Info:");
9323 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9324
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009325 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9326 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009327 if (r.thread != null) {
9328 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9329 pw.flush();
9330 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009331 TransferPipe tp = new TransferPipe();
9332 try {
9333 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9334 tp.go(fd);
9335 } finally {
9336 tp.kill();
9337 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009338 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009339 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009340 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009341 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009342 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009343 pw.flush();
9344 }
9345 }
9346 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009347 }
9348
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009349 final static class MemItem {
9350 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009351 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009352 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009353 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009354 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009355
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009356 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009357 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009358 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009359 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009360 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009361 }
9362 }
9363
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009364 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009365 boolean sort) {
9366 if (sort) {
9367 Collections.sort(items, new Comparator<MemItem>() {
9368 @Override
9369 public int compare(MemItem lhs, MemItem rhs) {
9370 if (lhs.pss < rhs.pss) {
9371 return 1;
9372 } else if (lhs.pss > rhs.pss) {
9373 return -1;
9374 }
9375 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009376 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009377 });
9378 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009379
9380 for (int i=0; i<items.size(); i++) {
9381 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009382 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009383 if (mi.subitems != null) {
9384 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9385 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009386 }
9387 }
9388
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009389 // These are in KB.
9390 static final long[] DUMP_MEM_BUCKETS = new long[] {
9391 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9392 120*1024, 160*1024, 200*1024,
9393 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9394 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9395 };
9396
9397 static final void appendMemBucket(StringBuilder out, long memKB, String label) {
9398 int start = label.lastIndexOf('.');
9399 if (start >= 0) start++;
9400 else start = 0;
9401 int end = label.length();
9402 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9403 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9404 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9405 out.append(bucket);
9406 out.append("MB ");
9407 out.append(label, start, end);
9408 return;
9409 }
9410 }
9411 out.append(memKB/1024);
9412 out.append("MB ");
9413 out.append(label, start, end);
9414 }
9415
9416 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9417 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9418 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9419 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9420 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9421 };
9422 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9423 "System", "Persistent", "Foreground",
9424 "Visible", "Perceptible", "Heavy Weight",
9425 "Backup", "A Services", "Home", "Previous",
9426 "B Services", "Background"
9427 };
9428
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009429 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009430 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009431 PrintWriter categoryPw, StringBuilder outTag) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009432 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009433 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009434
9435 int opti = 0;
9436 while (opti < args.length) {
9437 String opt = args[opti];
9438 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9439 break;
9440 }
9441 opti++;
9442 if ("-a".equals(opt)) {
9443 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009444 } else if ("--oom".equals(opt)) {
9445 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009446 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009447 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009448 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009449 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009450 pw.println("If [process] is specified it can be the name or ");
9451 pw.println("pid of a specific process to dump.");
9452 return;
9453 } else {
9454 pw.println("Unknown argument: " + opt + "; use -h for help");
9455 }
9456 }
9457
9458 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009459 if (procs == null) {
9460 return;
9461 }
9462
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009463 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009464 long uptime = SystemClock.uptimeMillis();
9465 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009466
9467 if (procs.size() == 1 || isCheckinRequest) {
9468 dumpAll = true;
9469 }
9470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009471 if (isCheckinRequest) {
9472 // short checkin version
9473 pw.println(uptime + "," + realtime);
9474 pw.flush();
9475 } else {
9476 pw.println("Applications Memory Usage (kB):");
9477 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9478 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009479
Dianne Hackbornb437e092011-08-05 17:50:29 -07009480 String[] innerArgs = new String[args.length-opti];
9481 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9482
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009483 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9484 long nativePss=0, dalvikPss=0, otherPss=0;
9485 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9486
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009487 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9488 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9489 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009490
9491 long totalPss = 0;
9492
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009493 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9494 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009495 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009496 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9498 pw.flush();
9499 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009500 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009501 if (dumpAll) {
9502 try {
9503 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9504 } catch (RemoteException e) {
9505 if (!isCheckinRequest) {
9506 pw.println("Got RemoteException!");
9507 pw.flush();
9508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009510 } else {
9511 mi = new Debug.MemoryInfo();
9512 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009513 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009514
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009515 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009516 long myTotalPss = mi.getTotalPss();
9517 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009518 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009519 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009520 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009521
9522 nativePss += mi.nativePss;
9523 dalvikPss += mi.dalvikPss;
9524 otherPss += mi.otherPss;
9525 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9526 long mem = mi.getOtherPss(j);
9527 miscPss[j] += mem;
9528 otherPss -= mem;
9529 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009530
9531 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009532 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9533 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009534 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009535 if (oomProcs[oomIndex] == null) {
9536 oomProcs[oomIndex] = new ArrayList<MemItem>();
9537 }
9538 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009539 break;
9540 }
9541 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 }
9544 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009545
9546 if (!isCheckinRequest && procs.size() > 1) {
9547 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9548
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009549 catMems.add(new MemItem("Native", "Native", nativePss, -1));
9550 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9551 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009552 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009553 String label = Debug.MemoryInfo.getOtherLabel(j);
9554 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009555 }
9556
Dianne Hackbornb437e092011-08-05 17:50:29 -07009557 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9558 for (int j=0; j<oomPss.length; j++) {
9559 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009560 String label = DUMP_MEM_OOM_LABEL[j];
9561 MemItem item = new MemItem(label, label, oomPss[j],
9562 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009563 item.subitems = oomProcs[j];
9564 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009565 }
9566 }
9567
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009568 if (outTag != null) {
9569 appendMemBucket(outTag, totalPss, "total");
9570 for (int i=0; i<oomMems.size(); i++) {
9571 MemItem miCat = oomMems.get(i);
9572 if (miCat.subitems == null || miCat.subitems.size() < 1) {
9573 continue;
9574 }
9575 if (miCat.id < ProcessList.SERVICE_ADJ
9576 || miCat.id == ProcessList.HOME_APP_ADJ
9577 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
9578 outTag.append(" / ");
9579 for (int j=0; j<miCat.subitems.size(); j++) {
9580 MemItem mi = miCat.subitems.get(j);
9581 if (j > 0) {
9582 outTag.append(" ");
9583 }
9584 appendMemBucket(outTag, mi.pss, mi.shortLabel);
9585 }
9586 }
9587 }
9588 }
9589
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009590 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009591 pw.println();
9592 pw.println("Total PSS by process:");
9593 dumpMemItems(pw, " ", procMems, true);
9594 pw.println();
9595 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009596 pw.println("Total PSS by OOM adjustment:");
9597 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009598 if (!oomOnly) {
9599 PrintWriter out = categoryPw != null ? categoryPw : pw;
9600 out.println();
9601 out.println("Total PSS by category:");
9602 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009603 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009604 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009605 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009607 }
9608
9609 /**
9610 * Searches array of arguments for the specified string
9611 * @param args array of argument strings
9612 * @param value value to search for
9613 * @return true if the value is contained in the array
9614 */
9615 private static boolean scanArgs(String[] args, String value) {
9616 if (args != null) {
9617 for (String arg : args) {
9618 if (value.equals(arg)) {
9619 return true;
9620 }
9621 }
9622 }
9623 return false;
9624 }
9625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009626 private final void killServicesLocked(ProcessRecord app,
9627 boolean allowRestart) {
9628 // Report disconnected services.
9629 if (false) {
9630 // XXX we are letting the client link to the service for
9631 // death notifications.
9632 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009633 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009635 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009636 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009637 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009638 = r.connections.values().iterator();
9639 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009640 ArrayList<ConnectionRecord> cl = jt.next();
9641 for (int i=0; i<cl.size(); i++) {
9642 ConnectionRecord c = cl.get(i);
9643 if (c.binding.client != app) {
9644 try {
9645 //c.conn.connected(r.className, null);
9646 } catch (Exception e) {
9647 // todo: this should be asynchronous!
9648 Slog.w(TAG, "Exception thrown disconnected servce "
9649 + r.shortName
9650 + " from app " + app.processName, e);
9651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652 }
9653 }
9654 }
9655 }
9656 }
9657 }
9658 }
9659
9660 // Clean up any connections this application has to other services.
9661 if (app.connections.size() > 0) {
9662 Iterator<ConnectionRecord> it = app.connections.iterator();
9663 while (it.hasNext()) {
9664 ConnectionRecord r = it.next();
9665 removeConnectionLocked(r, app, null);
9666 }
9667 }
9668 app.connections.clear();
9669
9670 if (app.services.size() != 0) {
9671 // Any services running in the application need to be placed
9672 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009673 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009675 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009676 synchronized (sr.stats.getBatteryStats()) {
9677 sr.stats.stopLaunchedLocked();
9678 }
9679 sr.app = null;
9680 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009681 if (mStoppingServices.remove(sr)) {
9682 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9683 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009684
9685 boolean hasClients = sr.bindings.size() > 0;
9686 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009687 Iterator<IntentBindRecord> bindings
9688 = sr.bindings.values().iterator();
9689 while (bindings.hasNext()) {
9690 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009691 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009692 + ": shouldUnbind=" + b.hasBound);
9693 b.binder = null;
9694 b.requested = b.received = b.hasBound = false;
9695 }
9696 }
9697
Dianne Hackborn070783f2010-12-29 16:46:28 -08009698 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9699 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009700 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009701 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009702 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009703 sr.crashCount, sr.shortName, app.pid);
9704 bringDownServiceLocked(sr, true);
9705 } else if (!allowRestart) {
9706 bringDownServiceLocked(sr, true);
9707 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009708 boolean canceled = scheduleServiceRestartLocked(sr, true);
9709
9710 // Should the service remain running? Note that in the
9711 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009712 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009713 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9714 if (sr.pendingStarts.size() == 0) {
9715 sr.startRequested = false;
9716 if (!hasClients) {
9717 // Whoops, no reason to restart!
9718 bringDownServiceLocked(sr, true);
9719 }
9720 }
9721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009722 }
9723 }
9724
9725 if (!allowRestart) {
9726 app.services.clear();
9727 }
9728 }
9729
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009730 // Make sure we have no more records on the stopping list.
9731 int i = mStoppingServices.size();
9732 while (i > 0) {
9733 i--;
9734 ServiceRecord sr = mStoppingServices.get(i);
9735 if (sr.app == app) {
9736 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009737 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009738 }
9739 }
9740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 app.executingServices.clear();
9742 }
9743
9744 private final void removeDyingProviderLocked(ProcessRecord proc,
9745 ContentProviderRecord cpr) {
9746 synchronized (cpr) {
9747 cpr.launchingApp = null;
9748 cpr.notifyAll();
9749 }
9750
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009751 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009752 String names[] = cpr.info.authority.split(";");
9753 for (int j = 0; j < names.length; j++) {
9754 mProvidersByName.remove(names[j]);
9755 }
9756
9757 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9758 while (cit.hasNext()) {
9759 ProcessRecord capp = cit.next();
9760 if (!capp.persistent && capp.thread != null
9761 && capp.pid != 0
9762 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009763 Slog.i(TAG, "Kill " + capp.processName
9764 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009765 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009766 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009767 capp.processName, capp.setAdj, "dying provider "
9768 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009769 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009770 }
9771 }
9772
9773 mLaunchingProviders.remove(cpr);
9774 }
9775
9776 /**
9777 * Main code for cleaning up a process when it has gone away. This is
9778 * called both as a result of the process dying, or directly when stopping
9779 * a process when running in single process mode.
9780 */
9781 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009782 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009783 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009784 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009785 }
9786
Dianne Hackborn36124872009-10-08 16:22:03 -07009787 mProcessesToGc.remove(app);
9788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009789 // Dismiss any open dialogs.
9790 if (app.crashDialog != null) {
9791 app.crashDialog.dismiss();
9792 app.crashDialog = null;
9793 }
9794 if (app.anrDialog != null) {
9795 app.anrDialog.dismiss();
9796 app.anrDialog = null;
9797 }
9798 if (app.waitDialog != null) {
9799 app.waitDialog.dismiss();
9800 app.waitDialog = null;
9801 }
9802
9803 app.crashing = false;
9804 app.notResponding = false;
9805
9806 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009807 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009808 app.thread = null;
9809 app.forcingToForeground = null;
9810 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009811 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009812 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009813 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009815 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816
9817 boolean restart = false;
9818
9819 int NL = mLaunchingProviders.size();
9820
9821 // Remove published content providers.
9822 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009823 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009824 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009825 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009826 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009827 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828
9829 // See if someone is waiting for this provider... in which
9830 // case we don't remove it, but just let it restart.
9831 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009832 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009833 for (; i<NL; i++) {
9834 if (mLaunchingProviders.get(i) == cpr) {
9835 restart = true;
9836 break;
9837 }
9838 }
9839 } else {
9840 i = NL;
9841 }
9842
9843 if (i >= NL) {
9844 removeDyingProviderLocked(app, cpr);
9845 NL = mLaunchingProviders.size();
9846 }
9847 }
9848 app.pubProviders.clear();
9849 }
9850
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009851 // Take care of any launching providers waiting for this process.
9852 if (checkAppInLaunchingProvidersLocked(app, false)) {
9853 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 // Unregister from connected content providers.
9857 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009858 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 while (it.hasNext()) {
9860 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9861 cpr.clients.remove(app);
9862 }
9863 app.conProviders.clear();
9864 }
9865
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009866 // At this point there may be remaining entries in mLaunchingProviders
9867 // where we were the only one waiting, so they are no longer of use.
9868 // Look for these and clean up if found.
9869 // XXX Commented out for now. Trying to figure out a way to reproduce
9870 // the actual situation to identify what is actually going on.
9871 if (false) {
9872 for (int i=0; i<NL; i++) {
9873 ContentProviderRecord cpr = (ContentProviderRecord)
9874 mLaunchingProviders.get(i);
9875 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9876 synchronized (cpr) {
9877 cpr.launchingApp = null;
9878 cpr.notifyAll();
9879 }
9880 }
9881 }
9882 }
9883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009884 skipCurrentReceiverLocked(app);
9885
9886 // Unregister any receivers.
9887 if (app.receivers.size() > 0) {
9888 Iterator<ReceiverList> it = app.receivers.iterator();
9889 while (it.hasNext()) {
9890 removeReceiverLocked(it.next());
9891 }
9892 app.receivers.clear();
9893 }
9894
Christopher Tate181fafa2009-05-14 11:12:14 -07009895 // If the app is undergoing backup, tell the backup manager about it
9896 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009897 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009898 try {
9899 IBackupManager bm = IBackupManager.Stub.asInterface(
9900 ServiceManager.getService(Context.BACKUP_SERVICE));
9901 bm.agentDisconnected(app.info.packageName);
9902 } catch (RemoteException e) {
9903 // can't happen; backup manager is local
9904 }
9905 }
9906
Jeff Sharkey287bd832011-05-28 19:36:26 -07009907 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 // If the caller is restarting this app, then leave it in its
9910 // current lists and let the caller take care of it.
9911 if (restarting) {
9912 return;
9913 }
9914
9915 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009916 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009917 "Removing non-persistent process during cleanup: " + app);
9918 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009919 if (mHeavyWeightProcess == app) {
9920 mHeavyWeightProcess = null;
9921 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009923 } else if (!app.removed) {
9924 // This app is persistent, so we need to keep its record around.
9925 // If it is not already on the pending app list, add it there
9926 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9928 mPersistentStartingProcesses.add(app);
9929 restart = true;
9930 }
9931 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009932 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9933 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 mProcessesOnHold.remove(app);
9935
The Android Open Source Project4df24232009-03-05 14:34:35 -08009936 if (app == mHomeProcess) {
9937 mHomeProcess = null;
9938 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009939 if (app == mPreviousProcess) {
9940 mPreviousProcess = null;
9941 }
9942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009943 if (restart) {
9944 // We have components that still need to be running in the
9945 // process, so re-launch it.
9946 mProcessNames.put(app.processName, app.info.uid, app);
9947 startProcessLocked(app, "restart", app.processName);
9948 } else if (app.pid > 0 && app.pid != MY_PID) {
9949 // Goodbye!
9950 synchronized (mPidsSelfLocked) {
9951 mPidsSelfLocked.remove(app.pid);
9952 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9953 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009954 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009955 }
9956 }
9957
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009958 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9959 // Look through the content providers we are waiting to have launched,
9960 // and if any run in this process then either schedule a restart of
9961 // the process or kill the client waiting for it if this process has
9962 // gone bad.
9963 int NL = mLaunchingProviders.size();
9964 boolean restart = false;
9965 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009966 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009967 if (cpr.launchingApp == app) {
9968 if (!alwaysBad && !app.bad) {
9969 restart = true;
9970 } else {
9971 removeDyingProviderLocked(app, cpr);
9972 NL = mLaunchingProviders.size();
9973 }
9974 }
9975 }
9976 return restart;
9977 }
9978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979 // =========================================================
9980 // SERVICES
9981 // =========================================================
9982
9983 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9984 ActivityManager.RunningServiceInfo info =
9985 new ActivityManager.RunningServiceInfo();
9986 info.service = r.name;
9987 if (r.app != null) {
9988 info.pid = r.app.pid;
9989 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009990 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009991 info.process = r.processName;
9992 info.foreground = r.isForeground;
9993 info.activeSince = r.createTime;
9994 info.started = r.startRequested;
9995 info.clientCount = r.connections.size();
9996 info.crashCount = r.crashCount;
9997 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009998 if (r.isForeground) {
9999 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10000 }
10001 if (r.startRequested) {
10002 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10003 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010004 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010005 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10006 }
10007 if (r.app != null && r.app.persistent) {
10008 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10009 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010010
10011 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10012 for (int i=0; i<connl.size(); i++) {
10013 ConnectionRecord conn = connl.get(i);
10014 if (conn.clientLabel != 0) {
10015 info.clientPackage = conn.binding.client.info.packageName;
10016 info.clientLabel = conn.clientLabel;
10017 return info;
10018 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010019 }
10020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010021 return info;
10022 }
10023
10024 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10025 int flags) {
10026 synchronized (this) {
10027 ArrayList<ActivityManager.RunningServiceInfo> res
10028 = new ArrayList<ActivityManager.RunningServiceInfo>();
10029
10030 if (mServices.size() > 0) {
10031 Iterator<ServiceRecord> it = mServices.values().iterator();
10032 while (it.hasNext() && res.size() < maxNum) {
10033 res.add(makeRunningServiceInfoLocked(it.next()));
10034 }
10035 }
10036
10037 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10038 ServiceRecord r = mRestartingServices.get(i);
10039 ActivityManager.RunningServiceInfo info =
10040 makeRunningServiceInfoLocked(r);
10041 info.restarting = r.nextRestartTime;
10042 res.add(info);
10043 }
10044
10045 return res;
10046 }
10047 }
10048
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010049 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10050 synchronized (this) {
10051 ServiceRecord r = mServices.get(name);
10052 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010053 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10054 for (int i=0; i<conn.size(); i++) {
10055 if (conn.get(i).clientIntent != null) {
10056 return conn.get(i).clientIntent;
10057 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010058 }
10059 }
10060 }
10061 }
10062 return null;
10063 }
10064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 private final ServiceRecord findServiceLocked(ComponentName name,
10066 IBinder token) {
10067 ServiceRecord r = mServices.get(name);
10068 return r == token ? r : null;
10069 }
10070
10071 private final class ServiceLookupResult {
10072 final ServiceRecord record;
10073 final String permission;
10074
10075 ServiceLookupResult(ServiceRecord _record, String _permission) {
10076 record = _record;
10077 permission = _permission;
10078 }
10079 };
10080
10081 private ServiceLookupResult findServiceLocked(Intent service,
10082 String resolvedType) {
10083 ServiceRecord r = null;
10084 if (service.getComponent() != null) {
10085 r = mServices.get(service.getComponent());
10086 }
10087 if (r == null) {
10088 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10089 r = mServicesByIntent.get(filter);
10090 }
10091
10092 if (r == null) {
10093 try {
10094 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010095 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010096 service, resolvedType, 0);
10097 ServiceInfo sInfo =
10098 rInfo != null ? rInfo.serviceInfo : null;
10099 if (sInfo == null) {
10100 return null;
10101 }
10102
10103 ComponentName name = new ComponentName(
10104 sInfo.applicationInfo.packageName, sInfo.name);
10105 r = mServices.get(name);
10106 } catch (RemoteException ex) {
10107 // pm is in same process, this will never happen.
10108 }
10109 }
10110 if (r != null) {
10111 int callingPid = Binder.getCallingPid();
10112 int callingUid = Binder.getCallingUid();
10113 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010114 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010115 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010116 if (!r.exported) {
10117 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10118 + " from pid=" + callingPid
10119 + ", uid=" + callingUid
10120 + " that is not exported from uid " + r.appInfo.uid);
10121 return new ServiceLookupResult(null, "not exported from uid "
10122 + r.appInfo.uid);
10123 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010124 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 + " from pid=" + callingPid
10126 + ", uid=" + callingUid
10127 + " requires " + r.permission);
10128 return new ServiceLookupResult(null, r.permission);
10129 }
10130 return new ServiceLookupResult(r, null);
10131 }
10132 return null;
10133 }
10134
10135 private class ServiceRestarter implements Runnable {
10136 private ServiceRecord mService;
10137
10138 void setService(ServiceRecord service) {
10139 mService = service;
10140 }
10141
10142 public void run() {
10143 synchronized(ActivityManagerService.this) {
10144 performServiceRestartLocked(mService);
10145 }
10146 }
10147 }
10148
10149 private ServiceLookupResult retrieveServiceLocked(Intent service,
10150 String resolvedType, int callingPid, int callingUid) {
10151 ServiceRecord r = null;
10152 if (service.getComponent() != null) {
10153 r = mServices.get(service.getComponent());
10154 }
10155 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10156 r = mServicesByIntent.get(filter);
10157 if (r == null) {
10158 try {
10159 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010160 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010161 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010162 ServiceInfo sInfo =
10163 rInfo != null ? rInfo.serviceInfo : null;
10164 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010165 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010166 ": not found");
10167 return null;
10168 }
10169
10170 ComponentName name = new ComponentName(
10171 sInfo.applicationInfo.packageName, sInfo.name);
10172 r = mServices.get(name);
10173 if (r == null) {
10174 filter = new Intent.FilterComparison(service.cloneFilter());
10175 ServiceRestarter res = new ServiceRestarter();
10176 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10177 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10178 synchronized (stats) {
10179 ss = stats.getServiceStatsLocked(
10180 sInfo.applicationInfo.uid, sInfo.packageName,
10181 sInfo.name);
10182 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010183 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 res.setService(r);
10185 mServices.put(name, r);
10186 mServicesByIntent.put(filter, r);
10187
10188 // Make sure this component isn't in the pending list.
10189 int N = mPendingServices.size();
10190 for (int i=0; i<N; i++) {
10191 ServiceRecord pr = mPendingServices.get(i);
10192 if (pr.name.equals(name)) {
10193 mPendingServices.remove(i);
10194 i--;
10195 N--;
10196 }
10197 }
10198 }
10199 } catch (RemoteException ex) {
10200 // pm is in same process, this will never happen.
10201 }
10202 }
10203 if (r != null) {
10204 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010205 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010207 if (!r.exported) {
10208 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10209 + " from pid=" + callingPid
10210 + ", uid=" + callingUid
10211 + " that is not exported from uid " + r.appInfo.uid);
10212 return new ServiceLookupResult(null, "not exported from uid "
10213 + r.appInfo.uid);
10214 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010215 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010216 + " from pid=" + callingPid
10217 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010218 + " requires " + r.permission);
10219 return new ServiceLookupResult(null, r.permission);
10220 }
10221 return new ServiceLookupResult(r, null);
10222 }
10223 return null;
10224 }
10225
Dianne Hackborn287952c2010-09-22 22:34:31 -070010226 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10227 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10228 + why + " of " + r + " in app " + r.app);
10229 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10230 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010231 long now = SystemClock.uptimeMillis();
10232 if (r.executeNesting == 0 && r.app != null) {
10233 if (r.app.executingServices.size() == 0) {
10234 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10235 msg.obj = r.app;
10236 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10237 }
10238 r.app.executingServices.add(r);
10239 }
10240 r.executeNesting++;
10241 r.executingStart = now;
10242 }
10243
10244 private final void sendServiceArgsLocked(ServiceRecord r,
10245 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010246 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 if (N == 0) {
10248 return;
10249 }
10250
Dianne Hackborn39792d22010-08-19 18:01:52 -070010251 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010252 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010253 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010254 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10255 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010256 if (si.intent == null && N > 1) {
10257 // If somehow we got a dummy null intent in the middle,
10258 // then skip it. DO NOT skip a null intent when it is
10259 // the only one in the list -- this is to support the
10260 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010261 continue;
10262 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010263 si.deliveredTime = SystemClock.uptimeMillis();
10264 r.deliveredStarts.add(si);
10265 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010266 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010267 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010268 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010269 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010270 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 if (!oomAdjusted) {
10272 oomAdjusted = true;
10273 updateOomAdjLocked(r.app);
10274 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010275 int flags = 0;
10276 if (si.deliveryCount > 0) {
10277 flags |= Service.START_FLAG_RETRY;
10278 }
10279 if (si.doneExecutingCount > 0) {
10280 flags |= Service.START_FLAG_REDELIVERY;
10281 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010282 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010283 } catch (RemoteException e) {
10284 // Remote process gone... we'll let the normal cleanup take
10285 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010286 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010287 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010289 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010290 break;
10291 }
10292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 }
10294
10295 private final boolean requestServiceBindingLocked(ServiceRecord r,
10296 IntentBindRecord i, boolean rebind) {
10297 if (r.app == null || r.app.thread == null) {
10298 // If service is not currently running, can't yet bind.
10299 return false;
10300 }
10301 if ((!i.requested || rebind) && i.apps.size() > 0) {
10302 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010303 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10305 if (!rebind) {
10306 i.requested = true;
10307 }
10308 i.hasBound = true;
10309 i.doRebind = false;
10310 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010311 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 return false;
10313 }
10314 }
10315 return true;
10316 }
10317
10318 private final void requestServiceBindingsLocked(ServiceRecord r) {
10319 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10320 while (bindings.hasNext()) {
10321 IntentBindRecord i = bindings.next();
10322 if (!requestServiceBindingLocked(r, i, false)) {
10323 break;
10324 }
10325 }
10326 }
10327
10328 private final void realStartServiceLocked(ServiceRecord r,
10329 ProcessRecord app) throws RemoteException {
10330 if (app.thread == null) {
10331 throw new RemoteException();
10332 }
10333
10334 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010335 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336
10337 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010338 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010339 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010340
10341 boolean created = false;
10342 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010343 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010344 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010345 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010347 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010348 synchronized (r.stats.getBatteryStats()) {
10349 r.stats.startLaunchedLocked();
10350 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010351 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010352 app.thread.scheduleCreateService(r, r.serviceInfo,
10353 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010354 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010355 created = true;
10356 } finally {
10357 if (!created) {
10358 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010359 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010360 }
10361 }
10362
10363 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010364
10365 // If the service is in the started state, and there are no
10366 // pending arguments, then fake up one so its onStartCommand() will
10367 // be called.
10368 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010369 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10370 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010371 }
10372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010373 sendServiceArgsLocked(r, true);
10374 }
10375
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010376 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10377 boolean allowCancel) {
10378 boolean canceled = false;
10379
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010380 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010381 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010382 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010383
Dianne Hackborn070783f2010-12-29 16:46:28 -080010384 if ((r.serviceInfo.applicationInfo.flags
10385 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10386 minDuration /= 4;
10387 }
10388
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010389 // Any delivered but not yet finished starts should be put back
10390 // on the pending list.
10391 final int N = r.deliveredStarts.size();
10392 if (N > 0) {
10393 for (int i=N-1; i>=0; i--) {
10394 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010395 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010396 if (si.intent == null) {
10397 // We'll generate this again if needed.
10398 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10399 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10400 r.pendingStarts.add(0, si);
10401 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10402 dur *= 2;
10403 if (minDuration < dur) minDuration = dur;
10404 if (resetTime < dur) resetTime = dur;
10405 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010406 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010407 + r.name);
10408 canceled = true;
10409 }
10410 }
10411 r.deliveredStarts.clear();
10412 }
10413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010414 r.totalRestartCount++;
10415 if (r.restartDelay == 0) {
10416 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010417 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010418 } else {
10419 // If it has been a "reasonably long time" since the service
10420 // was started, then reset our restart duration back to
10421 // the beginning, so we don't infinitely increase the duration
10422 // on a service that just occasionally gets killed (which is
10423 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010424 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010425 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010426 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010428 if ((r.serviceInfo.applicationInfo.flags
10429 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10430 // Services in peristent processes will restart much more
10431 // quickly, since they are pretty important. (Think SystemUI).
10432 r.restartDelay += minDuration/2;
10433 } else {
10434 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10435 if (r.restartDelay < minDuration) {
10436 r.restartDelay = minDuration;
10437 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010439 }
10440 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010441
10442 r.nextRestartTime = now + r.restartDelay;
10443
10444 // Make sure that we don't end up restarting a bunch of services
10445 // all at the same time.
10446 boolean repeat;
10447 do {
10448 repeat = false;
10449 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10450 ServiceRecord r2 = mRestartingServices.get(i);
10451 if (r2 != r && r.nextRestartTime
10452 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10453 && r.nextRestartTime
10454 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10455 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10456 r.restartDelay = r.nextRestartTime - now;
10457 repeat = true;
10458 break;
10459 }
10460 }
10461 } while (repeat);
10462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010463 if (!mRestartingServices.contains(r)) {
10464 mRestartingServices.add(r);
10465 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010466
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010467 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010470 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010472 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010474 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010475 r.shortName, r.restartDelay);
10476
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010477 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 }
10479
10480 final void performServiceRestartLocked(ServiceRecord r) {
10481 if (!mRestartingServices.contains(r)) {
10482 return;
10483 }
10484 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10485 }
10486
10487 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10488 if (r.restartDelay == 0) {
10489 return false;
10490 }
10491 r.resetRestartCounter();
10492 mRestartingServices.remove(r);
10493 mHandler.removeCallbacks(r.restarter);
10494 return true;
10495 }
10496
10497 private final boolean bringUpServiceLocked(ServiceRecord r,
10498 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010499 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010500 //r.dump(" ");
10501
Dianne Hackborn36124872009-10-08 16:22:03 -070010502 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010503 sendServiceArgsLocked(r, false);
10504 return true;
10505 }
10506
10507 if (!whileRestarting && r.restartDelay > 0) {
10508 // If waiting for a restart, then do nothing.
10509 return true;
10510 }
10511
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010512 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010513
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010514 // We are now bringing the service up, so no longer in the
10515 // restarting state.
10516 mRestartingServices.remove(r);
10517
Dianne Hackborne7f97212011-02-24 14:40:20 -080010518 // Service is now being launched, its package can't be stopped.
10519 try {
10520 AppGlobals.getPackageManager().setPackageStoppedState(
10521 r.packageName, false);
10522 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010523 } catch (IllegalArgumentException e) {
10524 Slog.w(TAG, "Failed trying to unstop package "
10525 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010526 }
10527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010528 final String appName = r.processName;
10529 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10530 if (app != null && app.thread != null) {
10531 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010532 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010533 realStartServiceLocked(r, app);
10534 return true;
10535 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010536 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010537 }
10538
10539 // If a dead object exception was thrown -- fall through to
10540 // restart the application.
10541 }
10542
Dianne Hackborn36124872009-10-08 16:22:03 -070010543 // Not running -- get it started, and enqueue this service record
10544 // to be executed when the app comes up.
10545 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10546 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010547 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010548 + r.appInfo.packageName + "/"
10549 + r.appInfo.uid + " for service "
10550 + r.intent.getIntent() + ": process is bad");
10551 bringDownServiceLocked(r, true);
10552 return false;
10553 }
10554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010556 mPendingServices.add(r);
10557 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010559 return true;
10560 }
10561
10562 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010563 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010564 //r.dump(" ");
10565
10566 // Does it still need to run?
10567 if (!force && r.startRequested) {
10568 return;
10569 }
10570 if (r.connections.size() > 0) {
10571 if (!force) {
10572 // XXX should probably keep a count of the number of auto-create
10573 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010574 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010575 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010576 ArrayList<ConnectionRecord> cr = it.next();
10577 for (int i=0; i<cr.size(); i++) {
10578 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10579 return;
10580 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010581 }
10582 }
10583 }
10584
10585 // Report to all of the connections that the service is no longer
10586 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010587 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010588 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010589 ArrayList<ConnectionRecord> c = it.next();
10590 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010591 ConnectionRecord cr = c.get(i);
10592 // There is still a connection to the service that is
10593 // being brought down. Mark it as dead.
10594 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010595 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010596 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010597 } catch (Exception e) {
10598 Slog.w(TAG, "Failure disconnecting service " + r.name +
10599 " to connection " + c.get(i).conn.asBinder() +
10600 " (in " + c.get(i).binding.client.processName + ")", e);
10601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010602 }
10603 }
10604 }
10605
10606 // Tell the service that it has been unbound.
10607 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10608 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10609 while (it.hasNext()) {
10610 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010611 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010612 + ": hasBound=" + ibr.hasBound);
10613 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10614 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010615 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010616 updateOomAdjLocked(r.app);
10617 ibr.hasBound = false;
10618 r.app.thread.scheduleUnbindService(r,
10619 ibr.intent.getIntent());
10620 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010621 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010622 + r.shortName, e);
10623 serviceDoneExecutingLocked(r, true);
10624 }
10625 }
10626 }
10627 }
10628
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010629 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010630 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010631 System.identityHashCode(r), r.shortName,
10632 (r.app != null) ? r.app.pid : -1);
10633
10634 mServices.remove(r.name);
10635 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636 r.totalRestartCount = 0;
10637 unscheduleServiceRestartLocked(r);
10638
10639 // Also make sure it is not on the pending list.
10640 int N = mPendingServices.size();
10641 for (int i=0; i<N; i++) {
10642 if (mPendingServices.get(i) == r) {
10643 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010644 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010645 i--;
10646 N--;
10647 }
10648 }
10649
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010650 r.cancelNotification();
10651 r.isForeground = false;
10652 r.foregroundId = 0;
10653 r.foregroundNoti = null;
10654
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010655 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010656 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010657 r.pendingStarts.clear();
10658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 if (r.app != null) {
10660 synchronized (r.stats.getBatteryStats()) {
10661 r.stats.stopLaunchedLocked();
10662 }
10663 r.app.services.remove(r);
10664 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010665 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010666 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667 mStoppingServices.add(r);
10668 updateOomAdjLocked(r.app);
10669 r.app.thread.scheduleStopService(r);
10670 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010671 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010672 + r.shortName, e);
10673 serviceDoneExecutingLocked(r, true);
10674 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010675 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010677 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010678 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010679 }
10680 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010681 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010682 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010684
10685 if (r.bindings.size() > 0) {
10686 r.bindings.clear();
10687 }
10688
10689 if (r.restarter instanceof ServiceRestarter) {
10690 ((ServiceRestarter)r.restarter).setService(null);
10691 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010692 }
10693
10694 ComponentName startServiceLocked(IApplicationThread caller,
10695 Intent service, String resolvedType,
10696 int callingPid, int callingUid) {
10697 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010698 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010699 + " type=" + resolvedType + " args=" + service.getExtras());
10700
10701 if (caller != null) {
10702 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10703 if (callerApp == null) {
10704 throw new SecurityException(
10705 "Unable to find app for caller " + caller
10706 + " (pid=" + Binder.getCallingPid()
10707 + ") when starting service " + service);
10708 }
10709 }
10710
10711 ServiceLookupResult res =
10712 retrieveServiceLocked(service, resolvedType,
10713 callingPid, callingUid);
10714 if (res == null) {
10715 return null;
10716 }
10717 if (res.record == null) {
10718 return new ComponentName("!", res.permission != null
10719 ? res.permission : "private to package");
10720 }
10721 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010722 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10723 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010725 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 }
10727 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010728 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010729 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010730 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010731 r.lastActivity = SystemClock.uptimeMillis();
10732 synchronized (r.stats.getBatteryStats()) {
10733 r.stats.startRunningLocked();
10734 }
10735 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10736 return new ComponentName("!", "Service process is bad");
10737 }
10738 return r.name;
10739 }
10740 }
10741
10742 public ComponentName startService(IApplicationThread caller, Intent service,
10743 String resolvedType) {
10744 // Refuse possible leaked file descriptors
10745 if (service != null && service.hasFileDescriptors() == true) {
10746 throw new IllegalArgumentException("File descriptors passed in Intent");
10747 }
10748
10749 synchronized(this) {
10750 final int callingPid = Binder.getCallingPid();
10751 final int callingUid = Binder.getCallingUid();
10752 final long origId = Binder.clearCallingIdentity();
10753 ComponentName res = startServiceLocked(caller, service,
10754 resolvedType, callingPid, callingUid);
10755 Binder.restoreCallingIdentity(origId);
10756 return res;
10757 }
10758 }
10759
10760 ComponentName startServiceInPackage(int uid,
10761 Intent service, String resolvedType) {
10762 synchronized(this) {
10763 final long origId = Binder.clearCallingIdentity();
10764 ComponentName res = startServiceLocked(null, service,
10765 resolvedType, -1, uid);
10766 Binder.restoreCallingIdentity(origId);
10767 return res;
10768 }
10769 }
10770
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010771 private void stopServiceLocked(ServiceRecord service) {
10772 synchronized (service.stats.getBatteryStats()) {
10773 service.stats.stopRunningLocked();
10774 }
10775 service.startRequested = false;
10776 service.callStart = false;
10777 bringDownServiceLocked(service, false);
10778 }
10779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010780 public int stopService(IApplicationThread caller, Intent service,
10781 String resolvedType) {
10782 // Refuse possible leaked file descriptors
10783 if (service != null && service.hasFileDescriptors() == true) {
10784 throw new IllegalArgumentException("File descriptors passed in Intent");
10785 }
10786
10787 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010788 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010789 + " type=" + resolvedType);
10790
10791 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10792 if (caller != null && callerApp == null) {
10793 throw new SecurityException(
10794 "Unable to find app for caller " + caller
10795 + " (pid=" + Binder.getCallingPid()
10796 + ") when stopping service " + service);
10797 }
10798
10799 // If this service is active, make sure it is stopped.
10800 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10801 if (r != null) {
10802 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010803 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010804 try {
10805 stopServiceLocked(r.record);
10806 } finally {
10807 Binder.restoreCallingIdentity(origId);
10808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809 return 1;
10810 }
10811 return -1;
10812 }
10813 }
10814
10815 return 0;
10816 }
10817
10818 public IBinder peekService(Intent service, String resolvedType) {
10819 // Refuse possible leaked file descriptors
10820 if (service != null && service.hasFileDescriptors() == true) {
10821 throw new IllegalArgumentException("File descriptors passed in Intent");
10822 }
10823
10824 IBinder ret = null;
10825
10826 synchronized(this) {
10827 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10828
10829 if (r != null) {
10830 // r.record is null if findServiceLocked() failed the caller permission check
10831 if (r.record == null) {
10832 throw new SecurityException(
10833 "Permission Denial: Accessing service " + r.record.name
10834 + " from pid=" + Binder.getCallingPid()
10835 + ", uid=" + Binder.getCallingUid()
10836 + " requires " + r.permission);
10837 }
10838 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10839 if (ib != null) {
10840 ret = ib.binder;
10841 }
10842 }
10843 }
10844
10845 return ret;
10846 }
10847
10848 public boolean stopServiceToken(ComponentName className, IBinder token,
10849 int startId) {
10850 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010851 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010852 + " " + token + " startId=" + startId);
10853 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010854 if (r != null) {
10855 if (startId >= 0) {
10856 // Asked to only stop if done with all work. Note that
10857 // to avoid leaks, we will take this as dropping all
10858 // start items up to and including this one.
10859 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10860 if (si != null) {
10861 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010862 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10863 cur.removeUriPermissionsLocked();
10864 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010865 break;
10866 }
10867 }
10868 }
10869
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010870 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010871 return false;
10872 }
10873
10874 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010875 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010876 + " is last, but have " + r.deliveredStarts.size()
10877 + " remaining args");
10878 }
10879 }
10880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 synchronized (r.stats.getBatteryStats()) {
10882 r.stats.stopRunningLocked();
10883 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010884 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010885 }
10886 final long origId = Binder.clearCallingIdentity();
10887 bringDownServiceLocked(r, false);
10888 Binder.restoreCallingIdentity(origId);
10889 return true;
10890 }
10891 }
10892 return false;
10893 }
10894
10895 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010896 int id, Notification notification, boolean removeNotification) {
10897 final long origId = Binder.clearCallingIdentity();
10898 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 synchronized(this) {
10900 ServiceRecord r = findServiceLocked(className, token);
10901 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010902 if (id != 0) {
10903 if (notification == null) {
10904 throw new IllegalArgumentException("null notification");
10905 }
10906 if (r.foregroundId != id) {
10907 r.cancelNotification();
10908 r.foregroundId = id;
10909 }
10910 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10911 r.foregroundNoti = notification;
10912 r.isForeground = true;
10913 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010914 if (r.app != null) {
10915 updateServiceForegroundLocked(r.app, true);
10916 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010917 } else {
10918 if (r.isForeground) {
10919 r.isForeground = false;
10920 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010921 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010922 updateServiceForegroundLocked(r.app, true);
10923 }
10924 }
10925 if (removeNotification) {
10926 r.cancelNotification();
10927 r.foregroundId = 0;
10928 r.foregroundNoti = null;
10929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010930 }
10931 }
10932 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010933 } finally {
10934 Binder.restoreCallingIdentity(origId);
10935 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010936 }
10937
10938 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10939 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010940 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010941 if (sr.isForeground) {
10942 anyForeground = true;
10943 break;
10944 }
10945 }
10946 if (anyForeground != proc.foregroundServices) {
10947 proc.foregroundServices = anyForeground;
10948 if (oomAdj) {
10949 updateOomAdjLocked();
10950 }
10951 }
10952 }
10953
10954 public int bindService(IApplicationThread caller, IBinder token,
10955 Intent service, String resolvedType,
10956 IServiceConnection connection, int flags) {
10957 // Refuse possible leaked file descriptors
10958 if (service != null && service.hasFileDescriptors() == true) {
10959 throw new IllegalArgumentException("File descriptors passed in Intent");
10960 }
10961
10962 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010963 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964 + " type=" + resolvedType + " conn=" + connection.asBinder()
10965 + " flags=0x" + Integer.toHexString(flags));
10966 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10967 if (callerApp == null) {
10968 throw new SecurityException(
10969 "Unable to find app for caller " + caller
10970 + " (pid=" + Binder.getCallingPid()
10971 + ") when binding service " + service);
10972 }
10973
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010974 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010975 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010976 activity = mMainStack.isInStackLocked(token);
10977 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010978 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 return 0;
10980 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010981 }
10982
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010983 int clientLabel = 0;
10984 PendingIntent clientIntent = null;
10985
10986 if (callerApp.info.uid == Process.SYSTEM_UID) {
10987 // Hacky kind of thing -- allow system stuff to tell us
10988 // what they are, so we can report this elsewhere for
10989 // others to know why certain services are running.
10990 try {
10991 clientIntent = (PendingIntent)service.getParcelableExtra(
10992 Intent.EXTRA_CLIENT_INTENT);
10993 } catch (RuntimeException e) {
10994 }
10995 if (clientIntent != null) {
10996 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10997 if (clientLabel != 0) {
10998 // There are no useful extras in the intent, trash them.
10999 // System code calling with this stuff just needs to know
11000 // this will happen.
11001 service = service.cloneFilter();
11002 }
11003 }
11004 }
11005
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011006 ServiceLookupResult res =
11007 retrieveServiceLocked(service, resolvedType,
11008 Binder.getCallingPid(), Binder.getCallingUid());
11009 if (res == null) {
11010 return 0;
11011 }
11012 if (res.record == null) {
11013 return -1;
11014 }
11015 ServiceRecord s = res.record;
11016
11017 final long origId = Binder.clearCallingIdentity();
11018
11019 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011020 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011021 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011022 }
11023
11024 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11025 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011026 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011027
11028 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011029 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11030 if (clist == null) {
11031 clist = new ArrayList<ConnectionRecord>();
11032 s.connections.put(binder, clist);
11033 }
11034 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 b.connections.add(c);
11036 if (activity != null) {
11037 if (activity.connections == null) {
11038 activity.connections = new HashSet<ConnectionRecord>();
11039 }
11040 activity.connections.add(c);
11041 }
11042 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011043 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11044 b.client.hasAboveClient = true;
11045 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011046 clist = mServiceConnections.get(binder);
11047 if (clist == null) {
11048 clist = new ArrayList<ConnectionRecord>();
11049 mServiceConnections.put(binder, clist);
11050 }
11051 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011052
11053 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11054 s.lastActivity = SystemClock.uptimeMillis();
11055 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11056 return 0;
11057 }
11058 }
11059
11060 if (s.app != null) {
11061 // This could have made the service more important.
11062 updateOomAdjLocked(s.app);
11063 }
11064
Joe Onorato8a9b2202010-02-26 18:56:32 -080011065 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011066 + ": received=" + b.intent.received
11067 + " apps=" + b.intent.apps.size()
11068 + " doRebind=" + b.intent.doRebind);
11069
11070 if (s.app != null && b.intent.received) {
11071 // Service is already running, so we can immediately
11072 // publish the connection.
11073 try {
11074 c.conn.connected(s.name, b.intent.binder);
11075 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011076 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011077 + " to connection " + c.conn.asBinder()
11078 + " (in " + c.binding.client.processName + ")", e);
11079 }
11080
11081 // If this is the first app connected back to this binding,
11082 // and the service had previously asked to be told when
11083 // rebound, then do so.
11084 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11085 requestServiceBindingLocked(s, b.intent, true);
11086 }
11087 } else if (!b.intent.requested) {
11088 requestServiceBindingLocked(s, b.intent, false);
11089 }
11090
11091 Binder.restoreCallingIdentity(origId);
11092 }
11093
11094 return 1;
11095 }
11096
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011097 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011098 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 IBinder binder = c.conn.asBinder();
11100 AppBindRecord b = c.binding;
11101 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011102 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11103 if (clist != null) {
11104 clist.remove(c);
11105 if (clist.size() == 0) {
11106 s.connections.remove(binder);
11107 }
11108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011109 b.connections.remove(c);
11110 if (c.activity != null && c.activity != skipAct) {
11111 if (c.activity.connections != null) {
11112 c.activity.connections.remove(c);
11113 }
11114 }
11115 if (b.client != skipApp) {
11116 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011117 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11118 b.client.updateHasAboveClientLocked();
11119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011120 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011121 clist = mServiceConnections.get(binder);
11122 if (clist != null) {
11123 clist.remove(c);
11124 if (clist.size() == 0) {
11125 mServiceConnections.remove(binder);
11126 }
11127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128
11129 if (b.connections.size() == 0) {
11130 b.intent.apps.remove(b.client);
11131 }
11132
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011133 if (!c.serviceDead) {
11134 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11135 + ": shouldUnbind=" + b.intent.hasBound);
11136 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11137 && b.intent.hasBound) {
11138 try {
11139 bumpServiceExecutingLocked(s, "unbind");
11140 updateOomAdjLocked(s.app);
11141 b.intent.hasBound = false;
11142 // Assume the client doesn't want to know about a rebind;
11143 // we will deal with that later if it asks for one.
11144 b.intent.doRebind = false;
11145 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11146 } catch (Exception e) {
11147 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11148 serviceDoneExecutingLocked(s, true);
11149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011150 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011151
11152 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11153 bringDownServiceLocked(s, false);
11154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 }
11156 }
11157
11158 public boolean unbindService(IServiceConnection connection) {
11159 synchronized (this) {
11160 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011161 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011162 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11163 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011164 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 + connection.asBinder());
11166 return false;
11167 }
11168
11169 final long origId = Binder.clearCallingIdentity();
11170
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011171 while (clist.size() > 0) {
11172 ConnectionRecord r = clist.get(0);
11173 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011174
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011175 if (r.binding.service.app != null) {
11176 // This could have made the service less important.
11177 updateOomAdjLocked(r.binding.service.app);
11178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011179 }
11180
11181 Binder.restoreCallingIdentity(origId);
11182 }
11183
11184 return true;
11185 }
11186
11187 public void publishService(IBinder token, Intent intent, IBinder service) {
11188 // Refuse possible leaked file descriptors
11189 if (intent != null && intent.hasFileDescriptors() == true) {
11190 throw new IllegalArgumentException("File descriptors passed in Intent");
11191 }
11192
11193 synchronized(this) {
11194 if (!(token instanceof ServiceRecord)) {
11195 throw new IllegalArgumentException("Invalid service token");
11196 }
11197 ServiceRecord r = (ServiceRecord)token;
11198
11199 final long origId = Binder.clearCallingIdentity();
11200
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011201 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011202 + " " + intent + ": " + service);
11203 if (r != null) {
11204 Intent.FilterComparison filter
11205 = new Intent.FilterComparison(intent);
11206 IntentBindRecord b = r.bindings.get(filter);
11207 if (b != null && !b.received) {
11208 b.binder = service;
11209 b.requested = true;
11210 b.received = true;
11211 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011212 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011213 = r.connections.values().iterator();
11214 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011215 ArrayList<ConnectionRecord> clist = it.next();
11216 for (int i=0; i<clist.size(); i++) {
11217 ConnectionRecord c = clist.get(i);
11218 if (!filter.equals(c.binding.intent.intent)) {
11219 if (DEBUG_SERVICE) Slog.v(
11220 TAG, "Not publishing to: " + c);
11221 if (DEBUG_SERVICE) Slog.v(
11222 TAG, "Bound intent: " + c.binding.intent.intent);
11223 if (DEBUG_SERVICE) Slog.v(
11224 TAG, "Published intent: " + intent);
11225 continue;
11226 }
11227 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11228 try {
11229 c.conn.connected(r.name, service);
11230 } catch (Exception e) {
11231 Slog.w(TAG, "Failure sending service " + r.name +
11232 " to connection " + c.conn.asBinder() +
11233 " (in " + c.binding.client.processName + ")", e);
11234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011235 }
11236 }
11237 }
11238 }
11239
11240 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11241
11242 Binder.restoreCallingIdentity(origId);
11243 }
11244 }
11245 }
11246
11247 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11248 // Refuse possible leaked file descriptors
11249 if (intent != null && intent.hasFileDescriptors() == true) {
11250 throw new IllegalArgumentException("File descriptors passed in Intent");
11251 }
11252
11253 synchronized(this) {
11254 if (!(token instanceof ServiceRecord)) {
11255 throw new IllegalArgumentException("Invalid service token");
11256 }
11257 ServiceRecord r = (ServiceRecord)token;
11258
11259 final long origId = Binder.clearCallingIdentity();
11260
11261 if (r != null) {
11262 Intent.FilterComparison filter
11263 = new Intent.FilterComparison(intent);
11264 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011265 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011266 + " at " + b + ": apps="
11267 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011268
11269 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011270 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011271 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011272 // Applications have already bound since the last
11273 // unbind, so just rebind right here.
11274 requestServiceBindingLocked(r, b, true);
11275 } else {
11276 // Note to tell the service the next time there is
11277 // a new client.
11278 b.doRebind = true;
11279 }
11280 }
11281
Per Edelberg78f9fff2010-08-30 20:01:35 +020011282 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011283
11284 Binder.restoreCallingIdentity(origId);
11285 }
11286 }
11287 }
11288
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011289 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011290 synchronized(this) {
11291 if (!(token instanceof ServiceRecord)) {
11292 throw new IllegalArgumentException("Invalid service token");
11293 }
11294 ServiceRecord r = (ServiceRecord)token;
11295 boolean inStopping = mStoppingServices.contains(token);
11296 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011297 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011298 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 + " with incorrect token: given " + token
11300 + ", expected " + r);
11301 return;
11302 }
11303
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011304 if (type == 1) {
11305 // This is a call from a service start... take care of
11306 // book-keeping.
11307 r.callStart = true;
11308 switch (res) {
11309 case Service.START_STICKY_COMPATIBILITY:
11310 case Service.START_STICKY: {
11311 // We are done with the associated start arguments.
11312 r.findDeliveredStart(startId, true);
11313 // Don't stop if killed.
11314 r.stopIfKilled = false;
11315 break;
11316 }
11317 case Service.START_NOT_STICKY: {
11318 // We are done with the associated start arguments.
11319 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011320 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011321 // There is no more work, and this service
11322 // doesn't want to hang around if killed.
11323 r.stopIfKilled = true;
11324 }
11325 break;
11326 }
11327 case Service.START_REDELIVER_INTENT: {
11328 // We'll keep this item until they explicitly
11329 // call stop for it, but keep track of the fact
11330 // that it was delivered.
11331 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11332 if (si != null) {
11333 si.deliveryCount = 0;
11334 si.doneExecutingCount++;
11335 // Don't stop if killed.
11336 r.stopIfKilled = true;
11337 }
11338 break;
11339 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011340 case Service.START_TASK_REMOVED_COMPLETE: {
11341 // Special processing for onTaskRemoved(). Don't
11342 // impact normal onStartCommand() processing.
11343 r.findDeliveredStart(startId, true);
11344 break;
11345 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011346 default:
11347 throw new IllegalArgumentException(
11348 "Unknown service start result: " + res);
11349 }
11350 if (res == Service.START_STICKY_COMPATIBILITY) {
11351 r.callStart = false;
11352 }
11353 }
11354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011355 final long origId = Binder.clearCallingIdentity();
11356 serviceDoneExecutingLocked(r, inStopping);
11357 Binder.restoreCallingIdentity(origId);
11358 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011359 Slog.w(TAG, "Done executing unknown service from pid "
11360 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 }
11362 }
11363 }
11364
11365 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011366 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11367 + ": nesting=" + r.executeNesting
11368 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011369 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011370 r.executeNesting--;
11371 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011372 if (DEBUG_SERVICE) Slog.v(TAG,
11373 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011374 r.app.executingServices.remove(r);
11375 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011376 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11377 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11379 }
11380 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011381 if (DEBUG_SERVICE) Slog.v(TAG,
11382 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011383 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011384 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011385 }
11386 updateOomAdjLocked(r.app);
11387 }
11388 }
11389
11390 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011391 String anrMessage = null;
11392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011393 synchronized(this) {
11394 if (proc.executingServices.size() == 0 || proc.thread == null) {
11395 return;
11396 }
11397 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11398 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11399 ServiceRecord timeout = null;
11400 long nextTime = 0;
11401 while (it.hasNext()) {
11402 ServiceRecord sr = it.next();
11403 if (sr.executingStart < maxTime) {
11404 timeout = sr;
11405 break;
11406 }
11407 if (sr.executingStart > nextTime) {
11408 nextTime = sr.executingStart;
11409 }
11410 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011411 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011412 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011413 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011414 } else {
11415 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11416 msg.obj = proc;
11417 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11418 }
11419 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011420
11421 if (anrMessage != null) {
11422 appNotResponding(proc, null, null, anrMessage);
11423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011424 }
11425
11426 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011427 // BACKUP AND RESTORE
11428 // =========================================================
11429
11430 // Cause the target app to be launched if necessary and its backup agent
11431 // instantiated. The backup agent will invoke backupAgentCreated() on the
11432 // activity manager to announce its creation.
11433 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011434 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011435 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11436
11437 synchronized(this) {
11438 // !!! TODO: currently no check here that we're already bound
11439 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11440 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11441 synchronized (stats) {
11442 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11443 }
11444
Dianne Hackborne7f97212011-02-24 14:40:20 -080011445 // Backup agent is now in use, its package can't be stopped.
11446 try {
11447 AppGlobals.getPackageManager().setPackageStoppedState(
11448 app.packageName, false);
11449 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011450 } catch (IllegalArgumentException e) {
11451 Slog.w(TAG, "Failed trying to unstop package "
11452 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011453 }
11454
Christopher Tate181fafa2009-05-14 11:12:14 -070011455 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011456 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11457 ? new ComponentName(app.packageName, app.backupAgentName)
11458 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011459 // startProcessLocked() returns existing proc's record if it's already running
11460 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011461 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011462 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011463 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011464 return false;
11465 }
11466
11467 r.app = proc;
11468 mBackupTarget = r;
11469 mBackupAppName = app.packageName;
11470
Christopher Tate6fa95972009-06-05 18:43:55 -070011471 // Try not to kill the process during backup
11472 updateOomAdjLocked(proc);
11473
Christopher Tate181fafa2009-05-14 11:12:14 -070011474 // If the process is already attached, schedule the creation of the backup agent now.
11475 // If it is not yet live, this will be done when it attaches to the framework.
11476 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011477 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011478 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011479 proc.thread.scheduleCreateBackupAgent(app,
11480 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011481 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011482 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011483 }
11484 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011485 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011486 }
11487 // Invariants: at this point, the target app process exists and the application
11488 // is either already running or in the process of coming up. mBackupTarget and
11489 // mBackupAppName describe the app, so that when it binds back to the AM we
11490 // know that it's scheduled for a backup-agent operation.
11491 }
11492
11493 return true;
11494 }
11495
11496 // A backup agent has just come up
11497 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011498 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011499 + " = " + agent);
11500
11501 synchronized(this) {
11502 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011503 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011504 return;
11505 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011506 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011507
Dianne Hackborn06740692010-09-22 22:46:21 -070011508 long oldIdent = Binder.clearCallingIdentity();
11509 try {
11510 IBackupManager bm = IBackupManager.Stub.asInterface(
11511 ServiceManager.getService(Context.BACKUP_SERVICE));
11512 bm.agentConnected(agentPackageName, agent);
11513 } catch (RemoteException e) {
11514 // can't happen; the backup manager service is local
11515 } catch (Exception e) {
11516 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11517 e.printStackTrace();
11518 } finally {
11519 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011520 }
11521 }
11522
11523 // done with this agent
11524 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011525 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011526 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011527 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011528 return;
11529 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011530
11531 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011532 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011533 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011534 return;
11535 }
11536
Christopher Tate181fafa2009-05-14 11:12:14 -070011537 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011538 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011539 return;
11540 }
11541
Christopher Tate6fa95972009-06-05 18:43:55 -070011542 ProcessRecord proc = mBackupTarget.app;
11543 mBackupTarget = null;
11544 mBackupAppName = null;
11545
11546 // Not backing this app up any more; reset its OOM adjustment
11547 updateOomAdjLocked(proc);
11548
Christopher Tatec7b31e32009-06-10 15:49:30 -070011549 // If the app crashed during backup, 'thread' will be null here
11550 if (proc.thread != null) {
11551 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011552 proc.thread.scheduleDestroyBackupAgent(appInfo,
11553 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011554 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011555 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011556 e.printStackTrace();
11557 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011558 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011559 }
11560 }
11561 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011562 // BROADCASTS
11563 // =========================================================
11564
Josh Bartel7f208742010-02-25 11:01:44 -060011565 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011566 List cur) {
11567 final ContentResolver resolver = mContext.getContentResolver();
11568 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11569 if (list == null) {
11570 return cur;
11571 }
11572 int N = list.size();
11573 for (int i=0; i<N; i++) {
11574 Intent intent = list.get(i);
11575 if (filter.match(resolver, intent, true, TAG) >= 0) {
11576 if (cur == null) {
11577 cur = new ArrayList<Intent>();
11578 }
11579 cur.add(intent);
11580 }
11581 }
11582 return cur;
11583 }
11584
11585 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011586 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 + mBroadcastsScheduled);
11588
11589 if (mBroadcastsScheduled) {
11590 return;
11591 }
11592 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11593 mBroadcastsScheduled = true;
11594 }
11595
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011596 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011597 IIntentReceiver receiver, IntentFilter filter, String permission) {
11598 synchronized(this) {
11599 ProcessRecord callerApp = null;
11600 if (caller != null) {
11601 callerApp = getRecordForAppLocked(caller);
11602 if (callerApp == null) {
11603 throw new SecurityException(
11604 "Unable to find app for caller " + caller
11605 + " (pid=" + Binder.getCallingPid()
11606 + ") when registering receiver " + receiver);
11607 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011608 if (callerApp.info.uid != Process.SYSTEM_UID &&
11609 !callerApp.pkgList.contains(callerPackage)) {
11610 throw new SecurityException("Given caller package " + callerPackage
11611 + " is not running in process " + callerApp);
11612 }
11613 } else {
11614 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011615 }
11616
11617 List allSticky = null;
11618
11619 // Look for any matching sticky broadcasts...
11620 Iterator actions = filter.actionsIterator();
11621 if (actions != null) {
11622 while (actions.hasNext()) {
11623 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011624 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011625 }
11626 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011627 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011628 }
11629
11630 // The first sticky in the list is returned directly back to
11631 // the client.
11632 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11633
Joe Onorato8a9b2202010-02-26 18:56:32 -080011634 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635 + ": " + sticky);
11636
11637 if (receiver == null) {
11638 return sticky;
11639 }
11640
11641 ReceiverList rl
11642 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11643 if (rl == null) {
11644 rl = new ReceiverList(this, callerApp,
11645 Binder.getCallingPid(),
11646 Binder.getCallingUid(), receiver);
11647 if (rl.app != null) {
11648 rl.app.receivers.add(rl);
11649 } else {
11650 try {
11651 receiver.asBinder().linkToDeath(rl, 0);
11652 } catch (RemoteException e) {
11653 return sticky;
11654 }
11655 rl.linkedToDeath = true;
11656 }
11657 mRegisteredReceivers.put(receiver.asBinder(), rl);
11658 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011659 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011660 rl.add(bf);
11661 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011662 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011663 }
11664 mReceiverResolver.addFilter(bf);
11665
11666 // Enqueue broadcasts for all existing stickies that match
11667 // this filter.
11668 if (allSticky != null) {
11669 ArrayList receivers = new ArrayList();
11670 receivers.add(bf);
11671
11672 int N = allSticky.size();
11673 for (int i=0; i<N; i++) {
11674 Intent intent = (Intent)allSticky.get(i);
11675 BroadcastRecord r = new BroadcastRecord(intent, null,
11676 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011677 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011678 if (mParallelBroadcasts.size() == 0) {
11679 scheduleBroadcastsLocked();
11680 }
11681 mParallelBroadcasts.add(r);
11682 }
11683 }
11684
11685 return sticky;
11686 }
11687 }
11688
11689 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011690 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011691
11692 boolean doNext = false;
11693
11694 synchronized(this) {
11695 ReceiverList rl
11696 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11697 if (rl != null) {
11698 if (rl.curBroadcast != null) {
11699 BroadcastRecord r = rl.curBroadcast;
11700 doNext = finishReceiverLocked(
11701 receiver.asBinder(), r.resultCode, r.resultData,
11702 r.resultExtras, r.resultAbort, true);
11703 }
11704
11705 if (rl.app != null) {
11706 rl.app.receivers.remove(rl);
11707 }
11708 removeReceiverLocked(rl);
11709 if (rl.linkedToDeath) {
11710 rl.linkedToDeath = false;
11711 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11712 }
11713 }
11714 }
11715
11716 if (!doNext) {
11717 return;
11718 }
11719
11720 final long origId = Binder.clearCallingIdentity();
11721 processNextBroadcast(false);
11722 trimApplications();
11723 Binder.restoreCallingIdentity(origId);
11724 }
11725
11726 void removeReceiverLocked(ReceiverList rl) {
11727 mRegisteredReceivers.remove(rl.receiver.asBinder());
11728 int N = rl.size();
11729 for (int i=0; i<N; i++) {
11730 mReceiverResolver.removeFilter(rl.get(i));
11731 }
11732 }
11733
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011734 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11735 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11736 ProcessRecord r = mLruProcesses.get(i);
11737 if (r.thread != null) {
11738 try {
11739 r.thread.dispatchPackageBroadcast(cmd, packages);
11740 } catch (RemoteException ex) {
11741 }
11742 }
11743 }
11744 }
11745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 private final int broadcastIntentLocked(ProcessRecord callerApp,
11747 String callerPackage, Intent intent, String resolvedType,
11748 IIntentReceiver resultTo, int resultCode, String resultData,
11749 Bundle map, String requiredPermission,
11750 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11751 intent = new Intent(intent);
11752
Dianne Hackborne7f97212011-02-24 14:40:20 -080011753 // By default broadcasts do not go to stopped apps.
11754 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11755
Joe Onorato8a9b2202010-02-26 18:56:32 -080011756 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011757 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11758 + " ordered=" + ordered);
11759 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011760 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011761 }
11762
11763 // Handle special intents: if this broadcast is from the package
11764 // manager about a package being removed, we need to remove all of
11765 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011766 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011767 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011768 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11769 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011770 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011771 || uidRemoved) {
11772 if (checkComponentPermission(
11773 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011774 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 == PackageManager.PERMISSION_GRANTED) {
11776 if (uidRemoved) {
11777 final Bundle intentExtras = intent.getExtras();
11778 final int uid = intentExtras != null
11779 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11780 if (uid >= 0) {
11781 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11782 synchronized (bs) {
11783 bs.removeUidStatsLocked(uid);
11784 }
11785 }
11786 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011787 // If resources are unvailble just force stop all
11788 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011789 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011790 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11791 if (list != null && (list.length > 0)) {
11792 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011793 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011794 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011795 sendPackageBroadcastLocked(
11796 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011797 }
11798 } else {
11799 Uri data = intent.getData();
11800 String ssp;
11801 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11802 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11803 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011804 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011805 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011806 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011807 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11808 new String[] {ssp});
11809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011810 }
11811 }
11812 }
11813 } else {
11814 String msg = "Permission Denial: " + intent.getAction()
11815 + " broadcast from " + callerPackage + " (pid=" + callingPid
11816 + ", uid=" + callingUid + ")"
11817 + " requires "
11818 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011819 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011820 throw new SecurityException(msg);
11821 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011822
11823 // Special case for adding a package: by default turn on compatibility
11824 // mode.
11825 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011826 Uri data = intent.getData();
11827 String ssp;
11828 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11829 mCompatModePackages.handlePackageAddedLocked(ssp,
11830 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011832 }
11833
11834 /*
11835 * If this is the time zone changed action, queue up a message that will reset the timezone
11836 * of all currently running processes. This message will get queued up before the broadcast
11837 * happens.
11838 */
11839 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11840 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11841 }
11842
Robert Greenwalt03595d02010-11-02 14:08:23 -070011843 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11844 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11845 }
11846
Robert Greenwalt434203a2010-10-11 16:00:27 -070011847 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11848 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11849 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11850 }
11851
Dianne Hackborn854060af2009-07-09 18:14:31 -070011852 /*
11853 * Prevent non-system code (defined here to be non-persistent
11854 * processes) from sending protected broadcasts.
11855 */
11856 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11857 || callingUid == Process.SHELL_UID || callingUid == 0) {
11858 // Always okay.
11859 } else if (callerApp == null || !callerApp.persistent) {
11860 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011861 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011862 intent.getAction())) {
11863 String msg = "Permission Denial: not allowed to send broadcast "
11864 + intent.getAction() + " from pid="
11865 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011866 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011867 throw new SecurityException(msg);
11868 }
11869 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011870 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011871 return BROADCAST_SUCCESS;
11872 }
11873 }
11874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011875 // Add to the sticky list if requested.
11876 if (sticky) {
11877 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11878 callingPid, callingUid)
11879 != PackageManager.PERMISSION_GRANTED) {
11880 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11881 + callingPid + ", uid=" + callingUid
11882 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011883 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011884 throw new SecurityException(msg);
11885 }
11886 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011887 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011888 + " and enforce permission " + requiredPermission);
11889 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11890 }
11891 if (intent.getComponent() != null) {
11892 throw new SecurityException(
11893 "Sticky broadcasts can't target a specific component");
11894 }
11895 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11896 if (list == null) {
11897 list = new ArrayList<Intent>();
11898 mStickyBroadcasts.put(intent.getAction(), list);
11899 }
11900 int N = list.size();
11901 int i;
11902 for (i=0; i<N; i++) {
11903 if (intent.filterEquals(list.get(i))) {
11904 // This sticky already exists, replace it.
11905 list.set(i, new Intent(intent));
11906 break;
11907 }
11908 }
11909 if (i >= N) {
11910 list.add(new Intent(intent));
11911 }
11912 }
11913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 // Figure out who all will receive this broadcast.
11915 List receivers = null;
11916 List<BroadcastFilter> registeredReceivers = null;
11917 try {
11918 if (intent.getComponent() != null) {
11919 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011920 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011921 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011922 if (ai != null) {
11923 receivers = new ArrayList();
11924 ResolveInfo ri = new ResolveInfo();
11925 ri.activityInfo = ai;
11926 receivers.add(ri);
11927 }
11928 } else {
11929 // Need to resolve the intent to interested receivers...
11930 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11931 == 0) {
11932 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011933 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011934 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011935 }
Mihai Preda074edef2009-05-18 17:13:31 +020011936 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011937 }
11938 } catch (RemoteException ex) {
11939 // pm is in same process, this will never happen.
11940 }
11941
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011942 final boolean replacePending =
11943 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11944
Joe Onorato8a9b2202010-02-26 18:56:32 -080011945 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011946 + " replacePending=" + replacePending);
11947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011948 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11949 if (!ordered && NR > 0) {
11950 // If we are not serializing this broadcast, then send the
11951 // registered receivers separately so they don't wait for the
11952 // components to be launched.
11953 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11954 callerPackage, callingPid, callingUid, requiredPermission,
11955 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011956 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011957 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011958 TAG, "Enqueueing parallel broadcast " + r
11959 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011960 boolean replaced = false;
11961 if (replacePending) {
11962 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11963 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011964 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011965 "***** DROPPING PARALLEL: " + intent);
11966 mParallelBroadcasts.set(i, r);
11967 replaced = true;
11968 break;
11969 }
11970 }
11971 }
11972 if (!replaced) {
11973 mParallelBroadcasts.add(r);
11974 scheduleBroadcastsLocked();
11975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976 registeredReceivers = null;
11977 NR = 0;
11978 }
11979
11980 // Merge into one list.
11981 int ir = 0;
11982 if (receivers != null) {
11983 // A special case for PACKAGE_ADDED: do not allow the package
11984 // being added to see this broadcast. This prevents them from
11985 // using this as a back door to get run as soon as they are
11986 // installed. Maybe in the future we want to have a special install
11987 // broadcast or such for apps, but we'd like to deliberately make
11988 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011989 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011990 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11991 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11992 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011993 Uri data = intent.getData();
11994 if (data != null) {
11995 String pkgName = data.getSchemeSpecificPart();
11996 if (pkgName != null) {
11997 skipPackages = new String[] { pkgName };
11998 }
11999 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012000 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012001 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012002 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012003 if (skipPackages != null && (skipPackages.length > 0)) {
12004 for (String skipPackage : skipPackages) {
12005 if (skipPackage != null) {
12006 int NT = receivers.size();
12007 for (int it=0; it<NT; it++) {
12008 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12009 if (curt.activityInfo.packageName.equals(skipPackage)) {
12010 receivers.remove(it);
12011 it--;
12012 NT--;
12013 }
12014 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 }
12016 }
12017 }
12018
12019 int NT = receivers != null ? receivers.size() : 0;
12020 int it = 0;
12021 ResolveInfo curt = null;
12022 BroadcastFilter curr = null;
12023 while (it < NT && ir < NR) {
12024 if (curt == null) {
12025 curt = (ResolveInfo)receivers.get(it);
12026 }
12027 if (curr == null) {
12028 curr = registeredReceivers.get(ir);
12029 }
12030 if (curr.getPriority() >= curt.priority) {
12031 // Insert this broadcast record into the final list.
12032 receivers.add(it, curr);
12033 ir++;
12034 curr = null;
12035 it++;
12036 NT++;
12037 } else {
12038 // Skip to the next ResolveInfo in the final list.
12039 it++;
12040 curt = null;
12041 }
12042 }
12043 }
12044 while (ir < NR) {
12045 if (receivers == null) {
12046 receivers = new ArrayList();
12047 }
12048 receivers.add(registeredReceivers.get(ir));
12049 ir++;
12050 }
12051
12052 if ((receivers != null && receivers.size() > 0)
12053 || resultTo != null) {
12054 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12055 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012056 receivers, resultTo, resultCode, resultData, map, ordered,
12057 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012058 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012059 TAG, "Enqueueing ordered broadcast " + r
12060 + ": prev had " + mOrderedBroadcasts.size());
12061 if (DEBUG_BROADCAST) {
12062 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012063 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012064 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012065 boolean replaced = false;
12066 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012067 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012068 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012069 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012070 "***** DROPPING ORDERED: " + intent);
12071 mOrderedBroadcasts.set(i, r);
12072 replaced = true;
12073 break;
12074 }
12075 }
12076 }
12077 if (!replaced) {
12078 mOrderedBroadcasts.add(r);
12079 scheduleBroadcastsLocked();
12080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012081 }
12082
12083 return BROADCAST_SUCCESS;
12084 }
12085
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012086 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087 // Refuse possible leaked file descriptors
12088 if (intent != null && intent.hasFileDescriptors() == true) {
12089 throw new IllegalArgumentException("File descriptors passed in Intent");
12090 }
12091
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012092 int flags = intent.getFlags();
12093
12094 if (!mProcessesReady) {
12095 // if the caller really truly claims to know what they're doing, go
12096 // ahead and allow the broadcast without launching any receivers
12097 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12098 intent = new Intent(intent);
12099 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12100 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12101 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12102 + " before boot completion");
12103 throw new IllegalStateException("Cannot broadcast before boot completed");
12104 }
12105 }
12106
12107 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12108 throw new IllegalArgumentException(
12109 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12110 }
12111
12112 return intent;
12113 }
12114
12115 public final int broadcastIntent(IApplicationThread caller,
12116 Intent intent, String resolvedType, IIntentReceiver resultTo,
12117 int resultCode, String resultData, Bundle map,
12118 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012119 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012120 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012122 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12123 final int callingPid = Binder.getCallingPid();
12124 final int callingUid = Binder.getCallingUid();
12125 final long origId = Binder.clearCallingIdentity();
12126 int res = broadcastIntentLocked(callerApp,
12127 callerApp != null ? callerApp.info.packageName : null,
12128 intent, resolvedType, resultTo,
12129 resultCode, resultData, map, requiredPermission, serialized,
12130 sticky, callingPid, callingUid);
12131 Binder.restoreCallingIdentity(origId);
12132 return res;
12133 }
12134 }
12135
12136 int broadcastIntentInPackage(String packageName, int uid,
12137 Intent intent, String resolvedType, IIntentReceiver resultTo,
12138 int resultCode, String resultData, Bundle map,
12139 String requiredPermission, boolean serialized, boolean sticky) {
12140 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012141 intent = verifyBroadcastLocked(intent);
12142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012143 final long origId = Binder.clearCallingIdentity();
12144 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12145 resultTo, resultCode, resultData, map, requiredPermission,
12146 serialized, sticky, -1, uid);
12147 Binder.restoreCallingIdentity(origId);
12148 return res;
12149 }
12150 }
12151
12152 public final void unbroadcastIntent(IApplicationThread caller,
12153 Intent intent) {
12154 // Refuse possible leaked file descriptors
12155 if (intent != null && intent.hasFileDescriptors() == true) {
12156 throw new IllegalArgumentException("File descriptors passed in Intent");
12157 }
12158
12159 synchronized(this) {
12160 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12161 != PackageManager.PERMISSION_GRANTED) {
12162 String msg = "Permission Denial: unbroadcastIntent() from pid="
12163 + Binder.getCallingPid()
12164 + ", uid=" + Binder.getCallingUid()
12165 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012166 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012167 throw new SecurityException(msg);
12168 }
12169 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12170 if (list != null) {
12171 int N = list.size();
12172 int i;
12173 for (i=0; i<N; i++) {
12174 if (intent.filterEquals(list.get(i))) {
12175 list.remove(i);
12176 break;
12177 }
12178 }
12179 }
12180 }
12181 }
12182
12183 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12184 String resultData, Bundle resultExtras, boolean resultAbort,
12185 boolean explicit) {
12186 if (mOrderedBroadcasts.size() == 0) {
12187 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012188 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012189 }
12190 return false;
12191 }
12192 BroadcastRecord r = mOrderedBroadcasts.get(0);
12193 if (r.receiver == null) {
12194 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012195 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 }
12197 return false;
12198 }
12199 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012200 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 return false;
12202 }
12203 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012204 r.state = BroadcastRecord.IDLE;
12205 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012206 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012207 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012208 }
12209 }
12210 r.receiver = null;
12211 r.intent.setComponent(null);
12212 if (r.curApp != null) {
12213 r.curApp.curReceiver = null;
12214 }
12215 if (r.curFilter != null) {
12216 r.curFilter.receiverList.curBroadcast = null;
12217 }
12218 r.curFilter = null;
12219 r.curApp = null;
12220 r.curComponent = null;
12221 r.curReceiver = null;
12222 mPendingBroadcast = null;
12223
12224 r.resultCode = resultCode;
12225 r.resultData = resultData;
12226 r.resultExtras = resultExtras;
12227 r.resultAbort = resultAbort;
12228
12229 // We will process the next receiver right now if this is finishing
12230 // an app receiver (which is always asynchronous) or after we have
12231 // come back from calling a receiver.
12232 return state == BroadcastRecord.APP_RECEIVE
12233 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12234 }
12235
12236 public void finishReceiver(IBinder who, int resultCode, String resultData,
12237 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012238 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012239
12240 // Refuse possible leaked file descriptors
12241 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12242 throw new IllegalArgumentException("File descriptors passed in Bundle");
12243 }
12244
12245 boolean doNext;
12246
12247 final long origId = Binder.clearCallingIdentity();
12248
12249 synchronized(this) {
12250 doNext = finishReceiverLocked(
12251 who, resultCode, resultData, resultExtras, resultAbort, true);
12252 }
12253
12254 if (doNext) {
12255 processNextBroadcast(false);
12256 }
12257 trimApplications();
12258
12259 Binder.restoreCallingIdentity(origId);
12260 }
12261
Jeff Brown4d94a762010-09-23 11:33:28 -070012262 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012263 if (r.nextReceiver > 0) {
12264 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12265 if (curReceiver instanceof BroadcastFilter) {
12266 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012267 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 System.identityHashCode(r),
12269 r.intent.getAction(),
12270 r.nextReceiver - 1,
12271 System.identityHashCode(bf));
12272 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012273 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012274 System.identityHashCode(r),
12275 r.intent.getAction(),
12276 r.nextReceiver - 1,
12277 ((ResolveInfo)curReceiver).toString());
12278 }
12279 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012280 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012281 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012282 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012283 System.identityHashCode(r),
12284 r.intent.getAction(),
12285 r.nextReceiver,
12286 "NONE");
12287 }
12288 }
12289
Jeff Brown4d94a762010-09-23 11:33:28 -070012290 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12291 if (! mPendingBroadcastTimeoutMessage) {
12292 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12293 mHandler.sendMessageAtTime(msg, timeoutTime);
12294 mPendingBroadcastTimeoutMessage = true;
12295 }
12296 }
12297
12298 private final void cancelBroadcastTimeoutLocked() {
12299 if (mPendingBroadcastTimeoutMessage) {
12300 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12301 mPendingBroadcastTimeoutMessage = false;
12302 }
12303 }
12304
12305 private final void broadcastTimeoutLocked(boolean fromMsg) {
12306 if (fromMsg) {
12307 mPendingBroadcastTimeoutMessage = false;
12308 }
12309
12310 if (mOrderedBroadcasts.size() == 0) {
12311 return;
12312 }
12313
12314 long now = SystemClock.uptimeMillis();
12315 BroadcastRecord r = mOrderedBroadcasts.get(0);
12316 if (fromMsg) {
12317 if (mDidDexOpt) {
12318 // Delay timeouts until dexopt finishes.
12319 mDidDexOpt = false;
12320 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12321 setBroadcastTimeoutLocked(timeoutTime);
12322 return;
12323 }
12324 if (! mProcessesReady) {
12325 // Only process broadcast timeouts if the system is ready. That way
12326 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12327 // to do heavy lifting for system up.
12328 return;
12329 }
12330
12331 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12332 if (timeoutTime > now) {
12333 // We can observe premature timeouts because we do not cancel and reset the
12334 // broadcast timeout message after each receiver finishes. Instead, we set up
12335 // an initial timeout then kick it down the road a little further as needed
12336 // when it expires.
12337 if (DEBUG_BROADCAST) Slog.v(TAG,
12338 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12339 + timeoutTime);
12340 setBroadcastTimeoutLocked(timeoutTime);
12341 return;
12342 }
12343 }
12344
12345 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12346 + ", started " + (now - r.receiverTime) + "ms ago");
12347 r.receiverTime = now;
12348 r.anrCount++;
12349
12350 // Current receiver has passed its expiration date.
12351 if (r.nextReceiver <= 0) {
12352 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12353 return;
12354 }
12355
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012356 ProcessRecord app = null;
12357 String anrMessage = null;
12358
Jeff Brown4d94a762010-09-23 11:33:28 -070012359 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12360 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12361 logBroadcastReceiverDiscardLocked(r);
12362 if (curReceiver instanceof BroadcastFilter) {
12363 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12364 if (bf.receiverList.pid != 0
12365 && bf.receiverList.pid != MY_PID) {
12366 synchronized (this.mPidsSelfLocked) {
12367 app = this.mPidsSelfLocked.get(
12368 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012370 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012371 } else {
12372 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012373 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012374
Jeff Brown4d94a762010-09-23 11:33:28 -070012375 if (app != null) {
12376 anrMessage = "Broadcast of " + r.intent.toString();
12377 }
12378
12379 if (mPendingBroadcast == r) {
12380 mPendingBroadcast = null;
12381 }
12382
12383 // Move on to the next receiver.
12384 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12385 r.resultExtras, r.resultAbort, true);
12386 scheduleBroadcastsLocked();
12387
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012388 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012389 // Post the ANR to the handler since we do not want to process ANRs while
12390 // potentially holding our lock.
12391 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012393 }
12394
12395 private final void processCurBroadcastLocked(BroadcastRecord r,
12396 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012397 if (DEBUG_BROADCAST) Slog.v(TAG,
12398 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012399 if (app.thread == null) {
12400 throw new RemoteException();
12401 }
12402 r.receiver = app.thread.asBinder();
12403 r.curApp = app;
12404 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012405 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012406
12407 // Tell the application to launch this receiver.
12408 r.intent.setComponent(r.curComponent);
12409
12410 boolean started = false;
12411 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012412 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413 "Delivering to component " + r.curComponent
12414 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012415 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012416 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012417 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012419 if (DEBUG_BROADCAST) Slog.v(TAG,
12420 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012421 started = true;
12422 } finally {
12423 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012424 if (DEBUG_BROADCAST) Slog.v(TAG,
12425 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012426 r.receiver = null;
12427 r.curApp = null;
12428 app.curReceiver = null;
12429 }
12430 }
12431
12432 }
12433
Jeff Brown4d94a762010-09-23 11:33:28 -070012434 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012435 Intent intent, int resultCode, String data, Bundle extras,
12436 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012437 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012438 if (app != null && app.thread != null) {
12439 // If we have an app thread, do the call through that so it is
12440 // correctly ordered with other one-way calls.
12441 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012442 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012444 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012445 }
12446 }
12447
Jeff Brown4d94a762010-09-23 11:33:28 -070012448 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012449 BroadcastFilter filter, boolean ordered) {
12450 boolean skip = false;
12451 if (filter.requiredPermission != null) {
12452 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012453 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012455 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012456 + r.intent.toString()
12457 + " from " + r.callerPackage + " (pid="
12458 + r.callingPid + ", uid=" + r.callingUid + ")"
12459 + " requires " + filter.requiredPermission
12460 + " due to registered receiver " + filter);
12461 skip = true;
12462 }
12463 }
12464 if (r.requiredPermission != null) {
12465 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012466 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012467 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012468 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012469 + r.intent.toString()
12470 + " to " + filter.receiverList.app
12471 + " (pid=" + filter.receiverList.pid
12472 + ", uid=" + filter.receiverList.uid + ")"
12473 + " requires " + r.requiredPermission
12474 + " due to sender " + r.callerPackage
12475 + " (uid " + r.callingUid + ")");
12476 skip = true;
12477 }
12478 }
12479
12480 if (!skip) {
12481 // If this is not being sent as an ordered broadcast, then we
12482 // don't want to touch the fields that keep track of the current
12483 // state of ordered broadcasts.
12484 if (ordered) {
12485 r.receiver = filter.receiverList.receiver.asBinder();
12486 r.curFilter = filter;
12487 filter.receiverList.curBroadcast = r;
12488 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012489 if (filter.receiverList.app != null) {
12490 // Bump hosting application to no longer be in background
12491 // scheduling class. Note that we can't do that if there
12492 // isn't an app... but we can only be in that case for
12493 // things that directly call the IActivityManager API, which
12494 // are already core system stuff so don't matter for this.
12495 r.curApp = filter.receiverList.app;
12496 filter.receiverList.app.curReceiver = r;
12497 updateOomAdjLocked();
12498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012499 }
12500 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012501 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012502 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012503 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012504 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012505 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012506 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012508 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 if (ordered) {
12510 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12511 }
12512 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012513 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012514 if (ordered) {
12515 r.receiver = null;
12516 r.curFilter = null;
12517 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012518 if (filter.receiverList.app != null) {
12519 filter.receiverList.app.curReceiver = null;
12520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012521 }
12522 }
12523 }
12524 }
12525
Dianne Hackborn12527f92009-11-11 17:39:50 -080012526 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12527 if (r.callingUid < 0) {
12528 // This was from a registerReceiver() call; ignore it.
12529 return;
12530 }
12531 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12532 MAX_BROADCAST_HISTORY-1);
12533 r.finishTime = SystemClock.uptimeMillis();
12534 mBroadcastHistory[0] = r;
12535 }
12536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012537 private final void processNextBroadcast(boolean fromMsg) {
12538 synchronized(this) {
12539 BroadcastRecord r;
12540
Joe Onorato8a9b2202010-02-26 18:56:32 -080012541 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012542 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012543 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012544
12545 updateCpuStats();
12546
12547 if (fromMsg) {
12548 mBroadcastsScheduled = false;
12549 }
12550
12551 // First, deliver any non-serialized broadcasts right away.
12552 while (mParallelBroadcasts.size() > 0) {
12553 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012554 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012555 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012556 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012557 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012558 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012559 for (int i=0; i<N; i++) {
12560 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012561 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012562 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012563 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012564 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012565 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012566 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012567 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012568 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012569 }
12570
12571 // Now take care of the next serialized one...
12572
12573 // If we are waiting for a process to come up to handle the next
12574 // broadcast, then do nothing at this point. Just in case, we
12575 // check that the process we're waiting for still exists.
12576 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012577 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012578 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012579 + mPendingBroadcast.curApp);
12580 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581
12582 boolean isDead;
12583 synchronized (mPidsSelfLocked) {
12584 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12585 }
12586 if (!isDead) {
12587 // It's still alive, so keep waiting
12588 return;
12589 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012590 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012591 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012592 mPendingBroadcast.state = BroadcastRecord.IDLE;
12593 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012594 mPendingBroadcast = null;
12595 }
12596 }
12597
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012598 boolean looped = false;
12599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012600 do {
12601 if (mOrderedBroadcasts.size() == 0) {
12602 // No more broadcasts pending, so all done!
12603 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012604 if (looped) {
12605 // If we had finished the last ordered broadcast, then
12606 // make sure all processes have correct oom and sched
12607 // adjustments.
12608 updateOomAdjLocked();
12609 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012610 return;
12611 }
12612 r = mOrderedBroadcasts.get(0);
12613 boolean forceReceive = false;
12614
12615 // Ensure that even if something goes awry with the timeout
12616 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012617 // and continue to make progress.
12618 //
12619 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012620 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012621 // one time heavy lifting after system upgrades and can take
12622 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012623 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012624 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012625 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012626 if ((numReceivers > 0) &&
12627 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012628 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012629 + " now=" + now
12630 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012631 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012632 + " intent=" + r.intent
12633 + " numReceivers=" + numReceivers
12634 + " nextReceiver=" + r.nextReceiver
12635 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012636 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012637 forceReceive = true;
12638 r.state = BroadcastRecord.IDLE;
12639 }
12640 }
12641
12642 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012643 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012644 "processNextBroadcast() called when not idle (state="
12645 + r.state + ")");
12646 return;
12647 }
12648
12649 if (r.receivers == null || r.nextReceiver >= numReceivers
12650 || r.resultAbort || forceReceive) {
12651 // No more receivers for this broadcast! Send the final
12652 // result if requested...
12653 if (r.resultTo != null) {
12654 try {
12655 if (DEBUG_BROADCAST) {
12656 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012657 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012658 + " seq=" + seq + " app=" + r.callerApp);
12659 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012660 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012661 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012662 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012663 // Set this to null so that the reference
12664 // (local and remote) isnt kept in the mBroadcastHistory.
12665 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012666 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012667 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012668 }
12669 }
12670
Joe Onorato8a9b2202010-02-26 18:56:32 -080012671 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012672 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012673
Joe Onorato8a9b2202010-02-26 18:56:32 -080012674 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012675 + r);
12676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012677 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012678 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012679 mOrderedBroadcasts.remove(0);
12680 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012681 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012682 continue;
12683 }
12684 } while (r == null);
12685
12686 // Get the next receiver...
12687 int recIdx = r.nextReceiver++;
12688
12689 // Keep track of when this receiver started, and make sure there
12690 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012691 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012692 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012693 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012694 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012695 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012696 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012697 }
12698 if (! mPendingBroadcastTimeoutMessage) {
12699 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012700 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012701 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12702 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012703 }
12704
12705 Object nextReceiver = r.receivers.get(recIdx);
12706 if (nextReceiver instanceof BroadcastFilter) {
12707 // Simple case: this is a registered receiver who gets
12708 // a direct call.
12709 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012710 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012711 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012712 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012713 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012714 if (r.receiver == null || !r.ordered) {
12715 // The receiver has already finished, so schedule to
12716 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012717 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12718 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012719 r.state = BroadcastRecord.IDLE;
12720 scheduleBroadcastsLocked();
12721 }
12722 return;
12723 }
12724
12725 // Hard case: need to instantiate the receiver, possibly
12726 // starting its application process to host it.
12727
12728 ResolveInfo info =
12729 (ResolveInfo)nextReceiver;
12730
12731 boolean skip = false;
12732 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012733 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12734 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012735 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012736 if (!info.activityInfo.exported) {
12737 Slog.w(TAG, "Permission Denial: broadcasting "
12738 + r.intent.toString()
12739 + " from " + r.callerPackage + " (pid=" + r.callingPid
12740 + ", uid=" + r.callingUid + ")"
12741 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12742 + " due to receiver " + info.activityInfo.packageName
12743 + "/" + info.activityInfo.name);
12744 } else {
12745 Slog.w(TAG, "Permission Denial: broadcasting "
12746 + r.intent.toString()
12747 + " from " + r.callerPackage + " (pid=" + r.callingPid
12748 + ", uid=" + r.callingUid + ")"
12749 + " requires " + info.activityInfo.permission
12750 + " due to receiver " + info.activityInfo.packageName
12751 + "/" + info.activityInfo.name);
12752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 skip = true;
12754 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012755 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012756 r.requiredPermission != null) {
12757 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012758 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012759 checkPermission(r.requiredPermission,
12760 info.activityInfo.applicationInfo.packageName);
12761 } catch (RemoteException e) {
12762 perm = PackageManager.PERMISSION_DENIED;
12763 }
12764 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012765 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012766 + r.intent + " to "
12767 + info.activityInfo.applicationInfo.packageName
12768 + " requires " + r.requiredPermission
12769 + " due to sender " + r.callerPackage
12770 + " (uid " + r.callingUid + ")");
12771 skip = true;
12772 }
12773 }
12774 if (r.curApp != null && r.curApp.crashing) {
12775 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012776 if (DEBUG_BROADCAST) Slog.v(TAG,
12777 "Skipping deliver ordered " + r + " to " + r.curApp
12778 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012779 skip = true;
12780 }
12781
12782 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012783 if (DEBUG_BROADCAST) Slog.v(TAG,
12784 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012785 r.receiver = null;
12786 r.curFilter = null;
12787 r.state = BroadcastRecord.IDLE;
12788 scheduleBroadcastsLocked();
12789 return;
12790 }
12791
12792 r.state = BroadcastRecord.APP_RECEIVE;
12793 String targetProcess = info.activityInfo.processName;
12794 r.curComponent = new ComponentName(
12795 info.activityInfo.applicationInfo.packageName,
12796 info.activityInfo.name);
12797 r.curReceiver = info.activityInfo;
12798
Dianne Hackborne7f97212011-02-24 14:40:20 -080012799 // Broadcast is being executed, its package can't be stopped.
12800 try {
12801 AppGlobals.getPackageManager().setPackageStoppedState(
12802 r.curComponent.getPackageName(), false);
12803 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012804 } catch (IllegalArgumentException e) {
12805 Slog.w(TAG, "Failed trying to unstop package "
12806 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012807 }
12808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 // Is this receiver's application already running?
12810 ProcessRecord app = getProcessRecordLocked(targetProcess,
12811 info.activityInfo.applicationInfo.uid);
12812 if (app != null && app.thread != null) {
12813 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012814 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012815 processCurBroadcastLocked(r, app);
12816 return;
12817 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012818 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012819 + r.curComponent, e);
12820 }
12821
12822 // If a dead object exception was thrown -- fall through to
12823 // restart the application.
12824 }
12825
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012826 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012827 if (DEBUG_BROADCAST) Slog.v(TAG,
12828 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012829 if ((r.curApp=startProcessLocked(targetProcess,
12830 info.activityInfo.applicationInfo, true,
12831 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012832 "broadcast", r.curComponent,
12833 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12834 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012835 // Ah, this recipient is unavailable. Finish it if necessary,
12836 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012837 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012838 + info.activityInfo.applicationInfo.packageName + "/"
12839 + info.activityInfo.applicationInfo.uid + " for broadcast "
12840 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012841 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012842 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12843 r.resultExtras, r.resultAbort, true);
12844 scheduleBroadcastsLocked();
12845 r.state = BroadcastRecord.IDLE;
12846 return;
12847 }
12848
12849 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012850 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012851 }
12852 }
12853
12854 // =========================================================
12855 // INSTRUMENTATION
12856 // =========================================================
12857
12858 public boolean startInstrumentation(ComponentName className,
12859 String profileFile, int flags, Bundle arguments,
12860 IInstrumentationWatcher watcher) {
12861 // Refuse possible leaked file descriptors
12862 if (arguments != null && arguments.hasFileDescriptors()) {
12863 throw new IllegalArgumentException("File descriptors passed in Bundle");
12864 }
12865
12866 synchronized(this) {
12867 InstrumentationInfo ii = null;
12868 ApplicationInfo ai = null;
12869 try {
12870 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012871 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012872 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012873 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012874 } catch (PackageManager.NameNotFoundException e) {
12875 }
12876 if (ii == null) {
12877 reportStartInstrumentationFailure(watcher, className,
12878 "Unable to find instrumentation info for: " + className);
12879 return false;
12880 }
12881 if (ai == null) {
12882 reportStartInstrumentationFailure(watcher, className,
12883 "Unable to find instrumentation target package: " + ii.targetPackage);
12884 return false;
12885 }
12886
12887 int match = mContext.getPackageManager().checkSignatures(
12888 ii.targetPackage, ii.packageName);
12889 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12890 String msg = "Permission Denial: starting instrumentation "
12891 + className + " from pid="
12892 + Binder.getCallingPid()
12893 + ", uid=" + Binder.getCallingPid()
12894 + " not allowed because package " + ii.packageName
12895 + " does not have a signature matching the target "
12896 + ii.targetPackage;
12897 reportStartInstrumentationFailure(watcher, className, msg);
12898 throw new SecurityException(msg);
12899 }
12900
12901 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012902 // Instrumentation can kill and relaunch even persistent processes
12903 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012904 ProcessRecord app = addAppLocked(ai);
12905 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012906 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012907 app.instrumentationProfileFile = profileFile;
12908 app.instrumentationArguments = arguments;
12909 app.instrumentationWatcher = watcher;
12910 app.instrumentationResultClass = className;
12911 Binder.restoreCallingIdentity(origId);
12912 }
12913
12914 return true;
12915 }
12916
12917 /**
12918 * Report errors that occur while attempting to start Instrumentation. Always writes the
12919 * error to the logs, but if somebody is watching, send the report there too. This enables
12920 * the "am" command to report errors with more information.
12921 *
12922 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12923 * @param cn The component name of the instrumentation.
12924 * @param report The error report.
12925 */
12926 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12927 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012928 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012929 try {
12930 if (watcher != null) {
12931 Bundle results = new Bundle();
12932 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12933 results.putString("Error", report);
12934 watcher.instrumentationStatus(cn, -1, results);
12935 }
12936 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012937 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012938 }
12939 }
12940
12941 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12942 if (app.instrumentationWatcher != null) {
12943 try {
12944 // NOTE: IInstrumentationWatcher *must* be oneway here
12945 app.instrumentationWatcher.instrumentationFinished(
12946 app.instrumentationClass,
12947 resultCode,
12948 results);
12949 } catch (RemoteException e) {
12950 }
12951 }
12952 app.instrumentationWatcher = null;
12953 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012954 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012955 app.instrumentationProfileFile = null;
12956 app.instrumentationArguments = null;
12957
Christopher Tate3dacd842011-08-19 14:56:15 -070012958 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012959 }
12960
12961 public void finishInstrumentation(IApplicationThread target,
12962 int resultCode, Bundle results) {
12963 // Refuse possible leaked file descriptors
12964 if (results != null && results.hasFileDescriptors()) {
12965 throw new IllegalArgumentException("File descriptors passed in Intent");
12966 }
12967
12968 synchronized(this) {
12969 ProcessRecord app = getRecordForAppLocked(target);
12970 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012971 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012972 return;
12973 }
12974 final long origId = Binder.clearCallingIdentity();
12975 finishInstrumentationLocked(app, resultCode, results);
12976 Binder.restoreCallingIdentity(origId);
12977 }
12978 }
12979
12980 // =========================================================
12981 // CONFIGURATION
12982 // =========================================================
12983
12984 public ConfigurationInfo getDeviceConfigurationInfo() {
12985 ConfigurationInfo config = new ConfigurationInfo();
12986 synchronized (this) {
12987 config.reqTouchScreen = mConfiguration.touchscreen;
12988 config.reqKeyboardType = mConfiguration.keyboard;
12989 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012990 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12991 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012992 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12993 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012994 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12995 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012996 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12997 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012998 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 }
13000 return config;
13001 }
13002
13003 public Configuration getConfiguration() {
13004 Configuration ci;
13005 synchronized(this) {
13006 ci = new Configuration(mConfiguration);
13007 }
13008 return ci;
13009 }
13010
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013011 public void updatePersistentConfiguration(Configuration values) {
13012 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13013 "updateConfiguration()");
13014 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13015 "updateConfiguration()");
13016 if (values == null) {
13017 throw new NullPointerException("Configuration must not be null");
13018 }
13019
13020 synchronized(this) {
13021 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013022 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013023 Binder.restoreCallingIdentity(origId);
13024 }
13025 }
13026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013027 public void updateConfiguration(Configuration values) {
13028 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13029 "updateConfiguration()");
13030
13031 synchronized(this) {
13032 if (values == null && mWindowManager != null) {
13033 // sentinel: fetch the current configuration from the window manager
13034 values = mWindowManager.computeNewConfiguration();
13035 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013036
13037 if (mWindowManager != null) {
13038 mProcessList.applyDisplaySize(mWindowManager);
13039 }
13040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013041 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013042 if (values != null) {
13043 Settings.System.clearConfiguration(values);
13044 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013045 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013046 Binder.restoreCallingIdentity(origId);
13047 }
13048 }
13049
13050 /**
13051 * Do either or both things: (1) change the current configuration, and (2)
13052 * make sure the given activity is running with the (now) current
13053 * configuration. Returns true if the activity has been left running, or
13054 * false if <var>starting</var> is being destroyed to match the new
13055 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013056 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013057 */
13058 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013059 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013060 int changes = 0;
13061
13062 boolean kept = true;
13063
13064 if (values != null) {
13065 Configuration newConfig = new Configuration(mConfiguration);
13066 changes = newConfig.updateFrom(values);
13067 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013068 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013069 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013070 }
13071
Doug Zongker2bec3d42009-12-04 12:52:44 -080013072 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013073
Dianne Hackborn813075a62011-11-14 17:45:19 -080013074 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013075 saveLocaleLocked(values.locale,
13076 !values.locale.equals(mConfiguration.locale),
13077 values.userSetLocale);
13078 }
13079
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013080 mConfigurationSeq++;
13081 if (mConfigurationSeq <= 0) {
13082 mConfigurationSeq = 1;
13083 }
13084 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013085 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013086 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013087
13088 final Configuration configCopy = new Configuration(mConfiguration);
13089
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013090 AttributeCache ac = AttributeCache.instance();
13091 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013092 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013094
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013095 // Make sure all resources in our process are updated
13096 // right now, so that anyone who is going to retrieve
13097 // resource values after we return will be sure to get
13098 // the new ones. This is especially important during
13099 // boot, where the first config change needs to guarantee
13100 // all resources have that config before following boot
13101 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013102 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013103
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013104 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013105 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013106 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013107 mHandler.sendMessage(msg);
13108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013109
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013110 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13111 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013112 try {
13113 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013114 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013115 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013116 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013117 }
13118 } catch (Exception e) {
13119 }
13120 }
13121 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013122 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13123 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013124 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13125 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013126 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13127 broadcastIntentLocked(null, null,
13128 new Intent(Intent.ACTION_LOCALE_CHANGED),
13129 null, null, 0, null, null,
13130 null, false, false, MY_PID, Process.SYSTEM_UID);
13131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013132 }
13133 }
13134
13135 if (changes != 0 && starting == null) {
13136 // If the configuration changed, and the caller is not already
13137 // in the process of starting an activity, then find the top
13138 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013139 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013140 }
13141
13142 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013143 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013144 // And we need to make sure at this point that all other activities
13145 // are made visible with the correct configuration.
13146 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013147 }
13148
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013149 if (values != null && mWindowManager != null) {
13150 mWindowManager.setNewConfiguration(mConfiguration);
13151 }
13152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013153 return kept;
13154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155
13156 /**
13157 * Save the locale. You must be inside a synchronized (this) block.
13158 */
13159 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13160 if(isDiff) {
13161 SystemProperties.set("user.language", l.getLanguage());
13162 SystemProperties.set("user.region", l.getCountry());
13163 }
13164
13165 if(isPersist) {
13166 SystemProperties.set("persist.sys.language", l.getLanguage());
13167 SystemProperties.set("persist.sys.country", l.getCountry());
13168 SystemProperties.set("persist.sys.localevar", l.getVariant());
13169 }
13170 }
13171
13172 // =========================================================
13173 // LIFETIME MANAGEMENT
13174 // =========================================================
13175
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013176 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013177 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013178 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013179 // This adjustment has already been computed. If we are calling
13180 // from the top, we may have already computed our adjustment with
13181 // an earlier hidden adjustment that isn't really for us... if
13182 // so, use the new hidden adjustment.
13183 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013184 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013185 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013186 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013187 }
13188
13189 if (app.thread == null) {
13190 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013191 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013192 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013193 }
13194
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013195 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13196 app.adjSource = null;
13197 app.adjTarget = null;
13198 app.empty = false;
13199 app.hidden = false;
13200
13201 final int activitiesSize = app.activities.size();
13202
Dianne Hackborn7d608422011-08-07 16:24:18 -070013203 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013204 // The max adjustment doesn't allow this app to be anything
13205 // below foreground, so it is not worth doing work for it.
13206 app.adjType = "fixed";
13207 app.adjSeq = mAdjSeq;
13208 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013209 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013210 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013211 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013212 // System process can do UI, and when they do we want to have
13213 // them trim their memory after the user leaves the UI. To
13214 // facilitate this, here we need to determine whether or not it
13215 // is currently showing UI.
13216 app.systemNoUi = true;
13217 if (app == TOP_APP) {
13218 app.systemNoUi = false;
13219 } else if (activitiesSize > 0) {
13220 for (int j = 0; j < activitiesSize; j++) {
13221 final ActivityRecord r = app.activities.get(j);
13222 if (r.visible) {
13223 app.systemNoUi = false;
13224 break;
13225 }
13226 }
13227 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013228 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013229 }
13230
13231 final boolean hadForegroundActivities = app.foregroundActivities;
13232
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013233 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013234 app.keeping = false;
13235 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013236
The Android Open Source Project4df24232009-03-05 14:34:35 -080013237 // Determine the importance of the process, starting with most
13238 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013239 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013240 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013241 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013242 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013243 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013244 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013245 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013246 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013247 } else if (app.instrumentationClass != null) {
13248 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013249 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013250 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013251 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013252 } else if (app.curReceiver != null ||
13253 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13254 // An app that is currently receiving a broadcast also
13255 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013256 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013257 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013258 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013259 } else if (app.executingServices.size() > 0) {
13260 // An app that is currently executing a service callback also
13261 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013262 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013263 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013264 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013265 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013266 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013267 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013268 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013269 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013270 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013271 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013272 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013273 // A very not-needed process. If this is lower in the lru list,
13274 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013275 adj = hiddenAdj;
13276 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013277 app.hidden = true;
13278 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013279 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013280 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013281
13282 // Examine all activities if not already foreground.
13283 if (!app.foregroundActivities && activitiesSize > 0) {
13284 for (int j = 0; j < activitiesSize; j++) {
13285 final ActivityRecord r = app.activities.get(j);
13286 if (r.visible) {
13287 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013288 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13289 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013290 app.adjType = "visible";
13291 }
13292 schedGroup = Process.THREAD_GROUP_DEFAULT;
13293 app.hidden = false;
13294 app.foregroundActivities = true;
13295 break;
13296 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13297 || r.state == ActivityState.STOPPING) {
13298 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013299 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13300 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013301 app.adjType = "stopping";
13302 }
13303 app.foregroundActivities = true;
13304 }
13305 }
13306 }
13307
Dianne Hackborn7d608422011-08-07 16:24:18 -070013308 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013309 if (app.foregroundServices) {
13310 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013311 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013312 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013313 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013314 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013315 } else if (app.forcingToForeground != null) {
13316 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013317 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013318 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013319 app.adjType = "force-foreground";
13320 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013321 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013322 }
13323 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013324
Dianne Hackborn7d608422011-08-07 16:24:18 -070013325 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013326 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013327 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013328 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013329 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013330 app.adjType = "heavy";
13331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013332
Dianne Hackborn7d608422011-08-07 16:24:18 -070013333 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013334 // This process is hosting what we currently consider to be the
13335 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013336 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013337 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013338 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013339 app.adjType = "home";
13340 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013341
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013342 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13343 && app.activities.size() > 0) {
13344 // This was the previous process that showed UI to the user.
13345 // We want to try to keep it around more aggressively, to give
13346 // a good experience around switching between two apps.
13347 adj = ProcessList.PREVIOUS_APP_ADJ;
13348 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13349 app.hidden = false;
13350 app.adjType = "previous";
13351 }
13352
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013353 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13354 + " reason=" + app.adjType);
13355
The Android Open Source Project4df24232009-03-05 14:34:35 -080013356 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013357 // there are applications dependent on our services or providers, but
13358 // this gives us a baseline and makes sure we don't get into an
13359 // infinite recursion.
13360 app.adjSeq = mAdjSeq;
13361 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013362
Christopher Tate6fa95972009-06-05 18:43:55 -070013363 if (mBackupTarget != null && app == mBackupTarget.app) {
13364 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013365 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013366 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013367 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013368 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013369 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013370 }
13371 }
13372
Dianne Hackborn7d608422011-08-07 16:24:18 -070013373 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013374 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013375 final long now = SystemClock.uptimeMillis();
13376 // This process is more important if the top activity is
13377 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013378 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013379 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013380 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013382 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013383 // If this process has shown some UI, let it immediately
13384 // go to the LRU list because it may be pretty heavy with
13385 // UI stuff. We'll tag it with a label just to help
13386 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013387 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013388 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013389 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013390 } else {
13391 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13392 // This service has seen some activity within
13393 // recent memory, so we will keep its process ahead
13394 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013395 if (adj > ProcessList.SERVICE_ADJ) {
13396 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013397 app.adjType = "started-services";
13398 app.hidden = false;
13399 }
13400 }
13401 // If we have let the service slide into the background
13402 // state, still have some text describing what it is doing
13403 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013404 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013405 app.adjType = "started-bg-services";
13406 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013407 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013408 // Don't kill this process because it is doing work; it
13409 // has said it is doing work.
13410 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013411 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013412 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013413 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013414 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013415 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013416 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013417 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013418 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013419 // XXX should compute this based on the max of
13420 // all connected clients.
13421 ConnectionRecord cr = clist.get(i);
13422 if (cr.binding.client == app) {
13423 // Binding to ourself is not interesting.
13424 continue;
13425 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013426 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013427 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013428 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013429 int myHiddenAdj = hiddenAdj;
13430 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013431 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013432 myHiddenAdj = client.hiddenAdj;
13433 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013434 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013435 }
13436 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013437 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013438 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013439 String adjType = null;
13440 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13441 // Not doing bind OOM management, so treat
13442 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013443 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013444 // If this process has shown some UI, let it immediately
13445 // go to the LRU list because it may be pretty heavy with
13446 // UI stuff. We'll tag it with a label just to help
13447 // debug and understand what is going on.
13448 if (adj > clientAdj) {
13449 adjType = "bound-bg-ui-services";
13450 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013451 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013452 clientAdj = adj;
13453 } else {
13454 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13455 // This service has not seen activity within
13456 // recent memory, so allow it to drop to the
13457 // LRU list if there is no other reason to keep
13458 // it around. We'll also tag it with a label just
13459 // to help debug and undertand what is going on.
13460 if (adj > clientAdj) {
13461 adjType = "bound-bg-services";
13462 }
13463 clientAdj = adj;
13464 }
13465 }
13466 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013467 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013468 // If this process has recently shown UI, and
13469 // the process that is binding to it is less
13470 // important than being visible, then we don't
13471 // care about the binding as much as we care
13472 // about letting this process get into the LRU
13473 // list to be killed and restarted if needed for
13474 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013475 if (app.hasShownUi && app != mHomeProcess
13476 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013477 adjType = "bound-bg-ui-services";
13478 } else {
13479 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13480 |Context.BIND_IMPORTANT)) != 0) {
13481 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013482 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13483 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13484 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13485 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13486 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013487 adj = clientAdj;
13488 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013489 app.pendingUiClean = true;
13490 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13491 adj = ProcessList.VISIBLE_APP_ADJ;
13492 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013493 }
13494 if (!client.hidden) {
13495 app.hidden = false;
13496 }
13497 if (client.keeping) {
13498 app.keeping = true;
13499 }
13500 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013501 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013502 }
13503 if (adjType != null) {
13504 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013505 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13506 .REASON_SERVICE_IN_USE;
13507 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013508 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013509 app.adjTarget = s.name;
13510 }
13511 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13512 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13513 schedGroup = Process.THREAD_GROUP_DEFAULT;
13514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013515 }
13516 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013517 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13518 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013519 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013520 (a.visible || a.state == ActivityState.RESUMED
13521 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013522 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013523 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13524 schedGroup = Process.THREAD_GROUP_DEFAULT;
13525 }
13526 app.hidden = false;
13527 app.adjType = "service";
13528 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13529 .REASON_SERVICE_IN_USE;
13530 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013531 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013532 app.adjTarget = s.name;
13533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013535 }
13536 }
13537 }
13538 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013539
Dianne Hackborn287952c2010-09-22 22:34:31 -070013540 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013541 // would like to avoid killing it unless it would prevent the current
13542 // application from running. By default we put the process in
13543 // with the rest of the background processes; as we scan through
13544 // its services we may bump it up from there.
13545 if (adj > hiddenAdj) {
13546 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013547 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013548 app.adjType = "bg-services";
13549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013550 }
13551
Dianne Hackborn7d608422011-08-07 16:24:18 -070013552 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013553 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013554 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013555 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013556 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013557 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013558 if (cpr.clients.size() != 0) {
13559 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013560 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013561 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013562 if (client == app) {
13563 // Being our own client is not interesting.
13564 continue;
13565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013566 int myHiddenAdj = hiddenAdj;
13567 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013568 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013569 myHiddenAdj = client.hiddenAdj;
13570 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013571 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013572 }
13573 }
13574 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013575 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013576 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013577 if (app.hasShownUi && app != mHomeProcess
13578 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013579 app.adjType = "bg-ui-provider";
13580 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013581 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13582 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013583 app.adjType = "provider";
13584 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013585 if (!client.hidden) {
13586 app.hidden = false;
13587 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013588 if (client.keeping) {
13589 app.keeping = true;
13590 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013591 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13592 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013593 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013594 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013595 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013596 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013597 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13598 schedGroup = Process.THREAD_GROUP_DEFAULT;
13599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013600 }
13601 }
13602 // If the provider has external (non-framework) process
13603 // dependencies, ensure that its adjustment is at least
13604 // FOREGROUND_APP_ADJ.
13605 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013606 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13607 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013608 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013609 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013610 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013611 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013612 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013613 }
13614 }
13615 }
13616 }
13617
13618 app.curRawAdj = adj;
13619
Joe Onorato8a9b2202010-02-26 18:56:32 -080013620 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013621 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13622 if (adj > app.maxAdj) {
13623 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013624 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013625 schedGroup = Process.THREAD_GROUP_DEFAULT;
13626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013627 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013628 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013629 app.keeping = true;
13630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013631
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013632 if (app.hasAboveClient) {
13633 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13634 // then we need to drop its adjustment to be lower than the service's
13635 // in order to honor the request. We want to drop it by one adjustment
13636 // level... but there is special meaning applied to various levels so
13637 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013638 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013639 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013640 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13641 adj = ProcessList.VISIBLE_APP_ADJ;
13642 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13643 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13644 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13645 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013646 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013647 adj++;
13648 }
13649 }
13650
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013651 if (adj == ProcessList.SERVICE_ADJ) {
13652 if (doingAll) {
13653 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13654 mNewNumServiceProcs++;
13655 }
13656 if (app.serviceb) {
13657 adj = ProcessList.SERVICE_B_ADJ;
13658 }
13659 } else {
13660 app.serviceb = false;
13661 }
13662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013663 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013664 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013665
13666 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013667 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13668 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013669 }
13670
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013671 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013672 }
13673
13674 /**
13675 * Ask a given process to GC right now.
13676 */
13677 final void performAppGcLocked(ProcessRecord app) {
13678 try {
13679 app.lastRequestedGc = SystemClock.uptimeMillis();
13680 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013681 if (app.reportLowMemory) {
13682 app.reportLowMemory = false;
13683 app.thread.scheduleLowMemory();
13684 } else {
13685 app.thread.processInBackground();
13686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013687 }
13688 } catch (Exception e) {
13689 // whatever.
13690 }
13691 }
13692
13693 /**
13694 * Returns true if things are idle enough to perform GCs.
13695 */
Josh Bartel7f208742010-02-25 11:01:44 -060013696 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013697 return mParallelBroadcasts.size() == 0
13698 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013699 && (mSleeping || (mMainStack.mResumedActivity != null &&
13700 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013701 }
13702
13703 /**
13704 * Perform GCs on all processes that are waiting for it, but only
13705 * if things are idle.
13706 */
13707 final void performAppGcsLocked() {
13708 final int N = mProcessesToGc.size();
13709 if (N <= 0) {
13710 return;
13711 }
Josh Bartel7f208742010-02-25 11:01:44 -060013712 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013713 while (mProcessesToGc.size() > 0) {
13714 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013715 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013716 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13717 <= SystemClock.uptimeMillis()) {
13718 // To avoid spamming the system, we will GC processes one
13719 // at a time, waiting a few seconds between each.
13720 performAppGcLocked(proc);
13721 scheduleAppGcsLocked();
13722 return;
13723 } else {
13724 // It hasn't been long enough since we last GCed this
13725 // process... put it in the list to wait for its time.
13726 addProcessToGcListLocked(proc);
13727 break;
13728 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013729 }
13730 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013731
13732 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013733 }
13734 }
13735
13736 /**
13737 * If all looks good, perform GCs on all processes waiting for them.
13738 */
13739 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013740 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013741 performAppGcsLocked();
13742 return;
13743 }
13744 // Still not idle, wait some more.
13745 scheduleAppGcsLocked();
13746 }
13747
13748 /**
13749 * Schedule the execution of all pending app GCs.
13750 */
13751 final void scheduleAppGcsLocked() {
13752 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013753
13754 if (mProcessesToGc.size() > 0) {
13755 // Schedule a GC for the time to the next process.
13756 ProcessRecord proc = mProcessesToGc.get(0);
13757 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13758
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013759 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013760 long now = SystemClock.uptimeMillis();
13761 if (when < (now+GC_TIMEOUT)) {
13762 when = now + GC_TIMEOUT;
13763 }
13764 mHandler.sendMessageAtTime(msg, when);
13765 }
13766 }
13767
13768 /**
13769 * Add a process to the array of processes waiting to be GCed. Keeps the
13770 * list in sorted order by the last GC time. The process can't already be
13771 * on the list.
13772 */
13773 final void addProcessToGcListLocked(ProcessRecord proc) {
13774 boolean added = false;
13775 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13776 if (mProcessesToGc.get(i).lastRequestedGc <
13777 proc.lastRequestedGc) {
13778 added = true;
13779 mProcessesToGc.add(i+1, proc);
13780 break;
13781 }
13782 }
13783 if (!added) {
13784 mProcessesToGc.add(0, proc);
13785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013786 }
13787
13788 /**
13789 * Set up to ask a process to GC itself. This will either do it
13790 * immediately, or put it on the list of processes to gc the next
13791 * time things are idle.
13792 */
13793 final void scheduleAppGcLocked(ProcessRecord app) {
13794 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013795 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013796 return;
13797 }
13798 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013799 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013800 scheduleAppGcsLocked();
13801 }
13802 }
13803
Dianne Hackborn287952c2010-09-22 22:34:31 -070013804 final void checkExcessivePowerUsageLocked(boolean doKills) {
13805 updateCpuStatsNow();
13806
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013807 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013808 boolean doWakeKills = doKills;
13809 boolean doCpuKills = doKills;
13810 if (mLastPowerCheckRealtime == 0) {
13811 doWakeKills = false;
13812 }
13813 if (mLastPowerCheckUptime == 0) {
13814 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013815 }
13816 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013817 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013818 }
13819 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013820 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13821 final long curUptime = SystemClock.uptimeMillis();
13822 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13823 mLastPowerCheckRealtime = curRealtime;
13824 mLastPowerCheckUptime = curUptime;
13825 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13826 doWakeKills = false;
13827 }
13828 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13829 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013830 }
13831 int i = mLruProcesses.size();
13832 while (i > 0) {
13833 i--;
13834 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013835 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013836 long wtime;
13837 synchronized (stats) {
13838 wtime = stats.getProcessWakeTime(app.info.uid,
13839 app.pid, curRealtime);
13840 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013841 long wtimeUsed = wtime - app.lastWakeTime;
13842 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13843 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013844 StringBuilder sb = new StringBuilder(128);
13845 sb.append("Wake for ");
13846 app.toShortString(sb);
13847 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013848 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013849 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013850 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013851 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013852 sb.append((wtimeUsed*100)/realtimeSince);
13853 sb.append("%)");
13854 Slog.i(TAG, sb.toString());
13855 sb.setLength(0);
13856 sb.append("CPU for ");
13857 app.toShortString(sb);
13858 sb.append(": over ");
13859 TimeUtils.formatDuration(uptimeSince, sb);
13860 sb.append(" used ");
13861 TimeUtils.formatDuration(cputimeUsed, sb);
13862 sb.append(" (");
13863 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013864 sb.append("%)");
13865 Slog.i(TAG, sb.toString());
13866 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013867 // If a process has held a wake lock for more
13868 // than 50% of the time during this period,
13869 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013870 if (doWakeKills && realtimeSince > 0
13871 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13872 synchronized (stats) {
13873 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13874 realtimeSince, wtimeUsed);
13875 }
13876 Slog.w(TAG, "Excessive wake lock in " + app.processName
13877 + " (pid " + app.pid + "): held " + wtimeUsed
13878 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013879 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13880 app.processName, app.setAdj, "excessive wake lock");
13881 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013882 } else if (doCpuKills && uptimeSince > 0
13883 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13884 synchronized (stats) {
13885 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13886 uptimeSince, cputimeUsed);
13887 }
13888 Slog.w(TAG, "Excessive CPU in " + app.processName
13889 + " (pid " + app.pid + "): used " + cputimeUsed
13890 + " during " + uptimeSince);
13891 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13892 app.processName, app.setAdj, "excessive cpu");
13893 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013894 } else {
13895 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013896 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013897 }
13898 }
13899 }
13900 }
13901
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013902 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013903 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013904 app.hiddenAdj = hiddenAdj;
13905
13906 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013907 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013908 }
13909
Dianne Hackborn287952c2010-09-22 22:34:31 -070013910 final boolean wasKeeping = app.keeping;
13911
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013912 boolean success = true;
13913
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013914 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013915
Jeff Brown10e89712011-07-08 18:52:57 -070013916 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013917 if (false) {
13918 // Removing for now. Forcing GCs is not so useful anymore
13919 // with Dalvik, and the new memory level hint facility is
13920 // better for what we need to do these days.
13921 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13922 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13923 // If this app is transitioning from foreground to
13924 // non-foreground, have it do a gc.
13925 scheduleAppGcLocked(app);
13926 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13927 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13928 // Likewise do a gc when an app is moving in to the
13929 // background (such as a service stopping).
13930 scheduleAppGcLocked(app);
13931 }
Jeff Brown10e89712011-07-08 18:52:57 -070013932 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013933
Jeff Brown10e89712011-07-08 18:52:57 -070013934 if (wasKeeping && !app.keeping) {
13935 // This app is no longer something we want to keep. Note
13936 // its current wake lock time to later know to kill it if
13937 // it is not behaving well.
13938 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13939 synchronized (stats) {
13940 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13941 app.pid, SystemClock.elapsedRealtime());
13942 }
13943 app.lastCpuTime = app.curCpuTime;
13944 }
13945
13946 app.setRawAdj = app.curRawAdj;
13947 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013948
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013949 if (app.curAdj != app.setAdj) {
13950 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013951 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13952 TAG, "Set " + app.pid + " " + app.processName +
13953 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013954 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013955 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013956 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013957 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013958 }
13959 }
13960 if (app.setSchedGroup != app.curSchedGroup) {
13961 app.setSchedGroup = app.curSchedGroup;
13962 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13963 "Setting process group of " + app.processName
13964 + " to " + app.curSchedGroup);
13965 if (app.waitingToKill != null &&
13966 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13967 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13969 app.processName, app.setAdj, app.waitingToKill);
13970 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013971 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013972 } else {
13973 if (true) {
13974 long oldId = Binder.clearCallingIdentity();
13975 try {
13976 Process.setProcessGroup(app.pid, app.curSchedGroup);
13977 } catch (Exception e) {
13978 Slog.w(TAG, "Failed setting process group of " + app.pid
13979 + " to " + app.curSchedGroup);
13980 e.printStackTrace();
13981 } finally {
13982 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013983 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013984 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013985 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013986 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013987 app.thread.setSchedulingGroup(app.curSchedGroup);
13988 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013989 }
13990 }
13991 }
13992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013993 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013994 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013995 }
13996
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013997 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013998 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013999 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014000 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014001 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014002 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014003 }
14004 }
14005 return resumedActivity;
14006 }
14007
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014008 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014009 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014010 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14011 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014012 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14013 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014014
14015 mAdjSeq++;
14016
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014017 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014018 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14019 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014020 if (nowHidden != wasHidden) {
14021 // Changed to/from hidden state, so apps after it in the LRU
14022 // list may also be changed.
14023 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014024 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014025 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014026 }
14027
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014028 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014029 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014030 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14031
14032 if (false) {
14033 RuntimeException e = new RuntimeException();
14034 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014035 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014036 }
14037
14038 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014039 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014040
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014041 // Let's determine how many processes we have running vs.
14042 // how many slots we have for background processes; we may want
14043 // to put multiple processes in a slot of there are enough of
14044 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014045 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014046 int factor = (mLruProcesses.size()-4)/numSlots;
14047 if (factor < 1) factor = 1;
14048 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014049 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014050
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014051 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014052 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014053 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014054 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014055 while (i > 0) {
14056 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014057 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014058 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014059 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14060 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014061 && app.curAdj == curHiddenAdj) {
14062 step++;
14063 if (step >= factor) {
14064 step = 0;
14065 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014066 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014067 }
14068 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014069 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014070 numHidden++;
14071 if (numHidden > mProcessLimit) {
14072 Slog.i(TAG, "No longer want " + app.processName
14073 + " (pid " + app.pid + "): hidden #" + numHidden);
14074 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14075 app.processName, app.setAdj, "too many background");
14076 app.killedBackground = true;
14077 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014078 }
14079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014080 }
14081 }
14082
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014083 mNumServiceProcs = mNewNumServiceProcs;
14084
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014085 // Now determine the memory trimming level of background processes.
14086 // Unfortunately we need to start at the back of the list to do this
14087 // properly. We only do this if the number of background apps we
14088 // are managing to keep around is less than half the maximum we desire;
14089 // if we are keeping a good number around, we'll let them use whatever
14090 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014091 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014092 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014093 factor = numHidden/3;
14094 int minFactor = 2;
14095 if (mHomeProcess != null) minFactor++;
14096 if (mPreviousProcess != null) minFactor++;
14097 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014098 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014099 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014100 for (i=0; i<N; i++) {
14101 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014102 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14103 && app.curAdj != ProcessList.SERVICE_B_ADJ
14104 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014105 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14106 try {
14107 app.thread.scheduleTrimMemory(curLevel);
14108 } catch (RemoteException e) {
14109 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014110 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014111 // For these apps we will also finish their activities
14112 // to help them free memory.
Dianne Hackborn28695e02011-11-02 21:59:51 -070014113 mMainStack.destroyActivitiesLocked(app, false, "trim");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014114 }
14115 }
14116 app.trimMemoryLevel = curLevel;
14117 step++;
14118 if (step >= factor) {
14119 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014120 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14121 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014122 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014123 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14124 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014125 break;
14126 }
14127 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014128 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014129 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014130 && app.thread != null) {
14131 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014132 app.thread.scheduleTrimMemory(
14133 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014134 } catch (RemoteException e) {
14135 }
14136 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014137 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014138 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014139 && app.pendingUiClean) {
14140 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14141 && app.thread != null) {
14142 try {
14143 app.thread.scheduleTrimMemory(
14144 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14145 } catch (RemoteException e) {
14146 }
14147 }
14148 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14149 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014150 } else {
14151 app.trimMemoryLevel = 0;
14152 }
14153 }
14154 } else {
14155 final int N = mLruProcesses.size();
14156 for (i=0; i<N; i++) {
14157 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014158 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014159 && app.pendingUiClean) {
14160 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14161 && app.thread != null) {
14162 try {
14163 app.thread.scheduleTrimMemory(
14164 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14165 } catch (RemoteException e) {
14166 }
14167 }
14168 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14169 app.pendingUiClean = false;
14170 } else {
14171 app.trimMemoryLevel = 0;
14172 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014173 }
14174 }
14175
14176 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014177 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014179 }
14180
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014181 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014182 synchronized (this) {
14183 int i;
14184
14185 // First remove any unused application processes whose package
14186 // has been removed.
14187 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14188 final ProcessRecord app = mRemovedProcesses.get(i);
14189 if (app.activities.size() == 0
14190 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014191 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014192 TAG, "Exiting empty application process "
14193 + app.processName + " ("
14194 + (app.thread != null ? app.thread.asBinder() : null)
14195 + ")\n");
14196 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014197 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14198 app.processName, app.setAdj, "empty");
14199 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014200 } else {
14201 try {
14202 app.thread.scheduleExit();
14203 } catch (Exception e) {
14204 // Ignore exceptions.
14205 }
14206 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014207 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014208 mRemovedProcesses.remove(i);
14209
14210 if (app.persistent) {
14211 if (app.persistent) {
14212 addAppLocked(app.info);
14213 }
14214 }
14215 }
14216 }
14217
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014218 // Now update the oom adj for all processes.
14219 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014220 }
14221 }
14222
14223 /** This method sends the specified signal to each of the persistent apps */
14224 public void signalPersistentProcesses(int sig) throws RemoteException {
14225 if (sig != Process.SIGNAL_USR1) {
14226 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14227 }
14228
14229 synchronized (this) {
14230 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14231 != PackageManager.PERMISSION_GRANTED) {
14232 throw new SecurityException("Requires permission "
14233 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14234 }
14235
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014236 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14237 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014238 if (r.thread != null && r.persistent) {
14239 Process.sendSignal(r.pid, sig);
14240 }
14241 }
14242 }
14243 }
14244
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014245 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14246 if (proc == null || proc == mProfileProc) {
14247 proc = mProfileProc;
14248 path = mProfileFile;
14249 profileType = mProfileType;
14250 clearProfilerLocked();
14251 }
14252 if (proc == null) {
14253 return;
14254 }
14255 try {
14256 proc.thread.profilerControl(false, path, null, profileType);
14257 } catch (RemoteException e) {
14258 throw new IllegalStateException("Process disappeared");
14259 }
14260 }
14261
14262 private void clearProfilerLocked() {
14263 if (mProfileFd != null) {
14264 try {
14265 mProfileFd.close();
14266 } catch (IOException e) {
14267 }
14268 }
14269 mProfileApp = null;
14270 mProfileProc = null;
14271 mProfileFile = null;
14272 mProfileType = 0;
14273 mAutoStopProfiler = false;
14274 }
14275
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014276 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014277 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014278
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014279 try {
14280 synchronized (this) {
14281 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14282 // its own permission.
14283 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14284 != PackageManager.PERMISSION_GRANTED) {
14285 throw new SecurityException("Requires permission "
14286 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014287 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014288
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014289 if (start && fd == null) {
14290 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014291 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014292
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014293 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014294 if (process != null) {
14295 try {
14296 int pid = Integer.parseInt(process);
14297 synchronized (mPidsSelfLocked) {
14298 proc = mPidsSelfLocked.get(pid);
14299 }
14300 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014301 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014302
14303 if (proc == null) {
14304 HashMap<String, SparseArray<ProcessRecord>> all
14305 = mProcessNames.getMap();
14306 SparseArray<ProcessRecord> procs = all.get(process);
14307 if (procs != null && procs.size() > 0) {
14308 proc = procs.valueAt(0);
14309 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014310 }
14311 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014312
14313 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014314 throw new IllegalArgumentException("Unknown process: " + process);
14315 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014316
14317 if (start) {
14318 stopProfilerLocked(null, null, 0);
14319 setProfileApp(proc.info, proc.processName, path, fd, false);
14320 mProfileProc = proc;
14321 mProfileType = profileType;
14322 try {
14323 fd = fd.dup();
14324 } catch (IOException e) {
14325 fd = null;
14326 }
14327 proc.thread.profilerControl(start, path, fd, profileType);
14328 fd = null;
14329 mProfileFd = null;
14330 } else {
14331 stopProfilerLocked(proc, path, profileType);
14332 if (fd != null) {
14333 try {
14334 fd.close();
14335 } catch (IOException e) {
14336 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014337 }
14338 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014339
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014340 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014341 }
14342 } catch (RemoteException e) {
14343 throw new IllegalStateException("Process disappeared");
14344 } finally {
14345 if (fd != null) {
14346 try {
14347 fd.close();
14348 } catch (IOException e) {
14349 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014350 }
14351 }
14352 }
Andy McFadden824c5102010-07-09 16:26:57 -070014353
14354 public boolean dumpHeap(String process, boolean managed,
14355 String path, ParcelFileDescriptor fd) throws RemoteException {
14356
14357 try {
14358 synchronized (this) {
14359 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14360 // its own permission (same as profileControl).
14361 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14362 != PackageManager.PERMISSION_GRANTED) {
14363 throw new SecurityException("Requires permission "
14364 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14365 }
14366
14367 if (fd == null) {
14368 throw new IllegalArgumentException("null fd");
14369 }
14370
14371 ProcessRecord proc = null;
14372 try {
14373 int pid = Integer.parseInt(process);
14374 synchronized (mPidsSelfLocked) {
14375 proc = mPidsSelfLocked.get(pid);
14376 }
14377 } catch (NumberFormatException e) {
14378 }
14379
14380 if (proc == null) {
14381 HashMap<String, SparseArray<ProcessRecord>> all
14382 = mProcessNames.getMap();
14383 SparseArray<ProcessRecord> procs = all.get(process);
14384 if (procs != null && procs.size() > 0) {
14385 proc = procs.valueAt(0);
14386 }
14387 }
14388
14389 if (proc == null || proc.thread == null) {
14390 throw new IllegalArgumentException("Unknown process: " + process);
14391 }
14392
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014393 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14394 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014395 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14396 throw new SecurityException("Process not debuggable: " + proc);
14397 }
14398 }
14399
14400 proc.thread.dumpHeap(managed, path, fd);
14401 fd = null;
14402 return true;
14403 }
14404 } catch (RemoteException e) {
14405 throw new IllegalStateException("Process disappeared");
14406 } finally {
14407 if (fd != null) {
14408 try {
14409 fd.close();
14410 } catch (IOException e) {
14411 }
14412 }
14413 }
14414 }
14415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014416 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14417 public void monitor() {
14418 synchronized (this) { }
14419 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014420
14421 public void onCoreSettingsChange(Bundle settings) {
14422 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14423 ProcessRecord processRecord = mLruProcesses.get(i);
14424 try {
14425 if (processRecord.thread != null) {
14426 processRecord.thread.setCoreSettings(settings);
14427 }
14428 } catch (RemoteException re) {
14429 /* ignore */
14430 }
14431 }
14432 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014433
14434 // Multi-user methods
14435
14436 public boolean switchUser(int userid) {
14437 // TODO
14438 return true;
14439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014440}