blob: d6d3b9dc2ac98d92562bdee913ab6c173b874215 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
123import java.io.DataInputStream;
124import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.File;
126import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200130import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800131import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.PrintWriter;
133import java.lang.IllegalStateException;
134import java.lang.ref.WeakReference;
135import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700136import java.util.Collections;
137import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.util.HashMap;
139import java.util.HashSet;
140import java.util.Iterator;
141import java.util.List;
142import java.util.Locale;
143import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700144import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700145import java.util.concurrent.atomic.AtomicBoolean;
146import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148public final class ActivityManagerService extends ActivityManagerNative
149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "ActivityManager";
151 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400152 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_SWITCH = localLOGV || false;
154 static final boolean DEBUG_TASKS = localLOGV || false;
155 static final boolean DEBUG_PAUSE = localLOGV || false;
156 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
157 static final boolean DEBUG_TRANSITION = localLOGV || false;
158 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_VISBILITY = localLOGV || false;
163 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700164 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700167 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700168 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700169 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700170 static final boolean DEBUG_POWER = localLOGV || false;
171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean VALIDATE_TOKENS = false;
173 static final boolean SHOW_ACTIVITY_START_TIME = true;
174
175 // Control over CPU and battery monitoring.
176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
177 static final boolean MONITOR_CPU_USAGE = true;
178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
180 static final boolean MONITOR_THREAD_CPU_USAGE = false;
181
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 // Maximum number of recent tasks that we can remember.
188 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700189
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700190 // Amount of time after a call to stopAppSwitches() during which we will
191 // prevent further untrusted switches from happening.
192 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
194 // How long we wait for a launched process to attach to the activity manager
195 // before we decide it's never going to come up for real.
196 static final int PROC_START_TIMEOUT = 10*1000;
197
Jeff Brown3f9dd282011-07-08 20:02:19 -0700198 // How long we wait for a launched process to attach to the activity manager
199 // before we decide it's never going to come up for real, when the process was
200 // started with a wrapper for instrumentation (such as Valgrind) because it
201 // could take much longer than usual.
202 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 // How long to wait after going idle before forcing apps to GC.
205 static final int GC_TIMEOUT = 5*1000;
206
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700207 // The minimum amount of time between successive GC requests for a process.
208 static final int GC_MIN_INTERVAL = 60*1000;
209
Dianne Hackborn287952c2010-09-22 22:34:31 -0700210 // The rate at which we check for apps using excessive power -- 15 mins.
211 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
212
213 // The minimum sample duration we will allow before deciding we have
214 // enough data on wake locks to start killing things.
215 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
216
217 // The minimum sample duration we will allow before deciding we have
218 // enough data on CPU usage to start killing things.
219 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 // How long we allow a receiver to run before giving up on it.
222 static final int BROADCAST_TIMEOUT = 10*1000;
223
224 // How long we wait for a service to finish executing.
225 static final int SERVICE_TIMEOUT = 20*1000;
226
227 // How long a service needs to be running until restarting its process
228 // is no longer considered to be a relaunch of the service.
229 static final int SERVICE_RESTART_DURATION = 5*1000;
230
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700231 // How long a service needs to be running until it will start back at
232 // SERVICE_RESTART_DURATION after being killed.
233 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
234
235 // Multiplying factor to increase restart duration time by, for each time
236 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
237 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
238
239 // The minimum amount of time between restarting services that we allow.
240 // That is, when multiple services are restarting, we won't allow each
241 // to restart less than this amount of time from the last one.
242 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 // Maximum amount of time for there to be no activity on a service before
245 // we consider it non-essential and allow its process to go on the
246 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700247 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 // How long we wait until we timeout on key dispatching.
250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 // How long we wait until we timeout on key dispatching during instrumentation.
253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254
Dan Egnor42471dd2010-01-07 17:25:22 -0800255 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 static final String[] EMPTY_STRING_ARRAY = new String[0];
258
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700259 public ActivityStack mMainStack;
260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700262 * Description of a request to start a new activity, which has been held
263 * due to app switches being disabled.
264 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700265 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700266 ActivityRecord r;
267 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700268 Uri[] grantedUriPermissions;
269 int grantedMode;
270 boolean onlyIfNeeded;
271 }
272
273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274 = new ArrayList<PendingActivityLaunch>();
275
276 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 * List of all active broadcasts that are to be executed immediately
278 * (without waiting for another broadcast to finish). Currently this only
279 * contains broadcasts to registered receivers, to avoid spinning up
280 * a bunch of processes to execute IntentReceiver components.
281 */
282 final ArrayList<BroadcastRecord> mParallelBroadcasts
283 = new ArrayList<BroadcastRecord>();
284
285 /**
286 * List of all active broadcasts that are to be executed one at a time.
287 * The object at the top of the list is the currently activity broadcasts;
288 * those after it are waiting for the top to finish..
289 */
290 final ArrayList<BroadcastRecord> mOrderedBroadcasts
291 = new ArrayList<BroadcastRecord>();
292
293 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800294 * Historical data of past broadcasts, for debugging.
295 */
296 static final int MAX_BROADCAST_HISTORY = 100;
297 final BroadcastRecord[] mBroadcastHistory
298 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
299
300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * Set when we current have a BROADCAST_INTENT_MSG in flight.
302 */
303 boolean mBroadcastsScheduled = false;
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Activity we have told the window manager to have key focus.
307 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700308 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700309 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 * List of intents that were used to start the most recent tasks.
311 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700315 * Process management.
316 */
317 final ProcessList mProcessList = new ProcessList();
318
319 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 * All of the applications we currently have running organized by name.
321 * The keys are strings of the application package name (as
322 * returned by the package manager), and the keys are ApplicationRecord
323 * objects.
324 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
327 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700328 * The currently running heavy-weight process, if any.
329 */
330 ProcessRecord mHeavyWeightProcess = null;
331
332 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 * The last time that various processes have crashed.
334 */
335 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
336
337 /**
338 * Set of applications that we consider to be bad, and will reject
339 * incoming broadcasts from (which the user has no control over).
340 * Processes are added to this set when they have crashed twice within
341 * a minimum amount of time; they are removed from it when they are
342 * later restarted (hopefully due to some user action). The value is the
343 * time it was added to the list.
344 */
345 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
346
347 /**
348 * All of the processes we currently have running organized by pid.
349 * The keys are the pid running the application.
350 *
351 * <p>NOTE: This object is protected by its own lock, NOT the global
352 * activity manager lock!
353 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700354 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355
356 /**
357 * All of the processes that have been forced to be foreground. The key
358 * is the pid of the caller who requested it (we hold a death
359 * link on it).
360 */
361 abstract class ForegroundToken implements IBinder.DeathRecipient {
362 int pid;
363 IBinder token;
364 }
365 final SparseArray<ForegroundToken> mForegroundProcesses
366 = new SparseArray<ForegroundToken>();
367
368 /**
369 * List of records for processes that someone had tried to start before the
370 * system was ready. We don't start them at that point, but ensure they
371 * are started by the time booting is complete.
372 */
373 final ArrayList<ProcessRecord> mProcessesOnHold
374 = new ArrayList<ProcessRecord>();
375
376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 * List of persistent applications that are in the process
378 * of being started.
379 */
380 final ArrayList<ProcessRecord> mPersistentStartingProcesses
381 = new ArrayList<ProcessRecord>();
382
383 /**
384 * Processes that are being forcibly torn down.
385 */
386 final ArrayList<ProcessRecord> mRemovedProcesses
387 = new ArrayList<ProcessRecord>();
388
389 /**
390 * List of running applications, sorted by recent usage.
391 * The first entry in the list is the least recently used.
392 * It contains ApplicationRecord objects. This list does NOT include
393 * any persistent application records (since we never want to exit them).
394 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800395 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 = new ArrayList<ProcessRecord>();
397
398 /**
399 * List of processes that should gc as soon as things are idle.
400 */
401 final ArrayList<ProcessRecord> mProcessesToGc
402 = new ArrayList<ProcessRecord>();
403
404 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800405 * This is the process holding what we currently consider to be
406 * the "home" activity.
407 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700408 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800409
410 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400411 * Packages that the user has asked to have run in screen size
412 * compatibility mode instead of filling the screen.
413 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700414 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400415
416 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * Set of PendingResultRecord objects that are currently active.
418 */
419 final HashSet mPendingResultRecords = new HashSet();
420
421 /**
422 * Set of IntentSenderRecord objects that are currently active.
423 */
424 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
425 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
426
427 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800428 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700429 * already logged DropBox entries for. Guarded by itself. If
430 * something (rogue user app) forces this over
431 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
432 */
433 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
434 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
435
436 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700437 * Strict Mode background batched logging state.
438 *
439 * The string buffer is guarded by itself, and its lock is also
440 * used to determine if another batched write is already
441 * in-flight.
442 */
443 private final StringBuilder mStrictModeBuffer = new StringBuilder();
444
445 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700446 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
447 */
448 private boolean mPendingBroadcastTimeoutMessage;
449
450 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 * Intent broadcast that we have tried to start, but are
452 * waiting for its application's process to be created. We only
453 * need one (instead of a list) because we always process broadcasts
454 * one at a time, so no others can be started while waiting for this
455 * one.
456 */
457 BroadcastRecord mPendingBroadcast = null;
458
459 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700460 * The receiver index that is pending, to restart the broadcast if needed.
461 */
462 int mPendingBroadcastRecvIndex;
463
464 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 * Keeps track of all IIntentReceivers that have been registered for
466 * broadcasts. Hash keys are the receiver IBinder, hash value is
467 * a ReceiverList.
468 */
469 final HashMap mRegisteredReceivers = new HashMap();
470
471 /**
472 * Resolver for broadcast intents to registered receivers.
473 * Holds BroadcastFilter (subclass of IntentFilter).
474 */
475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
477 @Override
478 protected boolean allowFilterResult(
479 BroadcastFilter filter, List<BroadcastFilter> dest) {
480 IBinder target = filter.receiverList.receiver.asBinder();
481 for (int i=dest.size()-1; i>=0; i--) {
482 if (dest.get(i).receiverList.receiver.asBinder() == target) {
483 return false;
484 }
485 }
486 return true;
487 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700488
489 @Override
490 protected String packageForFilter(BroadcastFilter filter) {
491 return filter.packageName;
492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 };
494
495 /**
496 * State of all active sticky broadcasts. Keys are the action of the
497 * sticky Intent, values are an ArrayList of all broadcasted intents with
498 * that action (which should usually be one).
499 */
500 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
501 new HashMap<String, ArrayList<Intent>>();
502
503 /**
504 * All currently running services.
505 */
506 final HashMap<ComponentName, ServiceRecord> mServices =
507 new HashMap<ComponentName, ServiceRecord>();
508
509 /**
510 * All currently running services indexed by the Intent used to start them.
511 */
512 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
513 new HashMap<Intent.FilterComparison, ServiceRecord>();
514
515 /**
516 * All currently bound service connections. Keys are the IBinder of
517 * the client's IServiceConnection.
518 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700519 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
520 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521
522 /**
523 * List of services that we have been asked to start,
524 * but haven't yet been able to. It is used to hold start requests
525 * while waiting for their corresponding application thread to get
526 * going.
527 */
528 final ArrayList<ServiceRecord> mPendingServices
529 = new ArrayList<ServiceRecord>();
530
531 /**
532 * List of services that are scheduled to restart following a crash.
533 */
534 final ArrayList<ServiceRecord> mRestartingServices
535 = new ArrayList<ServiceRecord>();
536
537 /**
538 * List of services that are in the process of being stopped.
539 */
540 final ArrayList<ServiceRecord> mStoppingServices
541 = new ArrayList<ServiceRecord>();
542
543 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700544 * Backup/restore process management
545 */
546 String mBackupAppName = null;
547 BackupRecord mBackupTarget = null;
548
549 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * List of PendingThumbnailsRecord objects of clients who are still
551 * waiting to receive all of the thumbnails for a task.
552 */
553 final ArrayList mPendingThumbnails = new ArrayList();
554
555 /**
556 * List of HistoryRecord objects that have been finished and must
557 * still report back to a pending thumbnail receiver.
558 */
559 final ArrayList mCancelledThumbnails = new ArrayList();
560
561 /**
562 * All of the currently running global content providers. Keys are a
563 * string containing the provider name and values are a
564 * ContentProviderRecord object containing the data about it. Note
565 * that a single provider may be published under multiple names, so
566 * there may be multiple entries here for a single one in mProvidersByClass.
567 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700568 final HashMap<String, ContentProviderRecord> mProvidersByName
569 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570
571 /**
572 * All of the currently running global content providers. Keys are a
573 * string containing the provider's implementation class and values are a
574 * ContentProviderRecord object containing the data about it.
575 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700576 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
577 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * List of content providers who have clients waiting for them. The
581 * application is currently being launched and the provider will be
582 * removed from this list once it is published.
583 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700584 final ArrayList<ContentProviderRecord> mLaunchingProviders
585 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * Global set of specific Uri permissions that have been granted.
589 */
590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591 = new SparseArray<HashMap<Uri, UriPermission>>();
592
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800593 CoreSettingsObserver mCoreSettingsObserver;
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 /**
596 * Thread-local storage used to carry caller permissions over through
597 * indirect content-provider access.
598 * @see #ActivityManagerService.openContentUri()
599 */
600 private class Identity {
601 public int pid;
602 public int uid;
603
604 Identity(int _pid, int _uid) {
605 pid = _pid;
606 uid = _uid;
607 }
608 }
609 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
610
611 /**
612 * All information we have collected about the runtime performance of
613 * any user id that can impact battery performance.
614 */
615 final BatteryStatsService mBatteryStatsService;
616
617 /**
618 * information about component usage
619 */
620 final UsageStatsService mUsageStatsService;
621
622 /**
623 * Current configuration information. HistoryRecord objects are given
624 * a reference to this object to indicate which configuration they are
625 * currently running in, so this object must be kept immutable.
626 */
627 Configuration mConfiguration = new Configuration();
628
629 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800630 * Current sequencing integer of the configuration, for skipping old
631 * configurations.
632 */
633 int mConfigurationSeq = 0;
634
635 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700636 * Hardware-reported OpenGLES version.
637 */
638 final int GL_ES_VERSION;
639
640 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 * List of initialization arguments to pass to all processes when binding applications to them.
642 * For example, references to the commonly used services.
643 */
644 HashMap<String, IBinder> mAppBindArgs;
645
646 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700647 * Temporary to avoid allocations. Protected by main lock.
648 */
649 final StringBuilder mStringBuilder = new StringBuilder(256);
650
651 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 * Used to control how we initialize the service.
653 */
654 boolean mStartRunning = false;
655 ComponentName mTopComponent;
656 String mTopAction;
657 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700658 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 boolean mSystemReady = false;
660 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700661 boolean mWaitingUpdate = false;
662 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700663 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700664 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
666 Context mContext;
667
668 int mFactoryTest;
669
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700670 boolean mCheckedForSetup;
671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700673 * The time at which we will allow normal application switches again,
674 * after a call to {@link #stopAppSwitches()}.
675 */
676 long mAppSwitchesAllowedTime;
677
678 /**
679 * This is set to true after the first switch after mAppSwitchesAllowedTime
680 * is set; any switches after that will clear the time.
681 */
682 boolean mDidAppSwitch;
683
684 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700685 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700686 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700687 long mLastPowerCheckRealtime;
688
689 /**
690 * Last time (in uptime) at which we checked for power usage.
691 */
692 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700693
694 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 * Set while we are wanting to sleep, to prevent any
696 * activities from being started/resumed.
697 */
698 boolean mSleeping = false;
699
700 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700701 * Set if we are shutting down the system, similar to sleeping.
702 */
703 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * Task identifier that activities are currently being started
707 * in. Incremented each time a new task is created.
708 * todo: Replace this with a TokenSpace class that generates non-repeating
709 * integers that won't wrap.
710 */
711 int mCurTask = 1;
712
713 /**
714 * Current sequence id for oom_adj computation traversal.
715 */
716 int mAdjSeq = 0;
717
718 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700719 * Current sequence id for process LRU updating.
720 */
721 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
723 /**
724 * System monitoring: number of processes that died since the last
725 * N procs were started.
726 */
727 int[] mProcDeaths = new int[20];
728
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700729 /**
730 * This is set if we had to do a delayed dexopt of an app before launching
731 * it, to increasing the ANR timeouts in that case.
732 */
733 boolean mDidDexOpt;
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 String mDebugApp = null;
736 boolean mWaitForDebugger = false;
737 boolean mDebugTransient = false;
738 String mOrigDebugApp = null;
739 boolean mOrigWaitForDebugger = false;
740 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700741 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700742 String mProfileApp = null;
743 ProcessRecord mProfileProc = null;
744 String mProfileFile;
745 ParcelFileDescriptor mProfileFd;
746 int mProfileType = 0;
747 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700749 final RemoteCallbackList<IActivityWatcher> mWatchers
750 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700751
752 final RemoteCallbackList<IProcessObserver> mProcessObservers
753 = new RemoteCallbackList<IProcessObserver>();
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 /**
756 * Callback of last caller to {@link #requestPss}.
757 */
758 Runnable mRequestPssCallback;
759
760 /**
761 * Remaining processes for which we are waiting results from the last
762 * call to {@link #requestPss}.
763 */
764 final ArrayList<ProcessRecord> mRequestPssList
765 = new ArrayList<ProcessRecord>();
766
767 /**
768 * Runtime statistics collection thread. This object's lock is used to
769 * protect all related state.
770 */
771 final Thread mProcessStatsThread;
772
773 /**
774 * Used to collect process stats when showing not responding dialog.
775 * Protected by mProcessStatsThread.
776 */
777 final ProcessStats mProcessStats = new ProcessStats(
778 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700779 final AtomicLong mLastCpuTime = new AtomicLong(0);
780 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 long mLastWriteTime = 0;
783
784 /**
785 * Set to true after the system has finished booting.
786 */
787 boolean mBooted = false;
788
Dianne Hackborn7d608422011-08-07 16:24:18 -0700789 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700790 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 WindowManagerService mWindowManager;
793
794 static ActivityManagerService mSelf;
795 static ActivityThread mSystemThread;
796
797 private final class AppDeathRecipient implements IBinder.DeathRecipient {
798 final ProcessRecord mApp;
799 final int mPid;
800 final IApplicationThread mAppThread;
801
802 AppDeathRecipient(ProcessRecord app, int pid,
803 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800804 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 TAG, "New death recipient " + this
806 + " for thread " + thread.asBinder());
807 mApp = app;
808 mPid = pid;
809 mAppThread = thread;
810 }
811
812 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800813 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 TAG, "Death received in " + this
815 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 synchronized(ActivityManagerService.this) {
817 appDiedLocked(mApp, mPid, mAppThread);
818 }
819 }
820 }
821
822 static final int SHOW_ERROR_MSG = 1;
823 static final int SHOW_NOT_RESPONDING_MSG = 2;
824 static final int SHOW_FACTORY_ERROR_MSG = 3;
825 static final int UPDATE_CONFIGURATION_MSG = 4;
826 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827 static final int WAIT_FOR_DEBUGGER_MSG = 6;
828 static final int BROADCAST_INTENT_MSG = 7;
829 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static final int SERVICE_TIMEOUT_MSG = 12;
831 static final int UPDATE_TIME_ZONE = 13;
832 static final int SHOW_UID_ERROR_MSG = 14;
833 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700836 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800837 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700838 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700842 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700843 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700845 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
846 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847
848 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700849 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
851 final Handler mHandler = new Handler() {
852 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 //}
855
856 public void handleMessage(Message msg) {
857 switch (msg.what) {
858 case SHOW_ERROR_MSG: {
859 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 synchronized (ActivityManagerService.this) {
861 ProcessRecord proc = (ProcessRecord)data.get("app");
862 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800863 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 return;
865 }
866 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700867 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800868 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 d.show();
870 proc.crashDialog = d;
871 } else {
872 // The device is asleep, so just pretend that the user
873 // saw a crash dialog and hit "force quit".
874 res.set(0);
875 }
876 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700877
878 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 } break;
880 case SHOW_NOT_RESPONDING_MSG: {
881 synchronized (ActivityManagerService.this) {
882 HashMap data = (HashMap) msg.obj;
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800888
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700889 Intent intent = new Intent("android.intent.action.ANR");
890 if (!mProcessesReady) {
891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
892 }
893 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800894 null, null, 0, null, null, null,
895 false, false, MY_PID, Process.SYSTEM_UID);
896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700898 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 d.show();
900 proc.anrDialog = d;
901 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700902
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700903 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700905 case SHOW_STRICT_MODE_VIOLATION_MSG: {
906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907 synchronized (ActivityManagerService.this) {
908 ProcessRecord proc = (ProcessRecord) data.get("app");
909 if (proc == null) {
910 Slog.e(TAG, "App not found when showing strict mode dialog.");
911 break;
912 }
913 if (proc.crashDialog != null) {
914 Slog.e(TAG, "App already has strict mode dialog: " + proc);
915 return;
916 }
917 AppErrorResult res = (AppErrorResult) data.get("result");
918 if (!mSleeping && !mShuttingDown) {
919 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920 d.show();
921 proc.crashDialog = d;
922 } else {
923 // The device is asleep, so just pretend that the user
924 // saw a crash dialog and hit "force quit".
925 res.set(0);
926 }
927 }
928 ensureBootCompleted();
929 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 case SHOW_FACTORY_ERROR_MSG: {
931 Dialog d = new FactoryErrorDialog(
932 mContext, msg.getData().getCharSequence("msg"));
933 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700934 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 } break;
936 case UPDATE_CONFIGURATION_MSG: {
937 final ContentResolver resolver = mContext.getContentResolver();
938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939 } break;
940 case GC_BACKGROUND_PROCESSES_MSG: {
941 synchronized (ActivityManagerService.this) {
942 performAppGcsIfAppropriateLocked();
943 }
944 } break;
945 case WAIT_FOR_DEBUGGER_MSG: {
946 synchronized (ActivityManagerService.this) {
947 ProcessRecord app = (ProcessRecord)msg.obj;
948 if (msg.arg1 != 0) {
949 if (!app.waitedForDebugger) {
950 Dialog d = new AppWaitingForDebuggerDialog(
951 ActivityManagerService.this,
952 mContext, app);
953 app.waitDialog = d;
954 app.waitedForDebugger = true;
955 d.show();
956 }
957 } else {
958 if (app.waitDialog != null) {
959 app.waitDialog.dismiss();
960 app.waitDialog = null;
961 }
962 }
963 }
964 } break;
965 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800966 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 TAG, "Received BROADCAST_INTENT_MSG");
968 processNextBroadcast(true);
969 } break;
970 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700971 synchronized (ActivityManagerService.this) {
972 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700976 if (mDidDexOpt) {
977 mDidDexOpt = false;
978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979 nmsg.obj = msg.obj;
980 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
981 return;
982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 serviceTimeout((ProcessRecord)msg.obj);
984 } break;
985 case UPDATE_TIME_ZONE: {
986 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 if (r.thread != null) {
990 try {
991 r.thread.updateTimeZone();
992 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995 }
996 }
997 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700998 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700999 case CLEAR_DNS_CACHE: {
1000 synchronized (ActivityManagerService.this) {
1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002 ProcessRecord r = mLruProcesses.get(i);
1003 if (r.thread != null) {
1004 try {
1005 r.thread.clearDnsCache();
1006 } catch (RemoteException ex) {
1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008 }
1009 }
1010 }
1011 }
1012 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001013 case UPDATE_HTTP_PROXY: {
1014 ProxyProperties proxy = (ProxyProperties)msg.obj;
1015 String host = "";
1016 String port = "";
1017 String exclList = "";
1018 if (proxy != null) {
1019 host = proxy.getHost();
1020 port = Integer.toString(proxy.getPort());
1021 exclList = proxy.getExclusionList();
1022 }
1023 synchronized (ActivityManagerService.this) {
1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025 ProcessRecord r = mLruProcesses.get(i);
1026 if (r.thread != null) {
1027 try {
1028 r.thread.setHttpProxy(host, port, exclList);
1029 } catch (RemoteException ex) {
1030 Slog.w(TAG, "Failed to update http proxy for: " +
1031 r.info.processName);
1032 }
1033 }
1034 }
1035 }
1036 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 case SHOW_UID_ERROR_MSG: {
1038 // XXX This is a temporary dialog, no need to localize.
1039 AlertDialog d = new BaseErrorDialog(mContext);
1040 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1041 d.setCancelable(false);
1042 d.setTitle("System UIDs Inconsistent");
1043 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001044 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1046 mUidAlert = d;
1047 d.show();
1048 } break;
1049 case IM_FEELING_LUCKY_MSG: {
1050 if (mUidAlert != null) {
1051 mUidAlert.dismiss();
1052 mUidAlert = null;
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001056 if (mDidDexOpt) {
1057 mDidDexOpt = false;
1058 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1059 nmsg.obj = msg.obj;
1060 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1061 return;
1062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 ProcessRecord app = (ProcessRecord)msg.obj;
1064 synchronized (ActivityManagerService.this) {
1065 processStartTimedOutLocked(app);
1066 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001067 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001068 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1069 synchronized (ActivityManagerService.this) {
1070 doPendingActivityLaunchesLocked(true);
1071 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001072 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001073 case KILL_APPLICATION_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 int uid = msg.arg1;
1076 boolean restart = (msg.arg2 == 1);
1077 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001078 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001079 }
1080 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001081 case FINALIZE_PENDING_INTENT_MSG: {
1082 ((PendingIntentRecord)msg.obj).completeFinalize();
1083 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001084 case POST_HEAVY_NOTIFICATION_MSG: {
1085 INotificationManager inm = NotificationManager.getService();
1086 if (inm == null) {
1087 return;
1088 }
1089
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001090 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001091 ProcessRecord process = root.app;
1092 if (process == null) {
1093 return;
1094 }
1095
1096 try {
1097 Context context = mContext.createPackageContext(process.info.packageName, 0);
1098 String text = mContext.getString(R.string.heavy_weight_notification,
1099 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1100 Notification notification = new Notification();
1101 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1102 notification.when = 0;
1103 notification.flags = Notification.FLAG_ONGOING_EVENT;
1104 notification.tickerText = text;
1105 notification.defaults = 0; // please be quiet
1106 notification.sound = null;
1107 notification.vibrate = null;
1108 notification.setLatestEventInfo(context, text,
1109 mContext.getText(R.string.heavy_weight_notification_detail),
1110 PendingIntent.getActivity(mContext, 0, root.intent,
1111 PendingIntent.FLAG_CANCEL_CURRENT));
1112
1113 try {
1114 int[] outId = new int[1];
1115 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1116 notification, outId);
1117 } catch (RuntimeException e) {
1118 Slog.w(ActivityManagerService.TAG,
1119 "Error showing notification for heavy-weight app", e);
1120 } catch (RemoteException e) {
1121 }
1122 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001123 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001124 }
1125 } break;
1126 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1127 INotificationManager inm = NotificationManager.getService();
1128 if (inm == null) {
1129 return;
1130 }
1131 try {
1132 inm.cancelNotification("android",
1133 R.string.heavy_weight_notification);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error canceling notification for service", e);
1137 } catch (RemoteException e) {
1138 }
1139 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001140 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1141 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001142 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001143 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001144 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1145 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001146 }
1147 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001148 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1149 synchronized (ActivityManagerService.this) {
1150 ActivityRecord ar = (ActivityRecord)msg.obj;
1151 if (mCompatModeDialog != null) {
1152 if (mCompatModeDialog.mAppInfo.packageName.equals(
1153 ar.info.applicationInfo.packageName)) {
1154 return;
1155 }
1156 mCompatModeDialog.dismiss();
1157 mCompatModeDialog = null;
1158 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001159 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001160 if (mCompatModePackages.getPackageAskCompatModeLocked(
1161 ar.packageName)) {
1162 int mode = mCompatModePackages.computeCompatModeLocked(
1163 ar.info.applicationInfo);
1164 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1165 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1166 mCompatModeDialog = new CompatModeDialog(
1167 ActivityManagerService.this, mContext,
1168 ar.info.applicationInfo);
1169 mCompatModeDialog.show();
1170 }
1171 }
1172 }
1173 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001174 break;
1175 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001176 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001177 final int pid = msg.arg1;
1178 final int uid = msg.arg2;
1179 final boolean foregroundActivities = (Boolean) msg.obj;
1180 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001181 break;
1182 }
1183 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001184 final int pid = msg.arg1;
1185 final int uid = msg.arg2;
1186 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001187 break;
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 }
1190 }
1191 };
1192
1193 public static void setSystemProcess() {
1194 try {
1195 ActivityManagerService m = mSelf;
1196
1197 ServiceManager.addService("activity", m);
1198 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001199 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 if (MONITOR_CPU_USAGE) {
1201 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 ServiceManager.addService("permission", new PermissionController(m));
1204
1205 ApplicationInfo info =
1206 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001207 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001208 mSystemThread.installSystemApplicationInfo(info);
1209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 synchronized (mSelf) {
1211 ProcessRecord app = mSelf.newProcessRecordLocked(
1212 mSystemThread.getApplicationThread(), info,
1213 info.processName);
1214 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001215 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001216 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1218 synchronized (mSelf.mPidsSelfLocked) {
1219 mSelf.mPidsSelfLocked.put(app.pid, app);
1220 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001221 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
1223 } catch (PackageManager.NameNotFoundException e) {
1224 throw new RuntimeException(
1225 "Unable to find android system package", e);
1226 }
1227 }
1228
1229 public void setWindowManager(WindowManagerService wm) {
1230 mWindowManager = wm;
1231 }
1232
1233 public static final Context main(int factoryTest) {
1234 AThread thr = new AThread();
1235 thr.start();
1236
1237 synchronized (thr) {
1238 while (thr.mService == null) {
1239 try {
1240 thr.wait();
1241 } catch (InterruptedException e) {
1242 }
1243 }
1244 }
1245
1246 ActivityManagerService m = thr.mService;
1247 mSelf = m;
1248 ActivityThread at = ActivityThread.systemMain();
1249 mSystemThread = at;
1250 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001251 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 m.mContext = context;
1253 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001254 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
1256 m.mBatteryStatsService.publish(context);
1257 m.mUsageStatsService.publish(context);
1258
1259 synchronized (thr) {
1260 thr.mReady = true;
1261 thr.notifyAll();
1262 }
1263
1264 m.startRunning(null, null, null, null);
1265
1266 return context;
1267 }
1268
1269 public static ActivityManagerService self() {
1270 return mSelf;
1271 }
1272
1273 static class AThread extends Thread {
1274 ActivityManagerService mService;
1275 boolean mReady = false;
1276
1277 public AThread() {
1278 super("ActivityManager");
1279 }
1280
1281 public void run() {
1282 Looper.prepare();
1283
1284 android.os.Process.setThreadPriority(
1285 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001286 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287
1288 ActivityManagerService m = new ActivityManagerService();
1289
1290 synchronized (this) {
1291 mService = m;
1292 notifyAll();
1293 }
1294
1295 synchronized (this) {
1296 while (!mReady) {
1297 try {
1298 wait();
1299 } catch (InterruptedException e) {
1300 }
1301 }
1302 }
1303
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001304 // For debug builds, log event loop stalls to dropbox for analysis.
1305 if (StrictMode.conditionallyEnableDebugLogging()) {
1306 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1307 }
1308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 Looper.loop();
1310 }
1311 }
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 static class MemBinder extends Binder {
1314 ActivityManagerService mActivityManagerService;
1315 MemBinder(ActivityManagerService activityManagerService) {
1316 mActivityManagerService = activityManagerService;
1317 }
1318
1319 @Override
1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001321 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 }
1323 }
1324
Chet Haase9c1e23b2011-03-24 10:51:31 -07001325 static class GraphicsBinder extends Binder {
1326 ActivityManagerService mActivityManagerService;
1327 GraphicsBinder(ActivityManagerService activityManagerService) {
1328 mActivityManagerService = activityManagerService;
1329 }
1330
1331 @Override
1332 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001333 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001334 }
1335 }
1336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 static class CpuBinder extends Binder {
1338 ActivityManagerService mActivityManagerService;
1339 CpuBinder(ActivityManagerService activityManagerService) {
1340 mActivityManagerService = activityManagerService;
1341 }
1342
1343 @Override
1344 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1345 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001346 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1347 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1348 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 }
1350 }
1351 }
1352
1353 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001354 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 File dataDir = Environment.getDataDirectory();
1357 File systemDir = new File(dataDir, "system");
1358 systemDir.mkdirs();
1359 mBatteryStatsService = new BatteryStatsService(new File(
1360 systemDir, "batterystats.bin").toString());
1361 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001362 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001363 mOnBattery = DEBUG_POWER ? true
1364 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001365 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001367 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001368 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369
Jack Palevichb90d28c2009-07-22 15:35:24 -07001370 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1371 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1372
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001373 mConfiguration.setToDefaults();
1374 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 mProcessStats.init();
1376
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001377 mCompatModePackages = new CompatModePackages(this, systemDir);
1378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 // Add ourself to the Watchdog monitors.
1380 Watchdog.getInstance().addMonitor(this);
1381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 mProcessStatsThread = new Thread("ProcessStats") {
1383 public void run() {
1384 while (true) {
1385 try {
1386 try {
1387 synchronized(this) {
1388 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001389 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 // + ", write delay=" + nextWriteDelay);
1393 if (nextWriteDelay < nextCpuDelay) {
1394 nextCpuDelay = nextWriteDelay;
1395 }
1396 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001397 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 this.wait(nextCpuDelay);
1399 }
1400 }
1401 } catch (InterruptedException e) {
1402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 updateCpuStatsNow();
1404 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001405 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
1407 }
1408 }
1409 };
1410 mProcessStatsThread.start();
1411 }
1412
1413 @Override
1414 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1415 throws RemoteException {
1416 try {
1417 return super.onTransact(code, data, reply, flags);
1418 } catch (RuntimeException e) {
1419 // The activity manager only throws security exceptions, so let's
1420 // log all others.
1421 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424 throw e;
1425 }
1426 }
1427
1428 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001429 final long now = SystemClock.uptimeMillis();
1430 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1431 return;
1432 }
1433 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1434 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 mProcessStatsThread.notify();
1436 }
1437 }
1438 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 void updateCpuStatsNow() {
1441 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001442 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 final long now = SystemClock.uptimeMillis();
1444 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001447 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1448 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 haveNewCpuStats = true;
1450 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001451 //Slog.i(TAG, mProcessStats.printCurrentState());
1452 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 // + mProcessStats.getTotalCpuPercent() + "%");
1454
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 if ("true".equals(SystemProperties.get("events.cpu"))) {
1457 int user = mProcessStats.getLastUserTime();
1458 int system = mProcessStats.getLastSystemTime();
1459 int iowait = mProcessStats.getLastIoWaitTime();
1460 int irq = mProcessStats.getLastIrqTime();
1461 int softIrq = mProcessStats.getLastSoftIrqTime();
1462 int idle = mProcessStats.getLastIdleTime();
1463
1464 int total = user + system + iowait + irq + softIrq + idle;
1465 if (total == 0) total = 1;
1466
Doug Zongker2bec3d42009-12-04 12:52:44 -08001467 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 ((user+system+iowait+irq+softIrq) * 100) / total,
1469 (user * 100) / total,
1470 (system * 100) / total,
1471 (iowait * 100) / total,
1472 (irq * 100) / total,
1473 (softIrq * 100) / total);
1474 }
1475 }
1476
Amith Yamasanie43530a2009-08-21 13:11:37 -07001477 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001478 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001479 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 synchronized(mPidsSelfLocked) {
1481 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001482 if (mOnBattery) {
1483 int perc = bstats.startAddingCpuLocked();
1484 int totalUTime = 0;
1485 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001486 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001488 ProcessStats.Stats st = mProcessStats.getStats(i);
1489 if (!st.working) {
1490 continue;
1491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001493 int otherUTime = (st.rel_utime*perc)/100;
1494 int otherSTime = (st.rel_stime*perc)/100;
1495 totalUTime += otherUTime;
1496 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 if (pr != null) {
1498 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001499 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1500 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001502 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 } else {
1504 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001505 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001506 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001507 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1508 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001509 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 }
1512 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001513 bstats.finishAddingCpuLocked(perc, totalUTime,
1514 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 }
1517 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1520 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001521 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 }
1523 }
1524 }
1525 }
1526
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001527 @Override
1528 public void batteryNeedsCpuUpdate() {
1529 updateCpuStatsNow();
1530 }
1531
1532 @Override
1533 public void batteryPowerChanged(boolean onBattery) {
1534 // When plugging in, update the CPU stats first before changing
1535 // the plug state.
1536 updateCpuStatsNow();
1537 synchronized (this) {
1538 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001539 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001540 }
1541 }
1542 }
1543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 /**
1545 * Initialize the application bind args. These are passed to each
1546 * process when the bindApplication() IPC is sent to the process. They're
1547 * lazily setup to make sure the services are running when they're asked for.
1548 */
1549 private HashMap<String, IBinder> getCommonServicesLocked() {
1550 if (mAppBindArgs == null) {
1551 mAppBindArgs = new HashMap<String, IBinder>();
1552
1553 // Setup the application init args
1554 mAppBindArgs.put("package", ServiceManager.getService("package"));
1555 mAppBindArgs.put("window", ServiceManager.getService("window"));
1556 mAppBindArgs.put(Context.ALARM_SERVICE,
1557 ServiceManager.getService(Context.ALARM_SERVICE));
1558 }
1559 return mAppBindArgs;
1560 }
1561
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001562 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if (mFocusedActivity != r) {
1564 mFocusedActivity = r;
1565 mWindowManager.setFocusedApp(r, true);
1566 }
1567 }
1568
Dianne Hackborn906497c2010-05-10 15:57:38 -07001569 private final void updateLruProcessInternalLocked(ProcessRecord app,
1570 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001572 int lrui = mLruProcesses.indexOf(app);
1573 if (lrui >= 0) mLruProcesses.remove(lrui);
1574
1575 int i = mLruProcesses.size()-1;
1576 int skipTop = 0;
1577
Dianne Hackborn906497c2010-05-10 15:57:38 -07001578 app.lruSeq = mLruSeq;
1579
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001580 // compute the new weight for this process.
1581 if (updateActivityTime) {
1582 app.lastActivityTime = SystemClock.uptimeMillis();
1583 }
1584 if (app.activities.size() > 0) {
1585 // If this process has activities, we more strongly want to keep
1586 // it around.
1587 app.lruWeight = app.lastActivityTime;
1588 } else if (app.pubProviders.size() > 0) {
1589 // If this process contains content providers, we want to keep
1590 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001591 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001592 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001593 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001594 } else {
1595 // If this process doesn't have activities, we less strongly
1596 // want to keep it around, and generally want to avoid getting
1597 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001598 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001599 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001600 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001601 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001603 while (i >= 0) {
1604 ProcessRecord p = mLruProcesses.get(i);
1605 // If this app shouldn't be in front of the first N background
1606 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001607 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001608 skipTop--;
1609 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001610 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001611 mLruProcesses.add(i+1, app);
1612 break;
1613 }
1614 i--;
1615 }
1616 if (i < 0) {
1617 mLruProcesses.add(0, app);
1618 }
1619
Dianne Hackborn906497c2010-05-10 15:57:38 -07001620 // If the app is currently using a content provider or service,
1621 // bump those processes as well.
1622 if (app.connections.size() > 0) {
1623 for (ConnectionRecord cr : app.connections) {
1624 if (cr.binding != null && cr.binding.service != null
1625 && cr.binding.service.app != null
1626 && cr.binding.service.app.lruSeq != mLruSeq) {
1627 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1628 updateActivityTime, i+1);
1629 }
1630 }
1631 }
1632 if (app.conProviders.size() > 0) {
1633 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1634 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1635 updateLruProcessInternalLocked(cpr.app, oomAdj,
1636 updateActivityTime, i+1);
1637 }
1638 }
1639 }
1640
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if (oomAdj) {
1643 updateOomAdjLocked();
1644 }
1645 }
1646
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001647 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001648 boolean oomAdj, boolean updateActivityTime) {
1649 mLruSeq++;
1650 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1651 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001652
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001653 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 String processName, int uid) {
1655 if (uid == Process.SYSTEM_UID) {
1656 // The system gets to run in any process. If there are multiple
1657 // processes with the same uid, just pick the first (this
1658 // should never happen).
1659 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1660 processName);
1661 return procs != null ? procs.valueAt(0) : null;
1662 }
1663 ProcessRecord proc = mProcessNames.get(processName, uid);
1664 return proc;
1665 }
1666
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001667 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001668 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001669 try {
1670 if (pm.performDexOpt(packageName)) {
1671 mDidDexOpt = true;
1672 }
1673 } catch (RemoteException e) {
1674 }
1675 }
1676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 int transit = mWindowManager.getPendingAppTransition();
1679 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1680 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1681 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1682 }
1683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001686 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1688 // We don't have to do anything more if:
1689 // (1) There is an existing application record; and
1690 // (2) The caller doesn't think it is dead, OR there is no thread
1691 // object attached to it so we know it couldn't have crashed; and
1692 // (3) There is a pid assigned to it, so it is either starting or
1693 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001694 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 + " app=" + app + " knownToBeDead=" + knownToBeDead
1696 + " thread=" + (app != null ? app.thread : null)
1697 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001698 if (app != null && app.pid > 0) {
1699 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001700 // We already have the app running, or are waiting for it to
1701 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001702 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001703 // If this is a new package in the process, add the package to the list
1704 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001705 return app;
1706 } else {
1707 // An application record is attached to a previous process,
1708 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001709 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001710 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 String hostingNameStr = hostingName != null
1715 ? hostingName.flattenToShortString() : null;
1716
1717 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1718 // If we are in the background, then check to see if this process
1719 // is bad. If so, we will just silently fail.
1720 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001721 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1722 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 return null;
1724 }
1725 } else {
1726 // When the user is explicitly starting a process, then clear its
1727 // crash count so that we won't make it bad until they see at
1728 // least one crash dialog again, and make the process good again
1729 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001730 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1731 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 mProcessCrashTimes.remove(info.processName, info.uid);
1733 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001734 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 info.processName);
1736 mBadProcesses.remove(info.processName, info.uid);
1737 if (app != null) {
1738 app.bad = false;
1739 }
1740 }
1741 }
1742
1743 if (app == null) {
1744 app = newProcessRecordLocked(null, info, processName);
1745 mProcessNames.put(processName, info.uid, app);
1746 } else {
1747 // If this is a new package in the process, add the package to the list
1748 app.addPackage(info.packageName);
1749 }
1750
1751 // If the system is not ready yet, then hold off on starting this
1752 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001753 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001754 && !isAllowedWhileBooting(info)
1755 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 if (!mProcessesOnHold.contains(app)) {
1757 mProcessesOnHold.add(app);
1758 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001759 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 return app;
1761 }
1762
1763 startProcessLocked(app, hostingType, hostingNameStr);
1764 return (app.pid != 0) ? app : null;
1765 }
1766
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001767 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1769 }
1770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 private final void startProcessLocked(ProcessRecord app,
1772 String hostingType, String hostingNameStr) {
1773 if (app.pid > 0 && app.pid != MY_PID) {
1774 synchronized (mPidsSelfLocked) {
1775 mPidsSelfLocked.remove(app.pid);
1776 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1777 }
1778 app.pid = 0;
1779 }
1780
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001781 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1782 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 mProcessesOnHold.remove(app);
1784
1785 updateCpuStats();
1786
1787 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1788 mProcDeaths[0] = 0;
1789
1790 try {
1791 int uid = app.info.uid;
1792 int[] gids = null;
1793 try {
1794 gids = mContext.getPackageManager().getPackageGids(
1795 app.info.packageName);
1796 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001797 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 }
1799 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1800 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1801 && mTopComponent != null
1802 && app.processName.equals(mTopComponent.getPackageName())) {
1803 uid = 0;
1804 }
1805 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1806 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1807 uid = 0;
1808 }
1809 }
1810 int debugFlags = 0;
1811 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1812 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001813 // Also turn on CheckJNI for debuggable apps. It's quite
1814 // awkward to turn on otherwise.
1815 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001817 // Run the app in safe mode if its manifest requests so or the
1818 // system is booted in safe mode.
1819 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1820 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001821 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1824 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1825 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001826 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1827 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 if ("1".equals(SystemProperties.get("debug.assert"))) {
1830 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1831 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001832
1833 // Start the process. It will either succeed and return a result containing
1834 // the PID of the new process, or else throw a RuntimeException.
1835 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001836 app.processName, uid, uid, gids, debugFlags,
1837 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1840 synchronized (bs) {
1841 if (bs.isOnBattery()) {
1842 app.batteryStats.incStartsLocked();
1843 }
1844 }
1845
Jeff Brown3f9dd282011-07-08 20:02:19 -07001846 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 app.processName, hostingType,
1848 hostingNameStr != null ? hostingNameStr : "");
1849
1850 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001851 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001854 StringBuilder buf = mStringBuilder;
1855 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 buf.append("Start proc ");
1857 buf.append(app.processName);
1858 buf.append(" for ");
1859 buf.append(hostingType);
1860 if (hostingNameStr != null) {
1861 buf.append(" ");
1862 buf.append(hostingNameStr);
1863 }
1864 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001865 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 buf.append(" uid=");
1867 buf.append(uid);
1868 buf.append(" gids={");
1869 if (gids != null) {
1870 for (int gi=0; gi<gids.length; gi++) {
1871 if (gi != 0) buf.append(", ");
1872 buf.append(gids[gi]);
1873
1874 }
1875 }
1876 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001877 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001878 app.pid = startResult.pid;
1879 app.usingWrapper = startResult.usingWrapper;
1880 app.removed = false;
1881 synchronized (mPidsSelfLocked) {
1882 this.mPidsSelfLocked.put(startResult.pid, app);
1883 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1884 msg.obj = app;
1885 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1886 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 }
1888 } catch (RuntimeException e) {
1889 // XXX do better error recovery.
1890 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001891 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 }
1893 }
1894
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001895 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 if (resumed) {
1897 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1898 } else {
1899 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1900 }
1901 }
1902
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001903 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001904 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1905 && mTopAction == null) {
1906 // We are running in factory test mode, but unable to find
1907 // the factory test app, so just sit around displaying the
1908 // error message and don't try to start anything.
1909 return false;
1910 }
1911 Intent intent = new Intent(
1912 mTopAction,
1913 mTopData != null ? Uri.parse(mTopData) : null);
1914 intent.setComponent(mTopComponent);
1915 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1916 intent.addCategory(Intent.CATEGORY_HOME);
1917 }
1918 ActivityInfo aInfo =
1919 intent.resolveActivityInfo(mContext.getPackageManager(),
1920 STOCK_PM_FLAGS);
1921 if (aInfo != null) {
1922 intent.setComponent(new ComponentName(
1923 aInfo.applicationInfo.packageName, aInfo.name));
1924 // Don't do this if the home app is currently being
1925 // instrumented.
1926 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1927 aInfo.applicationInfo.uid);
1928 if (app == null || app.instrumentationClass == null) {
1929 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001930 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001931 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001932 }
1933 }
1934
1935
1936 return true;
1937 }
1938
1939 /**
1940 * Starts the "new version setup screen" if appropriate.
1941 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001942 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001943 // Only do this once per boot.
1944 if (mCheckedForSetup) {
1945 return;
1946 }
1947
1948 // We will show this screen if the current one is a different
1949 // version than the last one shown, and we are not running in
1950 // low-level factory test mode.
1951 final ContentResolver resolver = mContext.getContentResolver();
1952 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1953 Settings.Secure.getInt(resolver,
1954 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1955 mCheckedForSetup = true;
1956
1957 // See if we should be showing the platform update setup UI.
1958 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1959 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1960 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1961
1962 // We don't allow third party apps to replace this.
1963 ResolveInfo ri = null;
1964 for (int i=0; ris != null && i<ris.size(); i++) {
1965 if ((ris.get(i).activityInfo.applicationInfo.flags
1966 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1967 ri = ris.get(i);
1968 break;
1969 }
1970 }
1971
1972 if (ri != null) {
1973 String vers = ri.activityInfo.metaData != null
1974 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1975 : null;
1976 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1977 vers = ri.activityInfo.applicationInfo.metaData.getString(
1978 Intent.METADATA_SETUP_VERSION);
1979 }
1980 String lastVers = Settings.Secure.getString(
1981 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1982 if (vers != null && !vers.equals(lastVers)) {
1983 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1984 intent.setComponent(new ComponentName(
1985 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001986 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001987 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001988 }
1989 }
1990 }
1991 }
1992
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001993 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001994 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001995 }
1996
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001997 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001998 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001999 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2000 }
2001 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002002
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002003 public void setFrontActivityScreenCompatMode(int mode) {
2004 synchronized (this) {
2005 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2006 }
2007 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002008
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002009 public int getPackageScreenCompatMode(String packageName) {
2010 synchronized (this) {
2011 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2012 }
2013 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002014
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002015 public void setPackageScreenCompatMode(String packageName, int mode) {
2016 synchronized (this) {
2017 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002018 }
2019 }
2020
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002021 public boolean getPackageAskScreenCompat(String packageName) {
2022 synchronized (this) {
2023 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2024 }
2025 }
2026
2027 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2028 synchronized (this) {
2029 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2030 }
2031 }
2032
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002033 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002034 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002035
2036 final int identHash = System.identityHashCode(r);
2037 updateUsageStats(r, true);
2038
2039 int i = mWatchers.beginBroadcast();
2040 while (i > 0) {
2041 i--;
2042 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2043 if (w != null) {
2044 try {
2045 w.activityResuming(identHash);
2046 } catch (RemoteException e) {
2047 }
2048 }
2049 }
2050 mWatchers.finishBroadcast();
2051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052
Jeff Sharkeya4620792011-05-20 15:29:23 -07002053 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2054 int i = mProcessObservers.beginBroadcast();
2055 while (i > 0) {
2056 i--;
2057 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2058 if (observer != null) {
2059 try {
2060 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2061 } catch (RemoteException e) {
2062 }
2063 }
2064 }
2065 mProcessObservers.finishBroadcast();
2066 }
2067
2068 private void dispatchProcessDied(int pid, int uid) {
2069 int i = mProcessObservers.beginBroadcast();
2070 while (i > 0) {
2071 i--;
2072 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2073 if (observer != null) {
2074 try {
2075 observer.onProcessDied(pid, uid);
2076 } catch (RemoteException e) {
2077 }
2078 }
2079 }
2080 mProcessObservers.finishBroadcast();
2081 }
2082
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002083 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002084 final int N = mPendingActivityLaunches.size();
2085 if (N <= 0) {
2086 return;
2087 }
2088 for (int i=0; i<N; i++) {
2089 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002090 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002091 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2092 doResume && i == (N-1));
2093 }
2094 mPendingActivityLaunches.clear();
2095 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002096
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002097 public final int startActivity(IApplicationThread caller,
2098 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2099 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002100 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2101 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002102 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002103 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002104 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2105 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002106 }
2107
2108 public final WaitResult startActivityAndWait(IApplicationThread caller,
2109 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2110 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002111 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2112 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002113 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002114 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002115 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002116 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2117 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002118 return res;
2119 }
2120
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002121 public final int startActivityWithConfig(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
2124 String resultWho, int requestCode, boolean onlyIfNeeded,
2125 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002126 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002127 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002128 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002129 }
2130
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002131 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002132 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002133 IBinder resultTo, String resultWho, int requestCode,
2134 int flagsMask, int flagsValues) {
2135 // Refuse possible leaked file descriptors
2136 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2137 throw new IllegalArgumentException("File descriptors passed in Intent");
2138 }
2139
2140 IIntentSender sender = intent.getTarget();
2141 if (!(sender instanceof PendingIntentRecord)) {
2142 throw new IllegalArgumentException("Bad PendingIntent object");
2143 }
2144
2145 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002146
2147 synchronized (this) {
2148 // If this is coming from the currently resumed activity, it is
2149 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002150 if (mMainStack.mResumedActivity != null
2151 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002152 Binder.getCallingUid()) {
2153 mAppSwitchesAllowedTime = 0;
2154 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002155 }
2156
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002157 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002158 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2159 }
2160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 public boolean startNextMatchingActivity(IBinder callingActivity,
2162 Intent intent) {
2163 // Refuse possible leaked file descriptors
2164 if (intent != null && intent.hasFileDescriptors() == true) {
2165 throw new IllegalArgumentException("File descriptors passed in Intent");
2166 }
2167
2168 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002169 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2170 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 return false;
2172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 if (r.app == null || r.app.thread == null) {
2174 // The caller is not running... d'oh!
2175 return false;
2176 }
2177 intent = new Intent(intent);
2178 // The caller is not allowed to change the data.
2179 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2180 // And we are resetting to find the next component...
2181 intent.setComponent(null);
2182
2183 ActivityInfo aInfo = null;
2184 try {
2185 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002186 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002188 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189
2190 // Look for the original activity in the list...
2191 final int N = resolves != null ? resolves.size() : 0;
2192 for (int i=0; i<N; i++) {
2193 ResolveInfo rInfo = resolves.get(i);
2194 if (rInfo.activityInfo.packageName.equals(r.packageName)
2195 && rInfo.activityInfo.name.equals(r.info.name)) {
2196 // We found the current one... the next matching is
2197 // after it.
2198 i++;
2199 if (i<N) {
2200 aInfo = resolves.get(i).activityInfo;
2201 }
2202 break;
2203 }
2204 }
2205 } catch (RemoteException e) {
2206 }
2207
2208 if (aInfo == null) {
2209 // Nobody who is next!
2210 return false;
2211 }
2212
2213 intent.setComponent(new ComponentName(
2214 aInfo.applicationInfo.packageName, aInfo.name));
2215 intent.setFlags(intent.getFlags()&~(
2216 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2217 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2218 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2219 Intent.FLAG_ACTIVITY_NEW_TASK));
2220
2221 // Okay now we need to start the new activity, replacing the
2222 // currently running activity. This is a little tricky because
2223 // we want to start the new one as if the current one is finished,
2224 // but not finish the current one first so that there is no flicker.
2225 // And thus...
2226 final boolean wasFinishing = r.finishing;
2227 r.finishing = true;
2228
2229 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002230 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 final String resultWho = r.resultWho;
2232 final int requestCode = r.requestCode;
2233 r.resultTo = null;
2234 if (resultTo != null) {
2235 resultTo.removeResultsLocked(r, resultWho, requestCode);
2236 }
2237
2238 final long origId = Binder.clearCallingIdentity();
2239 // XXX we are not dealing with propagating grantedUriPermissions...
2240 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002241 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002243 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 Binder.restoreCallingIdentity(origId);
2245
2246 r.finishing = wasFinishing;
2247 if (res != START_SUCCESS) {
2248 return false;
2249 }
2250 return true;
2251 }
2252 }
2253
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002254 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 Intent intent, String resolvedType, IBinder resultTo,
2256 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002257
2258 // This is so super not safe, that only the system (or okay root)
2259 // can do it.
2260 final int callingUid = Binder.getCallingUid();
2261 if (callingUid != 0 && callingUid != Process.myUid()) {
2262 throw new SecurityException(
2263 "startActivityInPackage only available to the system");
2264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002266 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002267 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2268 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002269 }
2270
2271 public final int startActivities(IApplicationThread caller,
2272 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2273 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2274 }
2275
2276 public final int startActivitiesInPackage(int uid,
2277 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2278
2279 // This is so super not safe, that only the system (or okay root)
2280 // can do it.
2281 final int callingUid = Binder.getCallingUid();
2282 if (callingUid != 0 && callingUid != Process.myUid()) {
2283 throw new SecurityException(
2284 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002287 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 }
2289
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002290 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002292 // Quick case: check if the top-most recent task is the same.
2293 if (N > 0 && mRecentTasks.get(0) == task) {
2294 return;
2295 }
2296 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 for (int i=0; i<N; i++) {
2298 TaskRecord tr = mRecentTasks.get(i);
2299 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2300 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2301 mRecentTasks.remove(i);
2302 i--;
2303 N--;
2304 if (task.intent == null) {
2305 // If the new recent task we are adding is not fully
2306 // specified, then replace it with the existing recent task.
2307 task = tr;
2308 }
2309 }
2310 }
2311 if (N >= MAX_RECENT_TASKS) {
2312 mRecentTasks.remove(N-1);
2313 }
2314 mRecentTasks.add(0, task);
2315 }
2316
2317 public void setRequestedOrientation(IBinder token,
2318 int requestedOrientation) {
2319 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002320 ActivityRecord r = mMainStack.isInStackLocked(token);
2321 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 return;
2323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 final long origId = Binder.clearCallingIdentity();
2325 mWindowManager.setAppOrientation(r, requestedOrientation);
2326 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 r.mayFreezeScreenLocked(r.app) ? r : null);
2329 if (config != null) {
2330 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002331 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002332 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 }
2334 }
2335 Binder.restoreCallingIdentity(origId);
2336 }
2337 }
2338
2339 public int getRequestedOrientation(IBinder token) {
2340 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002341 ActivityRecord r = mMainStack.isInStackLocked(token);
2342 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 return mWindowManager.getAppOrientation(r);
2346 }
2347 }
2348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 /**
2350 * This is the internal entry point for handling Activity.finish().
2351 *
2352 * @param token The Binder token referencing the Activity we want to finish.
2353 * @param resultCode Result code, if any, from this Activity.
2354 * @param resultData Result data (Intent), if any, from this Activity.
2355 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002356 * @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 -08002357 */
2358 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2359 // Refuse possible leaked file descriptors
2360 if (resultData != null && resultData.hasFileDescriptors() == true) {
2361 throw new IllegalArgumentException("File descriptors passed in Intent");
2362 }
2363
2364 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002365 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002367 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (next != null) {
2369 // ask watcher if this is allowed
2370 boolean resumeOK = true;
2371 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002372 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002374 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
2376
2377 if (!resumeOK) {
2378 return false;
2379 }
2380 }
2381 }
2382 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002383 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 resultData, "app-request");
2385 Binder.restoreCallingIdentity(origId);
2386 return res;
2387 }
2388 }
2389
Dianne Hackborn860755f2010-06-03 18:47:52 -07002390 public final void finishHeavyWeightApp() {
2391 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2392 != PackageManager.PERMISSION_GRANTED) {
2393 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2394 + Binder.getCallingPid()
2395 + ", uid=" + Binder.getCallingUid()
2396 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2397 Slog.w(TAG, msg);
2398 throw new SecurityException(msg);
2399 }
2400
2401 synchronized(this) {
2402 if (mHeavyWeightProcess == null) {
2403 return;
2404 }
2405
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002406 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002407 mHeavyWeightProcess.activities);
2408 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002409 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002410 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002411 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002412 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002413 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 null, "finish-heavy");
2415 }
2416 }
2417 }
2418
2419 mHeavyWeightProcess = null;
2420 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2421 }
2422 }
2423
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002424 public void crashApplication(int uid, int initialPid, String packageName,
2425 String message) {
2426 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2427 != PackageManager.PERMISSION_GRANTED) {
2428 String msg = "Permission Denial: crashApplication() from pid="
2429 + Binder.getCallingPid()
2430 + ", uid=" + Binder.getCallingUid()
2431 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2432 Slog.w(TAG, msg);
2433 throw new SecurityException(msg);
2434 }
2435
2436 synchronized(this) {
2437 ProcessRecord proc = null;
2438
2439 // Figure out which process to kill. We don't trust that initialPid
2440 // still has any relation to current pids, so must scan through the
2441 // list.
2442 synchronized (mPidsSelfLocked) {
2443 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2444 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2445 if (p.info.uid != uid) {
2446 continue;
2447 }
2448 if (p.pid == initialPid) {
2449 proc = p;
2450 break;
2451 }
2452 for (String str : p.pkgList) {
2453 if (str.equals(packageName)) {
2454 proc = p;
2455 }
2456 }
2457 }
2458 }
2459
2460 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002461 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002462 + " initialPid=" + initialPid
2463 + " packageName=" + packageName);
2464 return;
2465 }
2466
2467 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002468 if (proc.pid == Process.myPid()) {
2469 Log.w(TAG, "crashApplication: trying to crash self!");
2470 return;
2471 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002472 long ident = Binder.clearCallingIdentity();
2473 try {
2474 proc.thread.scheduleCrash(message);
2475 } catch (RemoteException e) {
2476 }
2477 Binder.restoreCallingIdentity(ident);
2478 }
2479 }
2480 }
2481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482 public final void finishSubActivity(IBinder token, String resultWho,
2483 int requestCode) {
2484 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002485 ActivityRecord self = mMainStack.isInStackLocked(token);
2486 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 return;
2488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489
2490 final long origId = Binder.clearCallingIdentity();
2491
2492 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2494 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 if (r.resultTo == self && r.requestCode == requestCode) {
2496 if ((r.resultWho == null && resultWho == null) ||
2497 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002498 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 Activity.RESULT_CANCELED, null, "request-sub");
2500 }
2501 }
2502 }
2503
2504 Binder.restoreCallingIdentity(origId);
2505 }
2506 }
2507
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002508 public boolean willActivityBeVisible(IBinder token) {
2509 synchronized(this) {
2510 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2512 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002513 if (r == token) {
2514 return true;
2515 }
2516 if (r.fullscreen && !r.finishing) {
2517 return false;
2518 }
2519 }
2520 return true;
2521 }
2522 }
2523
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002524 public void overridePendingTransition(IBinder token, String packageName,
2525 int enterAnim, int exitAnim) {
2526 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002527 ActivityRecord self = mMainStack.isInStackLocked(token);
2528 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002529 return;
2530 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002531
2532 final long origId = Binder.clearCallingIdentity();
2533
2534 if (self.state == ActivityState.RESUMED
2535 || self.state == ActivityState.PAUSING) {
2536 mWindowManager.overridePendingAppTransition(packageName,
2537 enterAnim, exitAnim);
2538 }
2539
2540 Binder.restoreCallingIdentity(origId);
2541 }
2542 }
2543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 * Main function for removing an existing process from the activity manager
2546 * as a result of that process going away. Clears out all connections
2547 * to the process.
2548 */
2549 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002550 boolean restarting, boolean allowRestart) {
2551 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002553 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 }
2555
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002556 if (mProfileProc == app) {
2557 clearProfilerLocked();
2558 }
2559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002561 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2562 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2563 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002565 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2566 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 }
2568
2569 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002570 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571
2572 boolean atTop = true;
2573 boolean hasVisibleActivities = false;
2574
2575 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002577 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 TAG, "Removing app " + app + " from history with " + i + " entries");
2579 while (i > 0) {
2580 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002581 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002582 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2584 if (r.app == app) {
2585 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002586 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 TAG, "Removing this entry! frozen=" + r.haveState
2588 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002589 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002590 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002591 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 mWindowManager.removeAppToken(r);
2593 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597
2598 } else {
2599 // We have the current state for this activity, so
2600 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Keeping entry, setting app to null");
2603 if (r.visible) {
2604 hasVisibleActivities = true;
2605 }
2606 r.app = null;
2607 r.nowVisible = false;
2608 if (!r.haveState) {
2609 r.icicle = null;
2610 }
2611 }
2612
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002613 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 }
2615 atTop = false;
2616 }
2617
2618 app.activities.clear();
2619
2620 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002621 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 + " running instrumentation " + app.instrumentationClass);
2623 Bundle info = new Bundle();
2624 info.putString("shortMsg", "Process crashed.");
2625 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2626 }
2627
2628 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 // If there was nothing to resume, and we are not already
2631 // restarting this process, but there is a visible activity that
2632 // is hosted by the process... then make sure all visible
2633 // activities are running, taking care of restarting this
2634 // process.
2635 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638 }
2639 }
2640 }
2641
2642 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2643 IBinder threadBinder = thread.asBinder();
2644
2645 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002646 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2647 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2649 return i;
2650 }
2651 }
2652 return -1;
2653 }
2654
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002655 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 IApplicationThread thread) {
2657 if (thread == null) {
2658 return null;
2659 }
2660
2661 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002662 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 }
2664
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002665 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 IApplicationThread thread) {
2667
2668 mProcDeaths[0]++;
2669
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002670 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2671 synchronized (stats) {
2672 stats.noteProcessDiedLocked(app.info.uid, pid);
2673 }
2674
Magnus Edlund7bb25812010-02-24 15:45:06 +01002675 // Clean up already done if the process has been re-started.
2676 if (app.pid == pid && app.thread != null &&
2677 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002678 if (!app.killedBackground) {
2679 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2680 + ") has died.");
2681 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002682 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002683 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684 TAG, "Dying app: " + app + ", pid: " + pid
2685 + ", thread: " + thread.asBinder());
2686 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002687 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688
2689 if (doLowMem) {
2690 // If there are no longer any background processes running,
2691 // and the app that died was not running instrumentation,
2692 // then tell everyone we are now low on memory.
2693 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002694 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2695 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002696 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 haveBg = true;
2698 break;
2699 }
2700 }
2701
2702 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002704 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002705 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2706 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002707 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002708 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2709 // The low memory report is overriding any current
2710 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002711 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002712 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002713 rec.lastRequestedGc = 0;
2714 } else {
2715 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002717 rec.reportLowMemory = true;
2718 rec.lastLowMemory = now;
2719 mProcessesToGc.remove(rec);
2720 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002723 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002726 } else if (app.pid != pid) {
2727 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002729 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002731 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002732 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 + thread.asBinder());
2734 }
2735 }
2736
Dan Egnor42471dd2010-01-07 17:25:22 -08002737 /**
2738 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002739 * @param clearTraces causes the dump file to be erased prior to the new
2740 * traces being written, if true; when false, the new traces will be
2741 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002742 * @param firstPids of dalvik VM processes to dump stack traces for first
2743 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002744 * @return file containing stack traces, or null if no dump file is configured
2745 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002746 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2747 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002748 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2749 if (tracesPath == null || tracesPath.length() == 0) {
2750 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002752
2753 File tracesFile = new File(tracesPath);
2754 try {
2755 File tracesDir = tracesFile.getParentFile();
2756 if (!tracesDir.exists()) tracesFile.mkdirs();
2757 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2758
Christopher Tate6ee412d2010-05-28 12:01:56 -07002759 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002760 tracesFile.createNewFile();
2761 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2762 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002764 return null;
2765 }
2766
2767 // Use a FileObserver to detect when traces finish writing.
2768 // The order of traces is considered important to maintain for legibility.
2769 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2770 public synchronized void onEvent(int event, String path) { notify(); }
2771 };
2772
2773 try {
2774 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002775
2776 // First collect all of the stacks of the most important pids.
2777 try {
2778 int num = firstPids.size();
2779 for (int i = 0; i < num; i++) {
2780 synchronized (observer) {
2781 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2782 observer.wait(200); // Wait for write-close, give up after 200msec
2783 }
2784 }
2785 } catch (InterruptedException e) {
2786 Log.wtf(TAG, e);
2787 }
2788
2789 // Next measure CPU usage.
2790 if (processStats != null) {
2791 processStats.init();
2792 System.gc();
2793 processStats.update();
2794 try {
2795 synchronized (processStats) {
2796 processStats.wait(500); // measure over 1/2 second.
2797 }
2798 } catch (InterruptedException e) {
2799 }
2800 processStats.update();
2801
2802 // We'll take the stack crawls of just the top apps using CPU.
2803 final int N = processStats.countWorkingStats();
2804 int numProcs = 0;
2805 for (int i=0; i<N && numProcs<5; i++) {
2806 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2807 if (lastPids.indexOfKey(stats.pid) >= 0) {
2808 numProcs++;
2809 try {
2810 synchronized (observer) {
2811 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2812 observer.wait(200); // Wait for write-close, give up after 200msec
2813 }
2814 } catch (InterruptedException e) {
2815 Log.wtf(TAG, e);
2816 }
2817
2818 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002819 }
2820 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002821
2822 return tracesFile;
2823
Dan Egnor42471dd2010-01-07 17:25:22 -08002824 } finally {
2825 observer.stopWatching();
2826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 }
2828
Jeff Brown4d94a762010-09-23 11:33:28 -07002829 private final class AppNotResponding implements Runnable {
2830 private final ProcessRecord mApp;
2831 private final String mAnnotation;
2832
2833 public AppNotResponding(ProcessRecord app, String annotation) {
2834 mApp = app;
2835 mAnnotation = annotation;
2836 }
2837
2838 @Override
2839 public void run() {
2840 appNotResponding(mApp, null, null, mAnnotation);
2841 }
2842 }
2843
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002844 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2845 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2847 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2848
Dianne Hackborn287952c2010-09-22 22:34:31 -07002849 if (mController != null) {
2850 try {
2851 // 0 == continue, -1 = kill process immediately
2852 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2853 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2854 } catch (RemoteException e) {
2855 mController = null;
2856 }
2857 }
2858
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002859 long anrTime = SystemClock.uptimeMillis();
2860 if (MONITOR_CPU_USAGE) {
2861 updateCpuStatsNow();
2862 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002863
2864 synchronized (this) {
2865 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2866 if (mShuttingDown) {
2867 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2868 return;
2869 } else if (app.notResponding) {
2870 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2871 return;
2872 } else if (app.crashing) {
2873 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2874 return;
2875 }
2876
2877 // In case we come through here for the same app before completing
2878 // this one, mark as anring now so we will bail out.
2879 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002880
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881 // Log the ANR to the event log.
2882 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2883 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002884
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002885 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002886 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 int parentPid = app.pid;
2889 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002890 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002891
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002892 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002893
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002894 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2895 ProcessRecord r = mLruProcesses.get(i);
2896 if (r != null && r.thread != null) {
2897 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002898 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2899 if (r.persistent) {
2900 firstPids.add(pid);
2901 } else {
2902 lastPids.put(pid, Boolean.TRUE);
2903 }
2904 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
2907 }
2908
Dan Egnor42471dd2010-01-07 17:25:22 -08002909 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002910 StringBuilder info = mStringBuilder;
2911 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002912 info.append("ANR in ").append(app.processName);
2913 if (activity != null && activity.shortComponentName != null) {
2914 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002915 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002916 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002918 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002920 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002921 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923
Dianne Hackborn287952c2010-09-22 22:34:31 -07002924 final ProcessStats processStats = new ProcessStats(true);
2925
2926 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2927
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 String cpuInfo = null;
2929 if (MONITOR_CPU_USAGE) {
2930 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002931 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002935 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 info.append(processStats.printCurrentState(anrTime));
2939
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002941 if (tracesFile == null) {
2942 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2943 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2944 }
2945
2946 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2947
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002948 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002950 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2951 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2954 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 }
2956 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002957 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 }
2959 }
2960
Dan Egnor42471dd2010-01-07 17:25:22 -08002961 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2962 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2963 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964
2965 synchronized (this) {
2966 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002967 Slog.w(TAG, "Killing " + app + ": background ANR");
2968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2969 app.processName, app.setAdj, "background ANR");
2970 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002971 return;
2972 }
2973
2974 // Set the app's notResponding state, and look up the errorReportReceiver
2975 makeAppNotRespondingLocked(app,
2976 activity != null ? activity.shortComponentName : null,
2977 annotation != null ? "ANR " + annotation : "ANR",
2978 info.toString());
2979
2980 // Bring up the infamous App Not Responding dialog
2981 Message msg = Message.obtain();
2982 HashMap map = new HashMap();
2983 msg.what = SHOW_NOT_RESPONDING_MSG;
2984 msg.obj = map;
2985 map.put("app", app);
2986 if (activity != null) {
2987 map.put("activity", activity);
2988 }
2989
2990 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002994 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2995 if (!mLaunchWarningShown) {
2996 mLaunchWarningShown = true;
2997 mHandler.post(new Runnable() {
2998 @Override
2999 public void run() {
3000 synchronized (ActivityManagerService.this) {
3001 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3002 d.show();
3003 mHandler.postDelayed(new Runnable() {
3004 @Override
3005 public void run() {
3006 synchronized (ActivityManagerService.this) {
3007 d.dismiss();
3008 mLaunchWarningShown = false;
3009 }
3010 }
3011 }, 4000);
3012 }
3013 }
3014 });
3015 }
3016 }
3017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 public boolean clearApplicationUserData(final String packageName,
3019 final IPackageDataObserver observer) {
3020 int uid = Binder.getCallingUid();
3021 int pid = Binder.getCallingPid();
3022 long callingId = Binder.clearCallingIdentity();
3023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003024 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 int pkgUid = -1;
3026 synchronized(this) {
3027 try {
3028 pkgUid = pm.getPackageUid(packageName);
3029 } catch (RemoteException e) {
3030 }
3031 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003032 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 return false;
3034 }
3035 if (uid == pkgUid || checkComponentPermission(
3036 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003037 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003039 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 } else {
3041 throw new SecurityException(pid+" does not have permission:"+
3042 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3043 "for process:"+packageName);
3044 }
3045 }
3046
3047 try {
3048 //clear application user data
3049 pm.clearApplicationUserData(packageName, observer);
3050 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3051 Uri.fromParts("package", packageName, null));
3052 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003053 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3054 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 } catch (RemoteException e) {
3056 }
3057 } finally {
3058 Binder.restoreCallingIdentity(callingId);
3059 }
3060 return true;
3061 }
3062
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 public void killBackgroundProcesses(final String packageName) {
3064 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3065 != PackageManager.PERMISSION_GRANTED &&
3066 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3067 != PackageManager.PERMISSION_GRANTED) {
3068 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 + Binder.getCallingPid()
3070 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003072 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 throw new SecurityException(msg);
3074 }
3075
3076 long callingId = Binder.clearCallingIdentity();
3077 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003078 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 int pkgUid = -1;
3080 synchronized(this) {
3081 try {
3082 pkgUid = pm.getPackageUid(packageName);
3083 } catch (RemoteException e) {
3084 }
3085 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 return;
3088 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003089 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003090 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003091 }
3092 } finally {
3093 Binder.restoreCallingIdentity(callingId);
3094 }
3095 }
3096
3097 public void forceStopPackage(final String packageName) {
3098 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3099 != PackageManager.PERMISSION_GRANTED) {
3100 String msg = "Permission Denial: forceStopPackage() from pid="
3101 + Binder.getCallingPid()
3102 + ", uid=" + Binder.getCallingUid()
3103 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003104 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003105 throw new SecurityException(msg);
3106 }
3107
3108 long callingId = Binder.clearCallingIdentity();
3109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003110 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003111 int pkgUid = -1;
3112 synchronized(this) {
3113 try {
3114 pkgUid = pm.getPackageUid(packageName);
3115 } catch (RemoteException e) {
3116 }
3117 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003118 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003119 return;
3120 }
3121 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003122 try {
3123 pm.setPackageStoppedState(packageName, true);
3124 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003125 } catch (IllegalArgumentException e) {
3126 Slog.w(TAG, "Failed trying to unstop package "
3127 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 }
3130 } finally {
3131 Binder.restoreCallingIdentity(callingId);
3132 }
3133 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003134
3135 /*
3136 * The pkg name and uid have to be specified.
3137 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3138 */
3139 public void killApplicationWithUid(String pkg, int uid) {
3140 if (pkg == null) {
3141 return;
3142 }
3143 // Make sure the uid is valid.
3144 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003146 return;
3147 }
3148 int callerUid = Binder.getCallingUid();
3149 // Only the system server can kill an application
3150 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003151 // Post an aysnc message to kill the application
3152 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3153 msg.arg1 = uid;
3154 msg.arg2 = 0;
3155 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003156 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003157 } else {
3158 throw new SecurityException(callerUid + " cannot kill pkg: " +
3159 pkg);
3160 }
3161 }
3162
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003163 public void closeSystemDialogs(String reason) {
3164 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003165 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003166 if (reason != null) {
3167 intent.putExtra("reason", reason);
3168 }
3169
3170 final int uid = Binder.getCallingUid();
3171 final long origId = Binder.clearCallingIdentity();
3172 synchronized (this) {
3173 int i = mWatchers.beginBroadcast();
3174 while (i > 0) {
3175 i--;
3176 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3177 if (w != null) {
3178 try {
3179 w.closingSystemDialogs(reason);
3180 } catch (RemoteException e) {
3181 }
3182 }
3183 }
3184 mWatchers.finishBroadcast();
3185
Dianne Hackbornffa42482009-09-23 22:20:11 -07003186 mWindowManager.closeSystemDialogs(reason);
3187
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003188 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3189 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003190 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003191 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003192 Activity.RESULT_CANCELED, null, "close-sys");
3193 }
3194 }
3195
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003196 broadcastIntentLocked(null, null, intent, null,
3197 null, 0, null, null, null, false, false, -1, uid);
3198 }
3199 Binder.restoreCallingIdentity(origId);
3200 }
3201
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003202 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003203 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003204 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3205 for (int i=pids.length-1; i>=0; i--) {
3206 infos[i] = new Debug.MemoryInfo();
3207 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003208 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003209 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003210 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003211
Dianne Hackbornb437e092011-08-05 17:50:29 -07003212 public long[] getProcessPss(int[] pids) throws RemoteException {
3213 long[] pss = new long[pids.length];
3214 for (int i=pids.length-1; i>=0; i--) {
3215 pss[i] = Debug.getPss(pids[i]);
3216 }
3217 return pss;
3218 }
3219
Christopher Tate5e1ab332009-09-01 20:32:49 -07003220 public void killApplicationProcess(String processName, int uid) {
3221 if (processName == null) {
3222 return;
3223 }
3224
3225 int callerUid = Binder.getCallingUid();
3226 // Only the system server can kill an application
3227 if (callerUid == Process.SYSTEM_UID) {
3228 synchronized (this) {
3229 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003230 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003231 try {
3232 app.thread.scheduleSuicide();
3233 } catch (RemoteException e) {
3234 // If the other end already died, then our work here is done.
3235 }
3236 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003237 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003238 + processName + " / " + uid);
3239 }
3240 }
3241 } else {
3242 throw new SecurityException(callerUid + " cannot kill app process: " +
3243 processName);
3244 }
3245 }
3246
Dianne Hackborn03abb812010-01-04 18:43:19 -08003247 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003248 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3250 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003251 if (!mProcessesReady) {
3252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 intent.putExtra(Intent.EXTRA_UID, uid);
3255 broadcastIntentLocked(null, null, intent,
3256 null, null, 0, null, null, null,
3257 false, false, MY_PID, Process.SYSTEM_UID);
3258 }
3259
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003260 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003261 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3262 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003263 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264
Dianne Hackborn03abb812010-01-04 18:43:19 -08003265 // Remove all processes this package may have touched: all with the
3266 // same UID (except for the system or root user), and all whose name
3267 // matches the package name.
3268 final String procNamePrefix = packageName + ":";
3269 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3270 final int NA = apps.size();
3271 for (int ia=0; ia<NA; ia++) {
3272 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003273 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003274 // we don't kill persistent processes
3275 continue;
3276 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003277 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003278 if (doit) {
3279 procs.add(app);
3280 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003281 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3282 || app.processName.equals(packageName)
3283 || app.processName.startsWith(procNamePrefix)) {
3284 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003285 if (!doit) {
3286 return true;
3287 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003288 app.removed = true;
3289 procs.add(app);
3290 }
3291 }
3292 }
3293 }
3294
3295 int N = procs.size();
3296 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003297 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003298 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003299 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003300 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003301
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003302 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003303 boolean callerWillRestart, boolean purgeCache, boolean doit,
3304 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003305 int i;
3306 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 if (uid < 0) {
3309 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003310 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 } catch (RemoteException e) {
3312 }
3313 }
3314
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003316 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3319 while (badApps.hasNext()) {
3320 SparseArray<Long> ba = badApps.next();
3321 if (ba.get(uid) != null) {
3322 badApps.remove();
3323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 }
3325 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326
3327 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003328 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003330 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3331 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003332 if (r.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003333 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003334 if (!doit) {
3335 return true;
3336 }
3337 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003338 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 if (r.app != null) {
3340 r.app.removed = true;
3341 }
3342 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003343 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 }
3345 }
3346
3347 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3348 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003349 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003350 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003351 if (!doit) {
3352 return true;
3353 }
3354 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003355 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 if (service.app != null) {
3357 service.app.removed = true;
3358 }
3359 service.app = null;
3360 services.add(service);
3361 }
3362 }
3363
3364 N = services.size();
3365 for (i=0; i<N; i++) {
3366 bringDownServiceLocked(services.get(i), true);
3367 }
3368
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003369 if (doit) {
3370 if (purgeCache) {
3371 AttributeCache ac = AttributeCache.instance();
3372 if (ac != null) {
3373 ac.removePackage(name);
3374 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003375 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003376 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003377 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003378
3379 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 }
3381
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003382 private final boolean removeProcessLocked(ProcessRecord app,
3383 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 final String name = app.processName;
3385 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003386 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 TAG, "Force removing process " + app + " (" + name
3388 + "/" + uid + ")");
3389
3390 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003391 if (mHeavyWeightProcess == app) {
3392 mHeavyWeightProcess = null;
3393 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003395 boolean needRestart = false;
3396 if (app.pid > 0 && app.pid != MY_PID) {
3397 int pid = app.pid;
3398 synchronized (mPidsSelfLocked) {
3399 mPidsSelfLocked.remove(pid);
3400 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3401 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003402 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003403 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 Process.killProcess(pid);
3405
3406 if (app.persistent) {
3407 if (!callerWillRestart) {
3408 addAppLocked(app.info);
3409 } else {
3410 needRestart = true;
3411 }
3412 }
3413 } else {
3414 mRemovedProcesses.add(app);
3415 }
3416
3417 return needRestart;
3418 }
3419
3420 private final void processStartTimedOutLocked(ProcessRecord app) {
3421 final int pid = app.pid;
3422 boolean gone = false;
3423 synchronized (mPidsSelfLocked) {
3424 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3425 if (knownApp != null && knownApp.thread == null) {
3426 mPidsSelfLocked.remove(pid);
3427 gone = true;
3428 }
3429 }
3430
3431 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003432 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003433 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003434 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003436 if (mHeavyWeightProcess == app) {
3437 mHeavyWeightProcess = null;
3438 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3439 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003440 // Take care of any launching providers waiting for this process.
3441 checkAppInLaunchingProvidersLocked(app, true);
3442 // Take care of any services that are waiting for the process.
3443 for (int i=0; i<mPendingServices.size(); i++) {
3444 ServiceRecord sr = mPendingServices.get(i);
3445 if (app.info.uid == sr.appInfo.uid
3446 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003447 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003448 mPendingServices.remove(i);
3449 i--;
3450 bringDownServiceLocked(sr, true);
3451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003453 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3454 app.processName, app.setAdj, "start timeout");
3455 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003456 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003457 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003458 try {
3459 IBackupManager bm = IBackupManager.Stub.asInterface(
3460 ServiceManager.getService(Context.BACKUP_SERVICE));
3461 bm.agentDisconnected(app.info.packageName);
3462 } catch (RemoteException e) {
3463 // Can't happen; the backup manager is local
3464 }
3465 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003466 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003467 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003468 mPendingBroadcast.state = BroadcastRecord.IDLE;
3469 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003470 mPendingBroadcast = null;
3471 scheduleBroadcastsLocked();
3472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003474 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 }
3476 }
3477
3478 private final boolean attachApplicationLocked(IApplicationThread thread,
3479 int pid) {
3480
3481 // Find the application record that is being attached... either via
3482 // the pid if we are running in multiple processes, or just pull the
3483 // next app record if we are emulating process with anonymous threads.
3484 ProcessRecord app;
3485 if (pid != MY_PID && pid >= 0) {
3486 synchronized (mPidsSelfLocked) {
3487 app = mPidsSelfLocked.get(pid);
3488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 } else {
3490 app = null;
3491 }
3492
3493 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003494 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003496 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003498 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003499 } else {
3500 try {
3501 thread.scheduleExit();
3502 } catch (Exception e) {
3503 // Ignore exceptions.
3504 }
3505 }
3506 return false;
3507 }
3508
3509 // If this application record is still attached to a previous
3510 // process, clean it up now.
3511 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003512 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 }
3514
3515 // Tell the process all about itself.
3516
Joe Onorato8a9b2202010-02-26 18:56:32 -08003517 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 TAG, "Binding process pid " + pid + " to record " + app);
3519
3520 String processName = app.processName;
3521 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003522 AppDeathRecipient adr = new AppDeathRecipient(
3523 app, pid, thread);
3524 thread.asBinder().linkToDeath(adr, 0);
3525 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 } catch (RemoteException e) {
3527 app.resetPackageList();
3528 startProcessLocked(app, "link fail", processName);
3529 return false;
3530 }
3531
Doug Zongker2bec3d42009-12-04 12:52:44 -08003532 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533
3534 app.thread = thread;
3535 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003536 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3537 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 app.forcingToForeground = null;
3539 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003540 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 app.debugging = false;
3542
3543 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3544
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003545 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003546 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003548 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003549 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003550 }
3551
Joe Onorato8a9b2202010-02-26 18:56:32 -08003552 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 TAG, "New app record " + app
3554 + " thread=" + thread.asBinder() + " pid=" + pid);
3555 try {
3556 int testMode = IApplicationThread.DEBUG_OFF;
3557 if (mDebugApp != null && mDebugApp.equals(processName)) {
3558 testMode = mWaitForDebugger
3559 ? IApplicationThread.DEBUG_WAIT
3560 : IApplicationThread.DEBUG_ON;
3561 app.debugging = true;
3562 if (mDebugTransient) {
3563 mDebugApp = mOrigDebugApp;
3564 mWaitForDebugger = mOrigWaitForDebugger;
3565 }
3566 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003567 String profileFile = app.instrumentationProfileFile;
3568 ParcelFileDescriptor profileFd = null;
3569 boolean profileAutoStop = false;
3570 if (mProfileApp != null && mProfileApp.equals(processName)) {
3571 mProfileProc = app;
3572 profileFile = mProfileFile;
3573 profileFd = mProfileFd;
3574 profileAutoStop = mAutoStopProfiler;
3575 }
3576
Christopher Tate181fafa2009-05-14 11:12:14 -07003577 // If the app is being launched for restore or full backup, set it up specially
3578 boolean isRestrictedBackupMode = false;
3579 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3580 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003581 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003582 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3583 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003584
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003585 ensurePackageDexOpt(app.instrumentationInfo != null
3586 ? app.instrumentationInfo.packageName
3587 : app.info.packageName);
3588 if (app.instrumentationClass != null) {
3589 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003590 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003591 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003592 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003593 ApplicationInfo appInfo = app.instrumentationInfo != null
3594 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003595 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003596 if (profileFd != null) {
3597 profileFd = profileFd.dup();
3598 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003599 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003600 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003602 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003603 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003604 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003605 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003606 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 } catch (Exception e) {
3608 // todo: Yikes! What should we do? For now we will try to
3609 // start another process, but that could easily get us in
3610 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003611 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612
3613 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003614 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 startProcessLocked(app, "bind fail", processName);
3616 return false;
3617 }
3618
3619 // Remove this record from the list of starting applications.
3620 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003621 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3622 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623 mProcessesOnHold.remove(app);
3624
3625 boolean badApp = false;
3626 boolean didSomething = false;
3627
3628 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003629 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003630 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003631 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3632 && processName.equals(hr.processName)) {
3633 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003634 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 didSomething = true;
3636 }
3637 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003638 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 + hr.intent.getComponent().flattenToShortString(), e);
3640 badApp = true;
3641 }
3642 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003643 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 }
3645 }
3646
3647 // Find any services that should be running in this process...
3648 if (!badApp && mPendingServices.size() > 0) {
3649 ServiceRecord sr = null;
3650 try {
3651 for (int i=0; i<mPendingServices.size(); i++) {
3652 sr = mPendingServices.get(i);
3653 if (app.info.uid != sr.appInfo.uid
3654 || !processName.equals(sr.processName)) {
3655 continue;
3656 }
3657
3658 mPendingServices.remove(i);
3659 i--;
3660 realStartServiceLocked(sr, app);
3661 didSomething = true;
3662 }
3663 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003664 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 + sr.shortName, e);
3666 badApp = true;
3667 }
3668 }
3669
3670 // Check if the next broadcast receiver is in this process...
3671 BroadcastRecord br = mPendingBroadcast;
3672 if (!badApp && br != null && br.curApp == app) {
3673 try {
3674 mPendingBroadcast = null;
3675 processCurBroadcastLocked(br, app);
3676 didSomething = true;
3677 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003678 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 + br.curComponent.flattenToShortString(), e);
3680 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003681 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3683 br.resultExtras, br.resultAbort, true);
3684 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003685 // We need to reset the state if we fails to start the receiver.
3686 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 }
3688 }
3689
Christopher Tate181fafa2009-05-14 11:12:14 -07003690 // Check whether the next backup agent is in this process...
3691 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003692 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003693 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003694 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003695 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3696 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3697 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003698 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003699 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003700 e.printStackTrace();
3701 }
3702 }
3703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 if (badApp) {
3705 // todo: Also need to kill application to deal with all
3706 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003707 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 return false;
3709 }
3710
3711 if (!didSomething) {
3712 updateOomAdjLocked();
3713 }
3714
3715 return true;
3716 }
3717
3718 public final void attachApplication(IApplicationThread thread) {
3719 synchronized (this) {
3720 int callingPid = Binder.getCallingPid();
3721 final long origId = Binder.clearCallingIdentity();
3722 attachApplicationLocked(thread, callingPid);
3723 Binder.restoreCallingIdentity(origId);
3724 }
3725 }
3726
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003727 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003729 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3730 if (stopProfiling) {
3731 synchronized (this) {
3732 if (mProfileProc == r.app) {
3733 if (mProfileFd != null) {
3734 try {
3735 mProfileFd.close();
3736 } catch (IOException e) {
3737 }
3738 clearProfilerLocked();
3739 }
3740 }
3741 }
3742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 Binder.restoreCallingIdentity(origId);
3744 }
3745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003747 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003748 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 mWindowManager.enableScreenAfterBoot();
3750 }
3751
Dianne Hackborn661cd522011-08-22 00:26:20 -07003752 public void showBootMessage(final CharSequence msg, final boolean always) {
3753 mWindowManager.showBootMessage(msg, always);
3754 }
3755
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003756 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003757 IntentFilter pkgFilter = new IntentFilter();
3758 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3759 pkgFilter.addDataScheme("package");
3760 mContext.registerReceiver(new BroadcastReceiver() {
3761 @Override
3762 public void onReceive(Context context, Intent intent) {
3763 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3764 if (pkgs != null) {
3765 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003766 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003767 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003768 setResultCode(Activity.RESULT_OK);
3769 return;
3770 }
3771 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003772 }
3773 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003774 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003775 }, pkgFilter);
3776
3777 synchronized (this) {
3778 // Ensure that any processes we had put on hold are now started
3779 // up.
3780 final int NP = mProcessesOnHold.size();
3781 if (NP > 0) {
3782 ArrayList<ProcessRecord> procs =
3783 new ArrayList<ProcessRecord>(mProcessesOnHold);
3784 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003785 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3786 + procs.get(ip));
3787 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003788 }
3789 }
3790
3791 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003792 // Start looking for apps that are abusing wake locks.
3793 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003794 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003795 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003796 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003797 broadcastIntentLocked(null, null,
3798 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3799 null, null, 0, null, null,
3800 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3801 false, false, MY_PID, Process.SYSTEM_UID);
3802 }
3803 }
3804 }
3805
3806 final void ensureBootCompleted() {
3807 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003808 boolean enableScreen;
3809 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003810 booting = mBooting;
3811 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003812 enableScreen = !mBooted;
3813 mBooted = true;
3814 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003815
3816 if (booting) {
3817 finishBooting();
3818 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003819
3820 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003821 enableScreenAfterBoot();
3822 }
3823 }
3824
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003825 public final void activityPaused(IBinder token) {
3826 final long origId = Binder.clearCallingIdentity();
3827 mMainStack.activityPaused(token, false);
3828 Binder.restoreCallingIdentity(origId);
3829 }
3830
3831 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3832 CharSequence description) {
3833 if (localLOGV) Slog.v(
3834 TAG, "Activity stopped: token=" + token);
3835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 // Refuse possible leaked file descriptors
3837 if (icicle != null && icicle.hasFileDescriptors()) {
3838 throw new IllegalArgumentException("File descriptors passed in Bundle");
3839 }
3840
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003841 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842
3843 final long origId = Binder.clearCallingIdentity();
3844
3845 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003846 r = mMainStack.isInStackLocked(token);
3847 if (r != null) {
3848 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 }
3850 }
3851
3852 if (r != null) {
3853 sendPendingThumbnail(r, null, null, null, false);
3854 }
3855
3856 trimApplications();
3857
3858 Binder.restoreCallingIdentity(origId);
3859 }
3860
3861 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003862 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003863 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 }
3865
3866 public String getCallingPackage(IBinder token) {
3867 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003868 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003869 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 }
3871 }
3872
3873 public ComponentName getCallingActivity(IBinder token) {
3874 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003875 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 return r != null ? r.intent.getComponent() : null;
3877 }
3878 }
3879
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003880 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003881 ActivityRecord r = mMainStack.isInStackLocked(token);
3882 if (r == null) {
3883 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003884 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003885 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 }
3887
3888 public ComponentName getActivityClassForToken(IBinder token) {
3889 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003890 ActivityRecord r = mMainStack.isInStackLocked(token);
3891 if (r == null) {
3892 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003893 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003894 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 }
3896 }
3897
3898 public String getPackageForToken(IBinder token) {
3899 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003900 ActivityRecord r = mMainStack.isInStackLocked(token);
3901 if (r == null) {
3902 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003904 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 }
3906 }
3907
3908 public IIntentSender getIntentSender(int type,
3909 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003910 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003912 if (intents != null) {
3913 if (intents.length < 1) {
3914 throw new IllegalArgumentException("Intents array length must be >= 1");
3915 }
3916 for (int i=0; i<intents.length; i++) {
3917 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003918 if (intent != null) {
3919 if (intent.hasFileDescriptors()) {
3920 throw new IllegalArgumentException("File descriptors passed in Intent");
3921 }
3922 if (type == INTENT_SENDER_BROADCAST &&
3923 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3924 throw new IllegalArgumentException(
3925 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3926 }
3927 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003928 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003929 }
3930 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003931 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003932 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003933 }
3934 }
3935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 synchronized(this) {
3937 int callingUid = Binder.getCallingUid();
3938 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003939 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003940 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 .getPackageUid(packageName);
3942 if (uid != Binder.getCallingUid()) {
3943 String msg = "Permission Denial: getIntentSender() from pid="
3944 + Binder.getCallingPid()
3945 + ", uid=" + Binder.getCallingUid()
3946 + ", (need uid=" + uid + ")"
3947 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003948 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 throw new SecurityException(msg);
3950 }
3951 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003952
3953 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003954 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 } catch (RemoteException e) {
3957 throw new SecurityException(e);
3958 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003959 }
3960 }
3961
3962 IIntentSender getIntentSenderLocked(int type,
3963 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003964 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003965 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003966 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003967 activity = mMainStack.isInStackLocked(token);
3968 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003969 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003971 if (activity.finishing) {
3972 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003974 }
3975
3976 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3977 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3978 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3979 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3980 |PendingIntent.FLAG_UPDATE_CURRENT);
3981
3982 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3983 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003984 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003985 WeakReference<PendingIntentRecord> ref;
3986 ref = mIntentSenderRecords.get(key);
3987 PendingIntentRecord rec = ref != null ? ref.get() : null;
3988 if (rec != null) {
3989 if (!cancelCurrent) {
3990 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003991 if (rec.key.requestIntent != null) {
3992 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3993 }
3994 if (intents != null) {
3995 intents[intents.length-1] = rec.key.requestIntent;
3996 rec.key.allIntents = intents;
3997 rec.key.allResolvedTypes = resolvedTypes;
3998 } else {
3999 rec.key.allIntents = null;
4000 rec.key.allResolvedTypes = null;
4001 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 return rec;
4004 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004005 rec.canceled = true;
4006 mIntentSenderRecords.remove(key);
4007 }
4008 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 return rec;
4010 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004011 rec = new PendingIntentRecord(this, key, callingUid);
4012 mIntentSenderRecords.put(key, rec.ref);
4013 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4014 if (activity.pendingResults == null) {
4015 activity.pendingResults
4016 = new HashSet<WeakReference<PendingIntentRecord>>();
4017 }
4018 activity.pendingResults.add(rec.ref);
4019 }
4020 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 }
4022
4023 public void cancelIntentSender(IIntentSender sender) {
4024 if (!(sender instanceof PendingIntentRecord)) {
4025 return;
4026 }
4027 synchronized(this) {
4028 PendingIntentRecord rec = (PendingIntentRecord)sender;
4029 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004030 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 .getPackageUid(rec.key.packageName);
4032 if (uid != Binder.getCallingUid()) {
4033 String msg = "Permission Denial: cancelIntentSender() from pid="
4034 + Binder.getCallingPid()
4035 + ", uid=" + Binder.getCallingUid()
4036 + " is not allowed to cancel packges "
4037 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004038 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 throw new SecurityException(msg);
4040 }
4041 } catch (RemoteException e) {
4042 throw new SecurityException(e);
4043 }
4044 cancelIntentSenderLocked(rec, true);
4045 }
4046 }
4047
4048 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4049 rec.canceled = true;
4050 mIntentSenderRecords.remove(rec.key);
4051 if (cleanActivity && rec.key.activity != null) {
4052 rec.key.activity.pendingResults.remove(rec.ref);
4053 }
4054 }
4055
4056 public String getPackageForIntentSender(IIntentSender pendingResult) {
4057 if (!(pendingResult instanceof PendingIntentRecord)) {
4058 return null;
4059 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004060 try {
4061 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4062 return res.key.packageName;
4063 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 }
4065 return null;
4066 }
4067
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004068 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4069 if (!(pendingResult instanceof PendingIntentRecord)) {
4070 return false;
4071 }
4072 try {
4073 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4074 if (res.key.allIntents == null) {
4075 return false;
4076 }
4077 for (int i=0; i<res.key.allIntents.length; i++) {
4078 Intent intent = res.key.allIntents[i];
4079 if (intent.getPackage() != null && intent.getComponent() != null) {
4080 return false;
4081 }
4082 }
4083 return true;
4084 } catch (ClassCastException e) {
4085 }
4086 return false;
4087 }
4088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 public void setProcessLimit(int max) {
4090 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4091 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004092 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004093 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004094 mProcessLimitOverride = max;
4095 }
4096 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 }
4098
4099 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004100 synchronized (this) {
4101 return mProcessLimitOverride;
4102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103 }
4104
4105 void foregroundTokenDied(ForegroundToken token) {
4106 synchronized (ActivityManagerService.this) {
4107 synchronized (mPidsSelfLocked) {
4108 ForegroundToken cur
4109 = mForegroundProcesses.get(token.pid);
4110 if (cur != token) {
4111 return;
4112 }
4113 mForegroundProcesses.remove(token.pid);
4114 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4115 if (pr == null) {
4116 return;
4117 }
4118 pr.forcingToForeground = null;
4119 pr.foregroundServices = false;
4120 }
4121 updateOomAdjLocked();
4122 }
4123 }
4124
4125 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4126 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4127 "setProcessForeground()");
4128 synchronized(this) {
4129 boolean changed = false;
4130
4131 synchronized (mPidsSelfLocked) {
4132 ProcessRecord pr = mPidsSelfLocked.get(pid);
4133 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004134 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 return;
4136 }
4137 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4138 if (oldToken != null) {
4139 oldToken.token.unlinkToDeath(oldToken, 0);
4140 mForegroundProcesses.remove(pid);
4141 pr.forcingToForeground = null;
4142 changed = true;
4143 }
4144 if (isForeground && token != null) {
4145 ForegroundToken newToken = new ForegroundToken() {
4146 public void binderDied() {
4147 foregroundTokenDied(this);
4148 }
4149 };
4150 newToken.pid = pid;
4151 newToken.token = token;
4152 try {
4153 token.linkToDeath(newToken, 0);
4154 mForegroundProcesses.put(pid, newToken);
4155 pr.forcingToForeground = token;
4156 changed = true;
4157 } catch (RemoteException e) {
4158 // If the process died while doing this, we will later
4159 // do the cleanup with the process death link.
4160 }
4161 }
4162 }
4163
4164 if (changed) {
4165 updateOomAdjLocked();
4166 }
4167 }
4168 }
4169
4170 // =========================================================
4171 // PERMISSIONS
4172 // =========================================================
4173
4174 static class PermissionController extends IPermissionController.Stub {
4175 ActivityManagerService mActivityManagerService;
4176 PermissionController(ActivityManagerService activityManagerService) {
4177 mActivityManagerService = activityManagerService;
4178 }
4179
4180 public boolean checkPermission(String permission, int pid, int uid) {
4181 return mActivityManagerService.checkPermission(permission, pid,
4182 uid) == PackageManager.PERMISSION_GRANTED;
4183 }
4184 }
4185
4186 /**
4187 * This can be called with or without the global lock held.
4188 */
4189 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004190 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 // We might be performing an operation on behalf of an indirect binder
4192 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4193 // client identity accordingly before proceeding.
4194 Identity tlsIdentity = sCallerIdentity.get();
4195 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004196 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4198 uid = tlsIdentity.uid;
4199 pid = tlsIdentity.pid;
4200 }
4201
4202 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004203 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004204 return PackageManager.PERMISSION_GRANTED;
4205 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004206 // If there is a uid that owns whatever is being accessed, it has
4207 // blanket access to it regardless of the permissions it requires.
4208 if (owningUid >= 0 && uid == owningUid) {
4209 return PackageManager.PERMISSION_GRANTED;
4210 }
4211 // If the target is not exported, then nobody else can get to it.
4212 if (!exported) {
4213 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004214 return PackageManager.PERMISSION_DENIED;
4215 }
4216 if (permission == null) {
4217 return PackageManager.PERMISSION_GRANTED;
4218 }
4219 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004220 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004221 .checkUidPermission(permission, uid);
4222 } catch (RemoteException e) {
4223 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004224 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 }
4226 return PackageManager.PERMISSION_DENIED;
4227 }
4228
4229 /**
4230 * As the only public entry point for permissions checking, this method
4231 * can enforce the semantic that requesting a check on a null global
4232 * permission is automatically denied. (Internally a null permission
4233 * string is used when calling {@link #checkComponentPermission} in cases
4234 * when only uid-based security is needed.)
4235 *
4236 * This can be called with or without the global lock held.
4237 */
4238 public int checkPermission(String permission, int pid, int uid) {
4239 if (permission == null) {
4240 return PackageManager.PERMISSION_DENIED;
4241 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004242 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004243 }
4244
4245 /**
4246 * Binder IPC calls go through the public entry point.
4247 * This can be called with or without the global lock held.
4248 */
4249 int checkCallingPermission(String permission) {
4250 return checkPermission(permission,
4251 Binder.getCallingPid(),
4252 Binder.getCallingUid());
4253 }
4254
4255 /**
4256 * This can be called with or without the global lock held.
4257 */
4258 void enforceCallingPermission(String permission, String func) {
4259 if (checkCallingPermission(permission)
4260 == PackageManager.PERMISSION_GRANTED) {
4261 return;
4262 }
4263
4264 String msg = "Permission Denial: " + func + " from pid="
4265 + Binder.getCallingPid()
4266 + ", uid=" + Binder.getCallingUid()
4267 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004268 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 throw new SecurityException(msg);
4270 }
4271
4272 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004273 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4274 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4275 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4276 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4277 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004279 // Is the component private from the target uid?
4280 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4281
4282 // Acceptable if the there is no read permission needed from the
4283 // target or the target is holding the read permission.
4284 if (!readPerm) {
4285 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004287 == PackageManager.PERMISSION_GRANTED)) {
4288 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 }
4290 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004291
4292 // Acceptable if the there is no write permission needed from the
4293 // target or the target is holding the read permission.
4294 if (!writePerm) {
4295 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004297 == PackageManager.PERMISSION_GRANTED)) {
4298 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 }
4300 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004301
4302 // Acceptable if there is a path permission matching the URI that
4303 // the target holds the permission on.
4304 PathPermission[] pps = pi.pathPermissions;
4305 if (pps != null && (!readPerm || !writePerm)) {
4306 final String path = uri.getPath();
4307 int i = pps.length;
4308 while (i > 0 && (!readPerm || !writePerm)) {
4309 i--;
4310 PathPermission pp = pps[i];
4311 if (!readPerm) {
4312 final String pprperm = pp.getReadPermission();
4313 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4314 + pprperm + " for " + pp.getPath()
4315 + ": match=" + pp.match(path)
4316 + " check=" + pm.checkUidPermission(pprperm, uid));
4317 if (pprperm != null && pp.match(path) &&
4318 (pm.checkUidPermission(pprperm, uid)
4319 == PackageManager.PERMISSION_GRANTED)) {
4320 readPerm = true;
4321 }
4322 }
4323 if (!writePerm) {
4324 final String ppwperm = pp.getWritePermission();
4325 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4326 + ppwperm + " for " + pp.getPath()
4327 + ": match=" + pp.match(path)
4328 + " check=" + pm.checkUidPermission(ppwperm, uid));
4329 if (ppwperm != null && pp.match(path) &&
4330 (pm.checkUidPermission(ppwperm, uid)
4331 == PackageManager.PERMISSION_GRANTED)) {
4332 writePerm = true;
4333 }
4334 }
4335 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 } catch (RemoteException e) {
4338 return false;
4339 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004340
4341 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342 }
4343
4344 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4345 int modeFlags) {
4346 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004347 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 return true;
4349 }
4350 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4351 if (perms == null) return false;
4352 UriPermission perm = perms.get(uri);
4353 if (perm == null) return false;
4354 return (modeFlags&perm.modeFlags) == modeFlags;
4355 }
4356
4357 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4358 // Another redirected-binder-call permissions check as in
4359 // {@link checkComponentPermission}.
4360 Identity tlsIdentity = sCallerIdentity.get();
4361 if (tlsIdentity != null) {
4362 uid = tlsIdentity.uid;
4363 pid = tlsIdentity.pid;
4364 }
4365
4366 // Our own process gets to do everything.
4367 if (pid == MY_PID) {
4368 return PackageManager.PERMISSION_GRANTED;
4369 }
4370 synchronized(this) {
4371 return checkUriPermissionLocked(uri, uid, modeFlags)
4372 ? PackageManager.PERMISSION_GRANTED
4373 : PackageManager.PERMISSION_DENIED;
4374 }
4375 }
4376
Dianne Hackborn39792d22010-08-19 18:01:52 -07004377 /**
4378 * Check if the targetPkg can be granted permission to access uri by
4379 * the callingUid using the given modeFlags. Throws a security exception
4380 * if callingUid is not allowed to do this. Returns the uid of the target
4381 * if the URI permission grant should be performed; returns -1 if it is not
4382 * needed (for example targetPkg already has permission to access the URI).
4383 */
4384 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4385 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004386 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4387 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4388 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004389 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 }
4391
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004392 if (targetPkg != null) {
4393 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4394 "Checking grant " + targetPkg + " permission to " + uri);
4395 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004396
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004397 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398
4399 // If this is not a content: uri, we can't do anything with it.
4400 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004401 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004402 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004403 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 }
4405
4406 String name = uri.getAuthority();
4407 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004408 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 if (cpr != null) {
4410 pi = cpr.info;
4411 } else {
4412 try {
4413 pi = pm.resolveContentProvider(name,
4414 PackageManager.GET_URI_PERMISSION_PATTERNS);
4415 } catch (RemoteException ex) {
4416 }
4417 }
4418 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004419 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004420 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 }
4422
4423 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004424 if (targetPkg != null) {
4425 try {
4426 targetUid = pm.getPackageUid(targetPkg);
4427 if (targetUid < 0) {
4428 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4429 "Can't grant URI permission no uid for: " + targetPkg);
4430 return -1;
4431 }
4432 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004433 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004435 } else {
4436 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004439 if (targetUid >= 0) {
4440 // First... does the target actually need this permission?
4441 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4442 // No need to grant the target this permission.
4443 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4444 "Target " + targetPkg + " already has full permission to " + uri);
4445 return -1;
4446 }
4447 } else {
4448 // First... there is no target package, so can anyone access it?
4449 boolean allowed = pi.exported;
4450 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4451 if (pi.readPermission != null) {
4452 allowed = false;
4453 }
4454 }
4455 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4456 if (pi.writePermission != null) {
4457 allowed = false;
4458 }
4459 }
4460 if (allowed) {
4461 return -1;
4462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 }
4464
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004465 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 if (!pi.grantUriPermissions) {
4467 throw new SecurityException("Provider " + pi.packageName
4468 + "/" + pi.name
4469 + " does not allow granting of Uri permissions (uri "
4470 + uri + ")");
4471 }
4472 if (pi.uriPermissionPatterns != null) {
4473 final int N = pi.uriPermissionPatterns.length;
4474 boolean allowed = false;
4475 for (int i=0; i<N; i++) {
4476 if (pi.uriPermissionPatterns[i] != null
4477 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4478 allowed = true;
4479 break;
4480 }
4481 }
4482 if (!allowed) {
4483 throw new SecurityException("Provider " + pi.packageName
4484 + "/" + pi.name
4485 + " does not allow granting of permission to path of Uri "
4486 + uri);
4487 }
4488 }
4489
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004490 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004492 if (callingUid != Process.myUid()) {
4493 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4494 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4495 throw new SecurityException("Uid " + callingUid
4496 + " does not have permission to uri " + uri);
4497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 }
4499 }
4500
Dianne Hackborn39792d22010-08-19 18:01:52 -07004501 return targetUid;
4502 }
4503
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004504 public int checkGrantUriPermission(int callingUid, String targetPkg,
4505 Uri uri, int modeFlags) {
4506 synchronized(this) {
4507 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4508 }
4509 }
4510
Dianne Hackborn39792d22010-08-19 18:01:52 -07004511 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4512 Uri uri, int modeFlags, UriPermissionOwner owner) {
4513 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4514 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4515 if (modeFlags == 0) {
4516 return;
4517 }
4518
4519 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 // to the uri, and the target doesn't. Let's now give this to
4521 // the target.
4522
Joe Onorato8a9b2202010-02-26 18:56:32 -08004523 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004524 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 HashMap<Uri, UriPermission> targetUris
4527 = mGrantedUriPermissions.get(targetUid);
4528 if (targetUris == null) {
4529 targetUris = new HashMap<Uri, UriPermission>();
4530 mGrantedUriPermissions.put(targetUid, targetUris);
4531 }
4532
4533 UriPermission perm = targetUris.get(uri);
4534 if (perm == null) {
4535 perm = new UriPermission(targetUid, uri);
4536 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004537 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004540 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004542 } else {
4543 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4544 perm.readOwners.add(owner);
4545 owner.addReadPermission(perm);
4546 }
4547 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4548 perm.writeOwners.add(owner);
4549 owner.addWritePermission(perm);
4550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 }
4552 }
4553
Dianne Hackborn39792d22010-08-19 18:01:52 -07004554 void grantUriPermissionLocked(int callingUid,
4555 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004556 if (targetPkg == null) {
4557 throw new NullPointerException("targetPkg");
4558 }
4559
Dianne Hackborn39792d22010-08-19 18:01:52 -07004560 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4561 if (targetUid < 0) {
4562 return;
4563 }
4564
4565 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4566 }
4567
4568 /**
4569 * Like checkGrantUriPermissionLocked, but takes an Intent.
4570 */
4571 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4572 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004573 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004574 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004575 + " from " + intent + "; flags=0x"
4576 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4577
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004578 if (targetPkg == null) {
4579 throw new NullPointerException("targetPkg");
4580 }
4581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004583 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 }
4585 Uri data = intent.getData();
4586 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004587 return -1;
4588 }
4589 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4590 intent.getFlags());
4591 }
4592
4593 /**
4594 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4595 */
4596 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4597 String targetPkg, Intent intent, UriPermissionOwner owner) {
4598 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4599 intent.getFlags(), owner);
4600 }
4601
4602 void grantUriPermissionFromIntentLocked(int callingUid,
4603 String targetPkg, Intent intent, UriPermissionOwner owner) {
4604 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4605 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 return;
4607 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004608
4609 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 }
4611
4612 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4613 Uri uri, int modeFlags) {
4614 synchronized(this) {
4615 final ProcessRecord r = getRecordForAppLocked(caller);
4616 if (r == null) {
4617 throw new SecurityException("Unable to find app for caller "
4618 + caller
4619 + " when granting permission to uri " + uri);
4620 }
4621 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004622 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 }
4624 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004625 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627
4628 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4629 null);
4630 }
4631 }
4632
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004633 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4635 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4636 HashMap<Uri, UriPermission> perms
4637 = mGrantedUriPermissions.get(perm.uid);
4638 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004639 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004640 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 perms.remove(perm.uri);
4642 if (perms.size() == 0) {
4643 mGrantedUriPermissions.remove(perm.uid);
4644 }
4645 }
4646 }
4647 }
4648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004649 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4650 int modeFlags) {
4651 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4652 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4653 if (modeFlags == 0) {
4654 return;
4655 }
4656
Joe Onorato8a9b2202010-02-26 18:56:32 -08004657 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004658 "Revoking all granted permissions to " + uri);
4659
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004660 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661
4662 final String authority = uri.getAuthority();
4663 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004664 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004665 if (cpr != null) {
4666 pi = cpr.info;
4667 } else {
4668 try {
4669 pi = pm.resolveContentProvider(authority,
4670 PackageManager.GET_URI_PERMISSION_PATTERNS);
4671 } catch (RemoteException ex) {
4672 }
4673 }
4674 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004675 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 return;
4677 }
4678
4679 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004680 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 // Right now, if you are not the original owner of the permission,
4682 // you are not allowed to revoke it.
4683 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4684 throw new SecurityException("Uid " + callingUid
4685 + " does not have permission to uri " + uri);
4686 //}
4687 }
4688
4689 // Go through all of the permissions and remove any that match.
4690 final List<String> SEGMENTS = uri.getPathSegments();
4691 if (SEGMENTS != null) {
4692 final int NS = SEGMENTS.size();
4693 int N = mGrantedUriPermissions.size();
4694 for (int i=0; i<N; i++) {
4695 HashMap<Uri, UriPermission> perms
4696 = mGrantedUriPermissions.valueAt(i);
4697 Iterator<UriPermission> it = perms.values().iterator();
4698 toploop:
4699 while (it.hasNext()) {
4700 UriPermission perm = it.next();
4701 Uri targetUri = perm.uri;
4702 if (!authority.equals(targetUri.getAuthority())) {
4703 continue;
4704 }
4705 List<String> targetSegments = targetUri.getPathSegments();
4706 if (targetSegments == null) {
4707 continue;
4708 }
4709 if (targetSegments.size() < NS) {
4710 continue;
4711 }
4712 for (int j=0; j<NS; j++) {
4713 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4714 continue toploop;
4715 }
4716 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004717 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004718 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 perm.clearModes(modeFlags);
4720 if (perm.modeFlags == 0) {
4721 it.remove();
4722 }
4723 }
4724 if (perms.size() == 0) {
4725 mGrantedUriPermissions.remove(
4726 mGrantedUriPermissions.keyAt(i));
4727 N--;
4728 i--;
4729 }
4730 }
4731 }
4732 }
4733
4734 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4735 int modeFlags) {
4736 synchronized(this) {
4737 final ProcessRecord r = getRecordForAppLocked(caller);
4738 if (r == null) {
4739 throw new SecurityException("Unable to find app for caller "
4740 + caller
4741 + " when revoking permission to uri " + uri);
4742 }
4743 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004744 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 return;
4746 }
4747
4748 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4749 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4750 if (modeFlags == 0) {
4751 return;
4752 }
4753
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004754 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755
4756 final String authority = uri.getAuthority();
4757 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004758 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 if (cpr != null) {
4760 pi = cpr.info;
4761 } else {
4762 try {
4763 pi = pm.resolveContentProvider(authority,
4764 PackageManager.GET_URI_PERMISSION_PATTERNS);
4765 } catch (RemoteException ex) {
4766 }
4767 }
4768 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004769 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 return;
4771 }
4772
4773 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4774 }
4775 }
4776
Dianne Hackborn7e269642010-08-25 19:50:20 -07004777 @Override
4778 public IBinder newUriPermissionOwner(String name) {
4779 synchronized(this) {
4780 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4781 return owner.getExternalTokenLocked();
4782 }
4783 }
4784
4785 @Override
4786 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4787 Uri uri, int modeFlags) {
4788 synchronized(this) {
4789 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4790 if (owner == null) {
4791 throw new IllegalArgumentException("Unknown owner: " + token);
4792 }
4793 if (fromUid != Binder.getCallingUid()) {
4794 if (Binder.getCallingUid() != Process.myUid()) {
4795 // Only system code can grant URI permissions on behalf
4796 // of other users.
4797 throw new SecurityException("nice try");
4798 }
4799 }
4800 if (targetPkg == null) {
4801 throw new IllegalArgumentException("null target");
4802 }
4803 if (uri == null) {
4804 throw new IllegalArgumentException("null uri");
4805 }
4806
4807 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4808 }
4809 }
4810
4811 @Override
4812 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4813 synchronized(this) {
4814 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4815 if (owner == null) {
4816 throw new IllegalArgumentException("Unknown owner: " + token);
4817 }
4818
4819 if (uri == null) {
4820 owner.removeUriPermissionsLocked(mode);
4821 } else {
4822 owner.removeUriPermissionLocked(uri, mode);
4823 }
4824 }
4825 }
4826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4828 synchronized (this) {
4829 ProcessRecord app =
4830 who != null ? getRecordForAppLocked(who) : null;
4831 if (app == null) return;
4832
4833 Message msg = Message.obtain();
4834 msg.what = WAIT_FOR_DEBUGGER_MSG;
4835 msg.obj = app;
4836 msg.arg1 = waiting ? 1 : 0;
4837 mHandler.sendMessage(msg);
4838 }
4839 }
4840
4841 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004842 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4843 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004845 outInfo.threshold = homeAppMem;
4846 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4847 outInfo.hiddenAppThreshold = hiddenAppMem;
4848 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4849 ProcessList.SECONDARY_SERVER_ADJ);
4850 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4851 ProcessList.VISIBLE_APP_ADJ);
4852 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4853 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 }
4855
4856 // =========================================================
4857 // TASK MANAGEMENT
4858 // =========================================================
4859
4860 public List getTasks(int maxNum, int flags,
4861 IThumbnailReceiver receiver) {
4862 ArrayList list = new ArrayList();
4863
4864 PendingThumbnailsRecord pending = null;
4865 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004866 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867
4868 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004869 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4871 + ", receiver=" + receiver);
4872
4873 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4874 != PackageManager.PERMISSION_GRANTED) {
4875 if (receiver != null) {
4876 // If the caller wants to wait for pending thumbnails,
4877 // it ain't gonna get them.
4878 try {
4879 receiver.finished();
4880 } catch (RemoteException ex) {
4881 }
4882 }
4883 String msg = "Permission Denial: getTasks() from pid="
4884 + Binder.getCallingPid()
4885 + ", uid=" + Binder.getCallingUid()
4886 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004887 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 throw new SecurityException(msg);
4889 }
4890
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004891 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004892 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004893 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004894 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 TaskRecord curTask = null;
4896 int numActivities = 0;
4897 int numRunning = 0;
4898 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004899 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004901 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004902
4903 // Initialize state for next task if needed.
4904 if (top == null ||
4905 (top.state == ActivityState.INITIALIZING
4906 && top.task == r.task)) {
4907 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 curTask = r.task;
4909 numActivities = numRunning = 0;
4910 }
4911
4912 // Add 'r' into the current task.
4913 numActivities++;
4914 if (r.app != null && r.app.thread != null) {
4915 numRunning++;
4916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917
Joe Onorato8a9b2202010-02-26 18:56:32 -08004918 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 TAG, r.intent.getComponent().flattenToShortString()
4920 + ": task=" + r.task);
4921
4922 // If the next one is a different task, generate a new
4923 // TaskInfo entry for what we have.
4924 if (next == null || next.task != curTask) {
4925 ActivityManager.RunningTaskInfo ci
4926 = new ActivityManager.RunningTaskInfo();
4927 ci.id = curTask.taskId;
4928 ci.baseActivity = r.intent.getComponent();
4929 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004930 if (top.thumbHolder != null) {
4931 ci.description = top.thumbHolder.lastDescription;
4932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 ci.numActivities = numActivities;
4934 ci.numRunning = numRunning;
4935 //System.out.println(
4936 // "#" + maxNum + ": " + " descr=" + ci.description);
4937 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004938 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939 TAG, "State=" + top.state + "Idle=" + top.idle
4940 + " app=" + top.app
4941 + " thr=" + (top.app != null ? top.app.thread : null));
4942 if (top.state == ActivityState.RESUMED
4943 || top.state == ActivityState.PAUSING) {
4944 if (top.idle && top.app != null
4945 && top.app.thread != null) {
4946 topRecord = top;
4947 topThumbnail = top.app.thread;
4948 } else {
4949 top.thumbnailNeeded = true;
4950 }
4951 }
4952 if (pending == null) {
4953 pending = new PendingThumbnailsRecord(receiver);
4954 }
4955 pending.pendingRecords.add(top);
4956 }
4957 list.add(ci);
4958 maxNum--;
4959 top = null;
4960 }
4961 }
4962
4963 if (pending != null) {
4964 mPendingThumbnails.add(pending);
4965 }
4966 }
4967
Joe Onorato8a9b2202010-02-26 18:56:32 -08004968 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969
4970 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004971 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972 try {
4973 topThumbnail.requestThumbnail(topRecord);
4974 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004975 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 sendPendingThumbnail(null, topRecord, null, null, true);
4977 }
4978 }
4979
4980 if (pending == null && receiver != null) {
4981 // In this case all thumbnails were available and the client
4982 // is being asked to be told when the remaining ones come in...
4983 // which is unusually, since the top-most currently running
4984 // activity should never have a canned thumbnail! Oh well.
4985 try {
4986 receiver.finished();
4987 } catch (RemoteException ex) {
4988 }
4989 }
4990
4991 return list;
4992 }
4993
4994 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4995 int flags) {
4996 synchronized (this) {
4997 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4998 "getRecentTasks()");
4999
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005000 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 final int N = mRecentTasks.size();
5003 ArrayList<ActivityManager.RecentTaskInfo> res
5004 = new ArrayList<ActivityManager.RecentTaskInfo>(
5005 maxNum < N ? maxNum : N);
5006 for (int i=0; i<N && maxNum > 0; i++) {
5007 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005008 // Return the entry if desired by the caller. We always return
5009 // the first entry, because callers always expect this to be the
5010 // forground app. We may filter others if the caller has
5011 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5012 // we should exclude the entry.
5013 if (i == 0
5014 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005015 || (tr.intent == null)
5016 || ((tr.intent.getFlags()
5017 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5018 ActivityManager.RecentTaskInfo rti
5019 = new ActivityManager.RecentTaskInfo();
5020 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005021 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005022 rti.baseIntent = new Intent(
5023 tr.intent != null ? tr.intent : tr.affinityIntent);
5024 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005025 rti.description = tr.lastDescription;
5026
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005027 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5028 // Check whether this activity is currently available.
5029 try {
5030 if (rti.origActivity != null) {
5031 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5032 continue;
5033 }
5034 } else if (rti.baseIntent != null) {
5035 if (pm.queryIntentActivities(rti.baseIntent,
5036 null, 0) == null) {
5037 continue;
5038 }
5039 }
5040 } catch (RemoteException e) {
5041 // Will never happen.
5042 }
5043 }
5044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 res.add(rti);
5046 maxNum--;
5047 }
5048 }
5049 return res;
5050 }
5051 }
5052
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005053 private TaskRecord taskForIdLocked(int id) {
5054 final int N = mRecentTasks.size();
5055 for (int i=0; i<N; i++) {
5056 TaskRecord tr = mRecentTasks.get(i);
5057 if (tr.taskId == id) {
5058 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005059 }
5060 }
5061 return null;
5062 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005063
5064 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5065 synchronized (this) {
5066 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5067 "getTaskThumbnails()");
5068 TaskRecord tr = taskForIdLocked(id);
5069 if (tr != null) {
5070 return mMainStack.getTaskThumbnailsLocked(tr);
5071 }
5072 }
5073 return null;
5074 }
5075
5076 public boolean removeSubTask(int taskId, int subTaskIndex) {
5077 synchronized (this) {
5078 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5079 "removeSubTask()");
5080 long ident = Binder.clearCallingIdentity();
5081 try {
5082 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5083 } finally {
5084 Binder.restoreCallingIdentity(ident);
5085 }
5086 }
5087 }
5088
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005089 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005090 TaskRecord tr = root.task;
5091 Intent baseIntent = new Intent(
5092 tr.intent != null ? tr.intent : tr.affinityIntent);
5093 ComponentName component = baseIntent.getComponent();
5094 if (component == null) {
5095 Slog.w(TAG, "Now component for base intent of task: " + tr);
5096 return;
5097 }
5098
5099 // Find any running services associated with this app.
5100 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5101 for (ServiceRecord sr : mServices.values()) {
5102 if (sr.packageName.equals(component.getPackageName())) {
5103 services.add(sr);
5104 }
5105 }
5106
5107 // Take care of any running services associated with the app.
5108 for (int i=0; i<services.size(); i++) {
5109 ServiceRecord sr = services.get(i);
5110 if (sr.startRequested) {
5111 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005112 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005113 stopServiceLocked(sr);
5114 } else {
5115 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5116 sr.makeNextStartId(), baseIntent, -1));
5117 if (sr.app != null && sr.app.thread != null) {
5118 sendServiceArgsLocked(sr, false);
5119 }
5120 }
5121 }
5122 }
5123
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005124 if (killProcesses) {
5125 // Find any running processes associated with this app.
5126 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5127 SparseArray<ProcessRecord> appProcs
5128 = mProcessNames.getMap().get(component.getPackageName());
5129 if (appProcs != null) {
5130 for (int i=0; i<appProcs.size(); i++) {
5131 procs.add(appProcs.valueAt(i));
5132 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005133 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005134
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005135 // Kill the running processes.
5136 for (int i=0; i<procs.size(); i++) {
5137 ProcessRecord pr = procs.get(i);
5138 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5139 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5140 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5141 pr.processName, pr.setAdj, "remove task");
5142 Process.killProcessQuiet(pr.pid);
5143 } else {
5144 pr.waitingToKill = "remove task";
5145 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005146 }
5147 }
5148 }
5149
5150 public boolean removeTask(int taskId, int flags) {
5151 synchronized (this) {
5152 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5153 "removeTask()");
5154 long ident = Binder.clearCallingIdentity();
5155 try {
5156 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5157 if (r != null) {
5158 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005159 cleanUpRemovedTaskLocked(r,
5160 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005161 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005162 } else {
5163 TaskRecord tr = null;
5164 int i=0;
5165 while (i < mRecentTasks.size()) {
5166 TaskRecord t = mRecentTasks.get(i);
5167 if (t.taskId == taskId) {
5168 tr = t;
5169 break;
5170 }
5171 i++;
5172 }
5173 if (tr != null) {
5174 if (tr.numActivities <= 0) {
5175 // Caller is just removing a recent task that is
5176 // not actively running. That is easy!
5177 mRecentTasks.remove(i);
5178 } else {
5179 Slog.w(TAG, "removeTask: task " + taskId
5180 + " does not have activities to remove, "
5181 + " but numActivities=" + tr.numActivities
5182 + ": " + tr);
5183 }
5184 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005185 }
5186 } finally {
5187 Binder.restoreCallingIdentity(ident);
5188 }
5189 }
5190 return false;
5191 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5194 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005195 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 TaskRecord jt = startTask;
5197
5198 // First look backwards
5199 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005200 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 if (r.task != jt) {
5202 jt = r.task;
5203 if (affinity.equals(jt.affinity)) {
5204 return j;
5205 }
5206 }
5207 }
5208
5209 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005210 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005211 jt = startTask;
5212 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005213 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005214 if (r.task != jt) {
5215 if (affinity.equals(jt.affinity)) {
5216 return j;
5217 }
5218 jt = r.task;
5219 }
5220 }
5221
5222 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005223 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 return N-1;
5225 }
5226
5227 return -1;
5228 }
5229
5230 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005231 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005233 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005234 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5235 "moveTaskToFront()");
5236
5237 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005238 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5239 Binder.getCallingUid(), "Task to front")) {
5240 return;
5241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 final long origId = Binder.clearCallingIdentity();
5243 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005244 TaskRecord tr = taskForIdLocked(task);
5245 if (tr != null) {
5246 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5247 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005249 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5250 // Caller wants the home activity moved with it. To accomplish this,
5251 // we'll just move the home task to the top first.
5252 mMainStack.moveHomeToFrontLocked();
5253 }
5254 mMainStack.moveTaskToFrontLocked(tr, null);
5255 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005257 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5258 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005260 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5261 mMainStack.mUserLeaving = true;
5262 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005263 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5264 // Caller wants the home activity moved with it. To accomplish this,
5265 // we'll just move the home task to the top first.
5266 mMainStack.moveHomeToFrontLocked();
5267 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005268 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005269 return;
5270 }
5271 }
5272 } finally {
5273 Binder.restoreCallingIdentity(origId);
5274 }
5275 }
5276 }
5277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005278 public void moveTaskToBack(int task) {
5279 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5280 "moveTaskToBack()");
5281
5282 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005283 if (mMainStack.mResumedActivity != null
5284 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005285 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5286 Binder.getCallingUid(), "Task to back")) {
5287 return;
5288 }
5289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005291 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005292 Binder.restoreCallingIdentity(origId);
5293 }
5294 }
5295
5296 /**
5297 * Moves an activity, and all of the other activities within the same task, to the bottom
5298 * of the history stack. The activity's order within the task is unchanged.
5299 *
5300 * @param token A reference to the activity we wish to move
5301 * @param nonRoot If false then this only works if the activity is the root
5302 * of a task; if true it will work for any activity in a task.
5303 * @return Returns true if the move completed, false if not.
5304 */
5305 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5306 synchronized(this) {
5307 final long origId = Binder.clearCallingIdentity();
5308 int taskId = getTaskForActivityLocked(token, !nonRoot);
5309 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005310 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 }
5312 Binder.restoreCallingIdentity(origId);
5313 }
5314 return false;
5315 }
5316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 public void moveTaskBackwards(int task) {
5318 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5319 "moveTaskBackwards()");
5320
5321 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005322 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5323 Binder.getCallingUid(), "Task backwards")) {
5324 return;
5325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005326 final long origId = Binder.clearCallingIdentity();
5327 moveTaskBackwardsLocked(task);
5328 Binder.restoreCallingIdentity(origId);
5329 }
5330 }
5331
5332 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005333 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 }
5335
5336 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5337 synchronized(this) {
5338 return getTaskForActivityLocked(token, onlyRoot);
5339 }
5340 }
5341
5342 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005343 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005344 TaskRecord lastTask = null;
5345 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005346 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 if (r == token) {
5348 if (!onlyRoot || lastTask != r.task) {
5349 return r.task.taskId;
5350 }
5351 return -1;
5352 }
5353 lastTask = r.task;
5354 }
5355
5356 return -1;
5357 }
5358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005359 public void finishOtherInstances(IBinder token, ComponentName className) {
5360 synchronized(this) {
5361 final long origId = Binder.clearCallingIdentity();
5362
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005363 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 TaskRecord lastTask = null;
5365 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005366 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005367 if (r.realActivity.equals(className)
5368 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005369 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005370 null, "others")) {
5371 i--;
5372 N--;
5373 }
5374 }
5375 lastTask = r.task;
5376 }
5377
5378 Binder.restoreCallingIdentity(origId);
5379 }
5380 }
5381
5382 // =========================================================
5383 // THUMBNAILS
5384 // =========================================================
5385
5386 public void reportThumbnail(IBinder token,
5387 Bitmap thumbnail, CharSequence description) {
5388 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5389 final long origId = Binder.clearCallingIdentity();
5390 sendPendingThumbnail(null, token, thumbnail, description, true);
5391 Binder.restoreCallingIdentity(origId);
5392 }
5393
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005394 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 Bitmap thumbnail, CharSequence description, boolean always) {
5396 TaskRecord task = null;
5397 ArrayList receivers = null;
5398
5399 //System.out.println("Send pending thumbnail: " + r);
5400
5401 synchronized(this) {
5402 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005403 r = mMainStack.isInStackLocked(token);
5404 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 return;
5406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005408 if (thumbnail == null && r.thumbHolder != null) {
5409 thumbnail = r.thumbHolder.lastThumbnail;
5410 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005411 }
5412 if (thumbnail == null && !always) {
5413 // If there is no thumbnail, and this entry is not actually
5414 // going away, then abort for now and pick up the next
5415 // thumbnail we get.
5416 return;
5417 }
5418 task = r.task;
5419
5420 int N = mPendingThumbnails.size();
5421 int i=0;
5422 while (i<N) {
5423 PendingThumbnailsRecord pr =
5424 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5425 //System.out.println("Looking in " + pr.pendingRecords);
5426 if (pr.pendingRecords.remove(r)) {
5427 if (receivers == null) {
5428 receivers = new ArrayList();
5429 }
5430 receivers.add(pr);
5431 if (pr.pendingRecords.size() == 0) {
5432 pr.finished = true;
5433 mPendingThumbnails.remove(i);
5434 N--;
5435 continue;
5436 }
5437 }
5438 i++;
5439 }
5440 }
5441
5442 if (receivers != null) {
5443 final int N = receivers.size();
5444 for (int i=0; i<N; i++) {
5445 try {
5446 PendingThumbnailsRecord pr =
5447 (PendingThumbnailsRecord)receivers.get(i);
5448 pr.receiver.newThumbnail(
5449 task != null ? task.taskId : -1, thumbnail, description);
5450 if (pr.finished) {
5451 pr.receiver.finished();
5452 }
5453 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005454 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005455 }
5456 }
5457 }
5458 }
5459
5460 // =========================================================
5461 // CONTENT PROVIDERS
5462 // =========================================================
5463
Jeff Brown10e89712011-07-08 18:52:57 -07005464 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5465 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005467 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005469 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 } catch (RemoteException ex) {
5471 }
5472 if (providers != null) {
5473 final int N = providers.size();
5474 for (int i=0; i<N; i++) {
5475 ProviderInfo cpi =
5476 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005477 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5478 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 if (cpr == null) {
5480 cpr = new ContentProviderRecord(cpi, app.info);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005481 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005482 }
5483 app.pubProviders.put(cpi.name, cpr);
5484 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005485 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 }
5487 }
5488 return providers;
5489 }
5490
5491 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005492 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5494 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5495 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005496 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005497 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005498 return null;
5499 }
5500 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005501 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005502 == PackageManager.PERMISSION_GRANTED) {
5503 return null;
5504 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005505
5506 PathPermission[] pps = cpi.pathPermissions;
5507 if (pps != null) {
5508 int i = pps.length;
5509 while (i > 0) {
5510 i--;
5511 PathPermission pp = pps[i];
5512 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005513 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005514 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005515 return null;
5516 }
5517 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005518 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005519 == PackageManager.PERMISSION_GRANTED) {
5520 return null;
5521 }
5522 }
5523 }
5524
Dianne Hackbornb424b632010-08-18 15:59:05 -07005525 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5526 if (perms != null) {
5527 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5528 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5529 return null;
5530 }
5531 }
5532 }
5533
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005534 String msg;
5535 if (!cpi.exported) {
5536 msg = "Permission Denial: opening provider " + cpi.name
5537 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5538 + ", uid=" + callingUid + ") that is not exported from uid "
5539 + cpi.applicationInfo.uid;
5540 } else {
5541 msg = "Permission Denial: opening provider " + cpi.name
5542 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5543 + ", uid=" + callingUid + ") requires "
5544 + cpi.readPermission + " or " + cpi.writePermission;
5545 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005546 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005547 return msg;
5548 }
5549
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005550 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5551 if (r != null) {
5552 Integer cnt = r.conProviders.get(cpr);
5553 if (DEBUG_PROVIDER) Slog.v(TAG,
5554 "Adding provider requested by "
5555 + r.processName + " from process "
5556 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5557 + " cnt=" + (cnt == null ? 1 : cnt));
5558 if (cnt == null) {
5559 cpr.clients.add(r);
5560 r.conProviders.put(cpr, new Integer(1));
5561 return true;
5562 } else {
5563 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5564 }
5565 } else {
5566 cpr.externals++;
5567 }
5568 return false;
5569 }
5570
5571 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5572 if (r != null) {
5573 Integer cnt = r.conProviders.get(cpr);
5574 if (DEBUG_PROVIDER) Slog.v(TAG,
5575 "Removing provider requested by "
5576 + r.processName + " from process "
5577 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5578 + " cnt=" + cnt);
5579 if (cnt == null || cnt.intValue() <= 1) {
5580 cpr.clients.remove(r);
5581 r.conProviders.remove(cpr);
5582 return true;
5583 } else {
5584 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5585 }
5586 } else {
5587 cpr.externals++;
5588 }
5589 return false;
5590 }
5591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 private final ContentProviderHolder getContentProviderImpl(
5593 IApplicationThread caller, String name) {
5594 ContentProviderRecord cpr;
5595 ProviderInfo cpi = null;
5596
5597 synchronized(this) {
5598 ProcessRecord r = null;
5599 if (caller != null) {
5600 r = getRecordForAppLocked(caller);
5601 if (r == null) {
5602 throw new SecurityException(
5603 "Unable to find app for caller " + caller
5604 + " (pid=" + Binder.getCallingPid()
5605 + ") when getting content provider " + name);
5606 }
5607 }
5608
5609 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005610 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005611 boolean providerRunning = cpr != null;
5612 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005614 String msg;
5615 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5616 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 }
5618
5619 if (r != null && cpr.canRunHere(r)) {
5620 // This provider has been published or is in the process
5621 // of being published... but it is also allowed to run
5622 // in the caller's process, so don't make a connection
5623 // and just let the caller instantiate its own instance.
5624 if (cpr.provider != null) {
5625 // don't give caller the provider object, it needs
5626 // to make its own.
5627 cpr = new ContentProviderRecord(cpr);
5628 }
5629 return cpr;
5630 }
5631
5632 final long origId = Binder.clearCallingIdentity();
5633
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005634 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005635 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005636 final boolean countChanged = incProviderCount(r, cpr);
5637 if (countChanged) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005638 if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005639 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005640 // make sure to count it as being accessed and thus
5641 // back up on the LRU list. This is good because
5642 // content providers are often expensive to start.
5643 updateLruProcessLocked(cpr.app, false, true);
5644 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005645 }
5646
5647 if (cpr.app != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005648 if (false) {
5649 if (cpr.name.flattenToShortString().equals(
5650 "com.android.providers.calendar/.CalendarProvider2")) {
5651 Slog.v(TAG, "****************** KILLING "
5652 + cpr.name.flattenToShortString());
5653 Process.killProcess(cpr.app.pid);
5654 }
5655 }
5656 boolean success = updateOomAdjLocked(cpr.app);
5657 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5658 // NOTE: there is still a race here where a signal could be
5659 // pending on the process even though we managed to update its
5660 // adj level. Not sure what to do about this, but at least
5661 // the race is now smaller.
5662 if (!success) {
5663 // Uh oh... it looks like the provider's process
5664 // has been killed on us. We need to wait for a new
5665 // process to be started, and make sure its death
5666 // doesn't kill our process.
5667 Slog.i(TAG,
5668 "Existing provider " + cpr.name.flattenToShortString()
5669 + " is crashing; detaching " + r);
5670 boolean lastRef = decProviderCount(r, cpr);
5671 appDiedLocked(cpr.app, cpr.app.pid, cpr.app.thread);
5672 if (!lastRef) {
5673 // This wasn't the last ref our process had on
5674 // the provider... we have now been killed, bail.
5675 return null;
5676 }
5677 providerRunning = false;
5678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005679 }
5680
5681 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005683
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005684 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005685 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005686 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005687 resolveContentProvider(name,
5688 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 } catch (RemoteException ex) {
5690 }
5691 if (cpi == null) {
5692 return null;
5693 }
5694
Dianne Hackbornb424b632010-08-18 15:59:05 -07005695 String msg;
5696 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5697 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005698 }
5699
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005700 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005701 && !cpi.processName.equals("system")) {
5702 // If this content provider does not run in the system
5703 // process, and the system is not yet ready to run other
5704 // processes, then fail fast instead of hanging.
5705 throw new IllegalArgumentException(
5706 "Attempt to launch content provider before system ready");
5707 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005708
5709 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5710 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005711 final boolean firstClass = cpr == null;
5712 if (firstClass) {
5713 try {
5714 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005715 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 getApplicationInfo(
5717 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005718 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005720 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 + cpi.name);
5722 return null;
5723 }
5724 cpr = new ContentProviderRecord(cpi, ai);
5725 } catch (RemoteException ex) {
5726 // pm is in same process, this will never happen.
5727 }
5728 }
5729
5730 if (r != null && cpr.canRunHere(r)) {
5731 // If this is a multiprocess provider, then just return its
5732 // info and allow the caller to instantiate it. Only do
5733 // this if the provider is the same user as the caller's
5734 // process, or can run as root (so can be in any process).
5735 return cpr;
5736 }
5737
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005738 if (DEBUG_PROVIDER) {
5739 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005740 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005741 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005742 }
5743
5744 // This is single process, and our app is now connecting to it.
5745 // See if we are already in the process of launching this
5746 // provider.
5747 final int N = mLaunchingProviders.size();
5748 int i;
5749 for (i=0; i<N; i++) {
5750 if (mLaunchingProviders.get(i) == cpr) {
5751 break;
5752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753 }
5754
5755 // If the provider is not already being launched, then get it
5756 // started.
5757 if (i >= N) {
5758 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005759
5760 try {
5761 // Content provider is now in use, its package can't be stopped.
5762 try {
5763 AppGlobals.getPackageManager().setPackageStoppedState(
5764 cpr.appInfo.packageName, false);
5765 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005766 } catch (IllegalArgumentException e) {
5767 Slog.w(TAG, "Failed trying to unstop package "
5768 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005769 }
5770
5771 ProcessRecord proc = startProcessLocked(cpi.processName,
5772 cpr.appInfo, false, 0, "content provider",
5773 new ComponentName(cpi.applicationInfo.packageName,
5774 cpi.name), false);
5775 if (proc == null) {
5776 Slog.w(TAG, "Unable to launch app "
5777 + cpi.applicationInfo.packageName + "/"
5778 + cpi.applicationInfo.uid + " for provider "
5779 + name + ": process is bad");
5780 return null;
5781 }
5782 cpr.launchingApp = proc;
5783 mLaunchingProviders.add(cpr);
5784 } finally {
5785 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005787 }
5788
5789 // Make sure the provider is published (the same provider class
5790 // may be published under multiple names).
5791 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005792 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793 }
5794 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005795 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005796 }
5797 }
5798
5799 // Wait for the provider to be published...
5800 synchronized (cpr) {
5801 while (cpr.provider == null) {
5802 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005803 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005804 + cpi.applicationInfo.packageName + "/"
5805 + cpi.applicationInfo.uid + " for provider "
5806 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005807 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005808 cpi.applicationInfo.packageName,
5809 cpi.applicationInfo.uid, name);
5810 return null;
5811 }
5812 try {
5813 cpr.wait();
5814 } catch (InterruptedException ex) {
5815 }
5816 }
5817 }
5818 return cpr;
5819 }
5820
5821 public final ContentProviderHolder getContentProvider(
5822 IApplicationThread caller, String name) {
5823 if (caller == null) {
5824 String msg = "null IApplicationThread when getting content provider "
5825 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005826 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 throw new SecurityException(msg);
5828 }
5829
5830 return getContentProviderImpl(caller, name);
5831 }
5832
5833 private ContentProviderHolder getContentProviderExternal(String name) {
5834 return getContentProviderImpl(null, name);
5835 }
5836
5837 /**
5838 * Drop a content provider from a ProcessRecord's bookkeeping
5839 * @param cpr
5840 */
5841 public void removeContentProvider(IApplicationThread caller, String name) {
5842 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005843 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005845 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005846 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005847 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 return;
5849 }
5850 final ProcessRecord r = getRecordForAppLocked(caller);
5851 if (r == null) {
5852 throw new SecurityException(
5853 "Unable to find app for caller " + caller +
5854 " when removing content provider " + name);
5855 }
5856 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005857 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5858 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005859 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005860 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005861 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005862 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005863 return;
5864 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005865 if (decProviderCount(r, localCpr)) {
5866 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 }
5870 }
5871
5872 private void removeContentProviderExternal(String name) {
5873 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005874 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005875 if(cpr == null) {
5876 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005877 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005878 return;
5879 }
5880
5881 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005882 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5883 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884 localCpr.externals--;
5885 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005886 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005887 }
5888 updateOomAdjLocked();
5889 }
5890 }
5891
5892 public final void publishContentProviders(IApplicationThread caller,
5893 List<ContentProviderHolder> providers) {
5894 if (providers == null) {
5895 return;
5896 }
5897
5898 synchronized(this) {
5899 final ProcessRecord r = getRecordForAppLocked(caller);
5900 if (r == null) {
5901 throw new SecurityException(
5902 "Unable to find app for caller " + caller
5903 + " (pid=" + Binder.getCallingPid()
5904 + ") when publishing content providers");
5905 }
5906
5907 final long origId = Binder.clearCallingIdentity();
5908
5909 final int N = providers.size();
5910 for (int i=0; i<N; i++) {
5911 ContentProviderHolder src = providers.get(i);
5912 if (src == null || src.info == null || src.provider == null) {
5913 continue;
5914 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005915 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005917 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5918 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 String names[] = dst.info.authority.split(";");
5920 for (int j = 0; j < names.length; j++) {
5921 mProvidersByName.put(names[j], dst);
5922 }
5923
5924 int NL = mLaunchingProviders.size();
5925 int j;
5926 for (j=0; j<NL; j++) {
5927 if (mLaunchingProviders.get(j) == dst) {
5928 mLaunchingProviders.remove(j);
5929 j--;
5930 NL--;
5931 }
5932 }
5933 synchronized (dst) {
5934 dst.provider = src.provider;
5935 dst.app = r;
5936 dst.notifyAll();
5937 }
5938 updateOomAdjLocked(r);
5939 }
5940 }
5941
5942 Binder.restoreCallingIdentity(origId);
5943 }
5944 }
5945
5946 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005947 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005948 synchronized (mSelf) {
5949 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5950 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005951 if (providers != null) {
5952 for (int i=providers.size()-1; i>=0; i--) {
5953 ProviderInfo pi = (ProviderInfo)providers.get(i);
5954 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5955 Slog.w(TAG, "Not installing system proc provider " + pi.name
5956 + ": not system .apk");
5957 providers.remove(i);
5958 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005959 }
5960 }
5961 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005962 if (providers != null) {
5963 mSystemThread.installSystemProviders(providers);
5964 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005965
5966 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005967
5968 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005969 }
5970
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005971 /**
5972 * Allows app to retrieve the MIME type of a URI without having permission
5973 * to access its content provider.
5974 *
5975 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5976 *
5977 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5978 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5979 */
5980 public String getProviderMimeType(Uri uri) {
5981 final String name = uri.getAuthority();
5982 final long ident = Binder.clearCallingIdentity();
5983 ContentProviderHolder holder = null;
5984
5985 try {
5986 holder = getContentProviderExternal(name);
5987 if (holder != null) {
5988 return holder.provider.getType(uri);
5989 }
5990 } catch (RemoteException e) {
5991 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5992 return null;
5993 } finally {
5994 if (holder != null) {
5995 removeContentProviderExternal(name);
5996 }
5997 Binder.restoreCallingIdentity(ident);
5998 }
5999
6000 return null;
6001 }
6002
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 // =========================================================
6004 // GLOBAL MANAGEMENT
6005 // =========================================================
6006
6007 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6008 ApplicationInfo info, String customProcess) {
6009 String proc = customProcess != null ? customProcess : info.processName;
6010 BatteryStatsImpl.Uid.Proc ps = null;
6011 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6012 synchronized (stats) {
6013 ps = stats.getProcessStatsLocked(info.uid, proc);
6014 }
6015 return new ProcessRecord(ps, thread, info, proc);
6016 }
6017
6018 final ProcessRecord addAppLocked(ApplicationInfo info) {
6019 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6020
6021 if (app == null) {
6022 app = newProcessRecordLocked(null, info, null);
6023 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006024 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 }
6026
Dianne Hackborne7f97212011-02-24 14:40:20 -08006027 // This package really, really can not be stopped.
6028 try {
6029 AppGlobals.getPackageManager().setPackageStoppedState(
6030 info.packageName, false);
6031 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006032 } catch (IllegalArgumentException e) {
6033 Slog.w(TAG, "Failed trying to unstop package "
6034 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006035 }
6036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006037 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6038 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6039 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006040 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 }
6042 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6043 mPersistentStartingProcesses.add(app);
6044 startProcessLocked(app, "added application", app.processName);
6045 }
6046
6047 return app;
6048 }
6049
6050 public void unhandledBack() {
6051 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6052 "unhandledBack()");
6053
6054 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006055 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006056 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006057 TAG, "Performing unhandledBack(): stack size = " + count);
6058 if (count > 1) {
6059 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006060 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006061 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6062 Binder.restoreCallingIdentity(origId);
6063 }
6064 }
6065 }
6066
6067 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6068 String name = uri.getAuthority();
6069 ContentProviderHolder cph = getContentProviderExternal(name);
6070 ParcelFileDescriptor pfd = null;
6071 if (cph != null) {
6072 // We record the binder invoker's uid in thread-local storage before
6073 // going to the content provider to open the file. Later, in the code
6074 // that handles all permissions checks, we look for this uid and use
6075 // that rather than the Activity Manager's own uid. The effect is that
6076 // we do the check against the caller's permissions even though it looks
6077 // to the content provider like the Activity Manager itself is making
6078 // the request.
6079 sCallerIdentity.set(new Identity(
6080 Binder.getCallingPid(), Binder.getCallingUid()));
6081 try {
6082 pfd = cph.provider.openFile(uri, "r");
6083 } catch (FileNotFoundException e) {
6084 // do nothing; pfd will be returned null
6085 } finally {
6086 // Ensure that whatever happens, we clean up the identity state
6087 sCallerIdentity.remove();
6088 }
6089
6090 // We've got the fd now, so we're done with the provider.
6091 removeContentProviderExternal(name);
6092 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006093 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 }
6095 return pfd;
6096 }
6097
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006098 // Actually is sleeping or shutting down or whatever else in the future
6099 // is an inactive state.
6100 public boolean isSleeping() {
6101 return mSleeping || mShuttingDown;
6102 }
6103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104 public void goingToSleep() {
6105 synchronized(this) {
6106 mSleeping = true;
6107 mWindowManager.setEventDispatching(false);
6108
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006109 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006110
6111 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006112 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006113 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6114 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006115 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006116 }
6117 }
6118
Dianne Hackborn55280a92009-05-07 15:53:46 -07006119 public boolean shutdown(int timeout) {
6120 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6121 != PackageManager.PERMISSION_GRANTED) {
6122 throw new SecurityException("Requires permission "
6123 + android.Manifest.permission.SHUTDOWN);
6124 }
6125
6126 boolean timedout = false;
6127
6128 synchronized(this) {
6129 mShuttingDown = true;
6130 mWindowManager.setEventDispatching(false);
6131
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006132 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006133 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006134 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006135 while (mMainStack.mResumedActivity != null
6136 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006137 long delay = endTime - System.currentTimeMillis();
6138 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006139 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006140 timedout = true;
6141 break;
6142 }
6143 try {
6144 this.wait();
6145 } catch (InterruptedException e) {
6146 }
6147 }
6148 }
6149 }
6150
6151 mUsageStatsService.shutdown();
6152 mBatteryStatsService.shutdown();
6153
6154 return timedout;
6155 }
6156
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006157 public final void activitySlept(IBinder token) {
6158 if (localLOGV) Slog.v(
6159 TAG, "Activity slept: token=" + token);
6160
6161 ActivityRecord r = null;
6162
6163 final long origId = Binder.clearCallingIdentity();
6164
6165 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006166 r = mMainStack.isInStackLocked(token);
6167 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006168 mMainStack.activitySleptLocked(r);
6169 }
6170 }
6171
6172 Binder.restoreCallingIdentity(origId);
6173 }
6174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006175 public void wakingUp() {
6176 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 mWindowManager.setEventDispatching(true);
6178 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006179 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006180 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006181 }
6182 }
6183
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006184 public void stopAppSwitches() {
6185 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6186 != PackageManager.PERMISSION_GRANTED) {
6187 throw new SecurityException("Requires permission "
6188 + android.Manifest.permission.STOP_APP_SWITCHES);
6189 }
6190
6191 synchronized(this) {
6192 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6193 + APP_SWITCH_DELAY_TIME;
6194 mDidAppSwitch = false;
6195 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6196 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6197 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6198 }
6199 }
6200
6201 public void resumeAppSwitches() {
6202 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6203 != PackageManager.PERMISSION_GRANTED) {
6204 throw new SecurityException("Requires permission "
6205 + android.Manifest.permission.STOP_APP_SWITCHES);
6206 }
6207
6208 synchronized(this) {
6209 // Note that we don't execute any pending app switches... we will
6210 // let those wait until either the timeout, or the next start
6211 // activity request.
6212 mAppSwitchesAllowedTime = 0;
6213 }
6214 }
6215
6216 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6217 String name) {
6218 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6219 return true;
6220 }
6221
6222 final int perm = checkComponentPermission(
6223 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006224 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006225 if (perm == PackageManager.PERMISSION_GRANTED) {
6226 return true;
6227 }
6228
Joe Onorato8a9b2202010-02-26 18:56:32 -08006229 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006230 return false;
6231 }
6232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006233 public void setDebugApp(String packageName, boolean waitForDebugger,
6234 boolean persistent) {
6235 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6236 "setDebugApp()");
6237
6238 // Note that this is not really thread safe if there are multiple
6239 // callers into it at the same time, but that's not a situation we
6240 // care about.
6241 if (persistent) {
6242 final ContentResolver resolver = mContext.getContentResolver();
6243 Settings.System.putString(
6244 resolver, Settings.System.DEBUG_APP,
6245 packageName);
6246 Settings.System.putInt(
6247 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6248 waitForDebugger ? 1 : 0);
6249 }
6250
6251 synchronized (this) {
6252 if (!persistent) {
6253 mOrigDebugApp = mDebugApp;
6254 mOrigWaitForDebugger = mWaitForDebugger;
6255 }
6256 mDebugApp = packageName;
6257 mWaitForDebugger = waitForDebugger;
6258 mDebugTransient = !persistent;
6259 if (packageName != null) {
6260 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006261 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006262 Binder.restoreCallingIdentity(origId);
6263 }
6264 }
6265 }
6266
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006267 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6268 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6269 synchronized (this) {
6270 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6271 if (!isDebuggable) {
6272 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6273 throw new SecurityException("Process not debuggable: " + app.packageName);
6274 }
6275 }
6276 mProfileApp = processName;
6277 mProfileFile = profileFile;
6278 if (mProfileFd != null) {
6279 try {
6280 mProfileFd.close();
6281 } catch (IOException e) {
6282 }
6283 mProfileFd = null;
6284 }
6285 mProfileFd = profileFd;
6286 mProfileType = 0;
6287 mAutoStopProfiler = autoStopProfiler;
6288 }
6289 }
6290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 public void setAlwaysFinish(boolean enabled) {
6292 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6293 "setAlwaysFinish()");
6294
6295 Settings.System.putInt(
6296 mContext.getContentResolver(),
6297 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6298
6299 synchronized (this) {
6300 mAlwaysFinishActivities = enabled;
6301 }
6302 }
6303
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006304 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006305 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006306 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006307 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006308 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 }
6310 }
6311
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006312 public boolean isUserAMonkey() {
6313 // For now the fact that there is a controller implies
6314 // we have a monkey.
6315 synchronized (this) {
6316 return mController != null;
6317 }
6318 }
6319
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006320 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006321 synchronized (this) {
6322 mWatchers.register(watcher);
6323 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006324 }
6325
6326 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006327 synchronized (this) {
6328 mWatchers.unregister(watcher);
6329 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006330 }
6331
Jeff Sharkeya4620792011-05-20 15:29:23 -07006332 public void registerProcessObserver(IProcessObserver observer) {
6333 mProcessObservers.register(observer);
6334 }
6335
6336 public void unregisterProcessObserver(IProcessObserver observer) {
6337 mProcessObservers.unregister(observer);
6338 }
6339
Daniel Sandler69a48172010-06-23 16:29:36 -04006340 public void setImmersive(IBinder token, boolean immersive) {
6341 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006342 ActivityRecord r = mMainStack.isInStackLocked(token);
6343 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006344 throw new IllegalArgumentException();
6345 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006346 r.immersive = immersive;
6347 }
6348 }
6349
6350 public boolean isImmersive(IBinder token) {
6351 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006352 ActivityRecord r = mMainStack.isInStackLocked(token);
6353 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006354 throw new IllegalArgumentException();
6355 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006356 return r.immersive;
6357 }
6358 }
6359
6360 public boolean isTopActivityImmersive() {
6361 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006362 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006363 return (r != null) ? r.immersive : false;
6364 }
6365 }
6366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006367 public final void enterSafeMode() {
6368 synchronized(this) {
6369 // It only makes sense to do this before the system is ready
6370 // and started launching other packages.
6371 if (!mSystemReady) {
6372 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006373 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 } catch (RemoteException e) {
6375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006376 }
6377 }
6378 }
6379
Jeff Brownb09abc12011-01-13 21:08:27 -08006380 public final void showSafeModeOverlay() {
6381 View v = LayoutInflater.from(mContext).inflate(
6382 com.android.internal.R.layout.safe_mode, null);
6383 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6384 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6385 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6386 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6387 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6388 lp.format = v.getBackground().getOpacity();
6389 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6390 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6391 ((WindowManager)mContext.getSystemService(
6392 Context.WINDOW_SERVICE)).addView(v, lp);
6393 }
6394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 public void noteWakeupAlarm(IIntentSender sender) {
6396 if (!(sender instanceof PendingIntentRecord)) {
6397 return;
6398 }
6399 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6400 synchronized (stats) {
6401 if (mBatteryStatsService.isOnBattery()) {
6402 mBatteryStatsService.enforceCallingPermission();
6403 PendingIntentRecord rec = (PendingIntentRecord)sender;
6404 int MY_UID = Binder.getCallingUid();
6405 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6406 BatteryStatsImpl.Uid.Pkg pkg =
6407 stats.getPackageStatsLocked(uid, rec.key.packageName);
6408 pkg.incWakeupsLocked();
6409 }
6410 }
6411 }
6412
Dianne Hackborn64825172011-03-02 21:32:58 -08006413 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006414 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006415 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006416 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006417 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006418 // XXX Note: don't acquire main activity lock here, because the window
6419 // manager calls in with its locks held.
6420
6421 boolean killed = false;
6422 synchronized (mPidsSelfLocked) {
6423 int[] types = new int[pids.length];
6424 int worstType = 0;
6425 for (int i=0; i<pids.length; i++) {
6426 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6427 if (proc != null) {
6428 int type = proc.setAdj;
6429 types[i] = type;
6430 if (type > worstType) {
6431 worstType = type;
6432 }
6433 }
6434 }
6435
Dianne Hackborn64825172011-03-02 21:32:58 -08006436 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006438 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6439 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006440 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006441
6442 // If this is not a secure call, don't let it kill processes that
6443 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006444 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6445 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006446 }
6447
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006448 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006449 for (int i=0; i<pids.length; i++) {
6450 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6451 if (proc == null) {
6452 continue;
6453 }
6454 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006455 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006456 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006457 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6458 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006460 proc.killedBackground = true;
6461 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 }
6463 }
6464 }
6465 return killed;
6466 }
6467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006468 public final void startRunning(String pkg, String cls, String action,
6469 String data) {
6470 synchronized(this) {
6471 if (mStartRunning) {
6472 return;
6473 }
6474 mStartRunning = true;
6475 mTopComponent = pkg != null && cls != null
6476 ? new ComponentName(pkg, cls) : null;
6477 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6478 mTopData = data;
6479 if (!mSystemReady) {
6480 return;
6481 }
6482 }
6483
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006484 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006485 }
6486
6487 private void retrieveSettings() {
6488 final ContentResolver resolver = mContext.getContentResolver();
6489 String debugApp = Settings.System.getString(
6490 resolver, Settings.System.DEBUG_APP);
6491 boolean waitForDebugger = Settings.System.getInt(
6492 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6493 boolean alwaysFinishActivities = Settings.System.getInt(
6494 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6495
6496 Configuration configuration = new Configuration();
6497 Settings.System.getConfiguration(resolver, configuration);
6498
6499 synchronized (this) {
6500 mDebugApp = mOrigDebugApp = debugApp;
6501 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6502 mAlwaysFinishActivities = alwaysFinishActivities;
6503 // This happens before any activities are started, so we can
6504 // change mConfiguration in-place.
6505 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006506 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006507 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006508 }
6509 }
6510
6511 public boolean testIsSystemReady() {
6512 // no need to synchronize(this) just to read & return the value
6513 return mSystemReady;
6514 }
6515
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006516 private static File getCalledPreBootReceiversFile() {
6517 File dataDir = Environment.getDataDirectory();
6518 File systemDir = new File(dataDir, "system");
6519 File fname = new File(systemDir, "called_pre_boots.dat");
6520 return fname;
6521 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006522
6523 static final int LAST_DONE_VERSION = 10000;
6524
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006525 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6526 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6527 File file = getCalledPreBootReceiversFile();
6528 FileInputStream fis = null;
6529 try {
6530 fis = new FileInputStream(file);
6531 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006532 int fvers = dis.readInt();
6533 if (fvers == LAST_DONE_VERSION) {
6534 String vers = dis.readUTF();
6535 String codename = dis.readUTF();
6536 String build = dis.readUTF();
6537 if (android.os.Build.VERSION.RELEASE.equals(vers)
6538 && android.os.Build.VERSION.CODENAME.equals(codename)
6539 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6540 int num = dis.readInt();
6541 while (num > 0) {
6542 num--;
6543 String pkg = dis.readUTF();
6544 String cls = dis.readUTF();
6545 lastDoneReceivers.add(new ComponentName(pkg, cls));
6546 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006547 }
6548 }
6549 } catch (FileNotFoundException e) {
6550 } catch (IOException e) {
6551 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6552 } finally {
6553 if (fis != null) {
6554 try {
6555 fis.close();
6556 } catch (IOException e) {
6557 }
6558 }
6559 }
6560 return lastDoneReceivers;
6561 }
6562
6563 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6564 File file = getCalledPreBootReceiversFile();
6565 FileOutputStream fos = null;
6566 DataOutputStream dos = null;
6567 try {
6568 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6569 fos = new FileOutputStream(file);
6570 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006571 dos.writeInt(LAST_DONE_VERSION);
6572 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006573 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006574 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006575 dos.writeInt(list.size());
6576 for (int i=0; i<list.size(); i++) {
6577 dos.writeUTF(list.get(i).getPackageName());
6578 dos.writeUTF(list.get(i).getClassName());
6579 }
6580 } catch (IOException e) {
6581 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6582 file.delete();
6583 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006584 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006585 if (dos != null) {
6586 try {
6587 dos.close();
6588 } catch (IOException e) {
6589 // TODO Auto-generated catch block
6590 e.printStackTrace();
6591 }
6592 }
6593 }
6594 }
6595
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006596 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006597 synchronized(this) {
6598 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006599 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006600 return;
6601 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006602
6603 // Check to see if there are any update receivers to run.
6604 if (!mDidUpdate) {
6605 if (mWaitingUpdate) {
6606 return;
6607 }
6608 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6609 List<ResolveInfo> ris = null;
6610 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006611 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006612 intent, null, 0);
6613 } catch (RemoteException e) {
6614 }
6615 if (ris != null) {
6616 for (int i=ris.size()-1; i>=0; i--) {
6617 if ((ris.get(i).activityInfo.applicationInfo.flags
6618 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6619 ris.remove(i);
6620 }
6621 }
6622 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006623
6624 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6625
6626 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006627 for (int i=0; i<ris.size(); i++) {
6628 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006629 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6630 if (lastDoneReceivers.contains(comp)) {
6631 ris.remove(i);
6632 i--;
6633 }
6634 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006635
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006636 for (int i=0; i<ris.size(); i++) {
6637 ActivityInfo ai = ris.get(i).activityInfo;
6638 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6639 doneReceivers.add(comp);
6640 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006641 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006642 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006643 finisher = new IIntentReceiver.Stub() {
6644 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006645 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006646 boolean sticky) {
6647 // The raw IIntentReceiver interface is called
6648 // with the AM lock held, so redispatch to
6649 // execute our code without the lock.
6650 mHandler.post(new Runnable() {
6651 public void run() {
6652 synchronized (ActivityManagerService.this) {
6653 mDidUpdate = true;
6654 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006655 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006656 showBootMessage(mContext.getText(
6657 R.string.android_upgrading_complete),
6658 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006659 systemReady(goingCallback);
6660 }
6661 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006662 }
6663 };
6664 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006665 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006666 broadcastIntentLocked(null, null, intent, null, finisher,
6667 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006668 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006669 mWaitingUpdate = true;
6670 }
6671 }
6672 }
6673 if (mWaitingUpdate) {
6674 return;
6675 }
6676 mDidUpdate = true;
6677 }
6678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 mSystemReady = true;
6680 if (!mStartRunning) {
6681 return;
6682 }
6683 }
6684
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006685 ArrayList<ProcessRecord> procsToKill = null;
6686 synchronized(mPidsSelfLocked) {
6687 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6688 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6689 if (!isAllowedWhileBooting(proc.info)){
6690 if (procsToKill == null) {
6691 procsToKill = new ArrayList<ProcessRecord>();
6692 }
6693 procsToKill.add(proc);
6694 }
6695 }
6696 }
6697
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006698 synchronized(this) {
6699 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006700 for (int i=procsToKill.size()-1; i>=0; i--) {
6701 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006702 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006703 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006704 }
6705 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006706
6707 // Now that we have cleaned up any update processes, we
6708 // are ready to start launching real processes and know that
6709 // we won't trample on them any more.
6710 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006711 }
6712
Joe Onorato8a9b2202010-02-26 18:56:32 -08006713 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006714 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 SystemClock.uptimeMillis());
6716
6717 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006718 // Make sure we have no pre-ready processes sitting around.
6719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6721 ResolveInfo ri = mContext.getPackageManager()
6722 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006723 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006724 CharSequence errorMsg = null;
6725 if (ri != null) {
6726 ActivityInfo ai = ri.activityInfo;
6727 ApplicationInfo app = ai.applicationInfo;
6728 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6729 mTopAction = Intent.ACTION_FACTORY_TEST;
6730 mTopData = null;
6731 mTopComponent = new ComponentName(app.packageName,
6732 ai.name);
6733 } else {
6734 errorMsg = mContext.getResources().getText(
6735 com.android.internal.R.string.factorytest_not_system);
6736 }
6737 } else {
6738 errorMsg = mContext.getResources().getText(
6739 com.android.internal.R.string.factorytest_no_action);
6740 }
6741 if (errorMsg != null) {
6742 mTopAction = null;
6743 mTopData = null;
6744 mTopComponent = null;
6745 Message msg = Message.obtain();
6746 msg.what = SHOW_FACTORY_ERROR_MSG;
6747 msg.getData().putCharSequence("msg", errorMsg);
6748 mHandler.sendMessage(msg);
6749 }
6750 }
6751 }
6752
6753 retrieveSettings();
6754
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006755 if (goingCallback != null) goingCallback.run();
6756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006757 synchronized (this) {
6758 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6759 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006760 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006761 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 if (apps != null) {
6763 int N = apps.size();
6764 int i;
6765 for (i=0; i<N; i++) {
6766 ApplicationInfo info
6767 = (ApplicationInfo)apps.get(i);
6768 if (info != null &&
6769 !info.packageName.equals("android")) {
6770 addAppLocked(info);
6771 }
6772 }
6773 }
6774 } catch (RemoteException ex) {
6775 // pm is in same process, this will never happen.
6776 }
6777 }
6778
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006779 // Start up initial activity.
6780 mBooting = true;
6781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006782 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006783 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006784 Message msg = Message.obtain();
6785 msg.what = SHOW_UID_ERROR_MSG;
6786 mHandler.sendMessage(msg);
6787 }
6788 } catch (RemoteException e) {
6789 }
6790
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006791 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 }
6793 }
6794
Dan Egnorb7f03672009-12-09 16:22:32 -08006795 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006796 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006797 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006798 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006799 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800 startAppProblemLocked(app);
6801 app.stopFreezingAllLocked();
6802 return handleAppCrashLocked(app);
6803 }
6804
Dan Egnorb7f03672009-12-09 16:22:32 -08006805 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006806 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006807 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006808 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006809 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6810 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 startAppProblemLocked(app);
6812 app.stopFreezingAllLocked();
6813 }
6814
6815 /**
6816 * Generate a process error record, suitable for attachment to a ProcessRecord.
6817 *
6818 * @param app The ProcessRecord in which the error occurred.
6819 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6820 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006821 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 * @param shortMsg Short message describing the crash.
6823 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006824 * @param stackTrace Full crash stack trace, may be null.
6825 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 * @return Returns a fully-formed AppErrorStateInfo record.
6827 */
6828 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006829 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006830 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 report.condition = condition;
6833 report.processName = app.processName;
6834 report.pid = app.pid;
6835 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006836 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837 report.shortMsg = shortMsg;
6838 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006839 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006840
6841 return report;
6842 }
6843
Dan Egnor42471dd2010-01-07 17:25:22 -08006844 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 synchronized (this) {
6846 app.crashing = false;
6847 app.crashingReport = null;
6848 app.notResponding = false;
6849 app.notRespondingReport = null;
6850 if (app.anrDialog == fromDialog) {
6851 app.anrDialog = null;
6852 }
6853 if (app.waitDialog == fromDialog) {
6854 app.waitDialog = null;
6855 }
6856 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006857 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006858 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006859 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6860 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006861 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 }
6864 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006865
Dan Egnorb7f03672009-12-09 16:22:32 -08006866 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006867 long now = SystemClock.uptimeMillis();
6868
6869 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6870 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006871 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006873 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006874 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006875 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006877 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6878 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006879 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006880 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006882 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 }
6884 }
6885 if (!app.persistent) {
6886 // We don't want to start this process again until the user
6887 // explicitly does so... but for persistent process, we really
6888 // need to keep it running. If a persistent process is actually
6889 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006890 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006891 app.info.processName);
6892 mBadProcesses.put(app.info.processName, app.info.uid, now);
6893 app.bad = true;
6894 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6895 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006896 // Don't let services in this process be restarted and potentially
6897 // annoy the user repeatedly. Unless it is persistent, since those
6898 // processes run critical code.
6899 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006900 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 return false;
6902 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006903 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006904 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006905 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006906 if (r.app == app) {
6907 // If the top running activity is from this crashing
6908 // process, then terminate it to avoid getting in a loop.
6909 Slog.w(TAG, " Force finishing activity "
6910 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006911 int index = mMainStack.indexOfTokenLocked(r);
6912 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006913 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006914 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006915 // stopped, to avoid a situation where one will get
6916 // re-start our crashing activity once it gets resumed again.
6917 index--;
6918 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006919 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006920 if (r.state == ActivityState.RESUMED
6921 || r.state == ActivityState.PAUSING
6922 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006923 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006924 Slog.w(TAG, " Force finishing activity "
6925 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006926 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006927 Activity.RESULT_CANCELED, null, "crashed");
6928 }
6929 }
6930 }
6931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 }
6933
6934 // Bump up the crash count of any services currently running in the proc.
6935 if (app.services.size() != 0) {
6936 // Any services running in the application need to be placed
6937 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006938 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006940 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006941 sr.crashCount++;
6942 }
6943 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006944
6945 // If the crashing process is what we consider to be the "home process" and it has been
6946 // replaced by a third-party app, clear the package preferred activities from packages
6947 // with a home activity running in the process to prevent a repeatedly crashing app
6948 // from blocking the user to manually clear the list.
6949 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6950 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6951 Iterator it = mHomeProcess.activities.iterator();
6952 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006953 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006954 if (r.isHomeActivity) {
6955 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6956 try {
6957 ActivityThread.getPackageManager()
6958 .clearPackagePreferredActivities(r.packageName);
6959 } catch (RemoteException c) {
6960 // pm is in same process, this will never happen.
6961 }
6962 }
6963 }
6964 }
6965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6967 return true;
6968 }
6969
6970 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006971 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6972 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 skipCurrentReceiverLocked(app);
6974 }
6975
6976 void skipCurrentReceiverLocked(ProcessRecord app) {
6977 boolean reschedule = false;
6978 BroadcastRecord r = app.curReceiver;
6979 if (r != null) {
6980 // The current broadcast is waiting for this app's receiver
6981 // to be finished. Looks like that's not going to happen, so
6982 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006983 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6985 r.resultExtras, r.resultAbort, true);
6986 reschedule = true;
6987 }
6988 r = mPendingBroadcast;
6989 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006990 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006992 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006993 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6994 r.resultExtras, r.resultAbort, true);
6995 reschedule = true;
6996 }
6997 if (reschedule) {
6998 scheduleBroadcastsLocked();
6999 }
7000 }
7001
Dan Egnor60d87622009-12-16 16:32:58 -08007002 /**
7003 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7004 * The application process will exit immediately after this call returns.
7005 * @param app object of the crashing app, null for the system server
7006 * @param crashInfo describing the exception
7007 */
7008 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007009 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08007010
7011 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7012 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007013 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007014 crashInfo.exceptionClassName,
7015 crashInfo.exceptionMessage,
7016 crashInfo.throwFileName,
7017 crashInfo.throwLineNumber);
7018
Dan Egnor42471dd2010-01-07 17:25:22 -08007019 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007020
7021 crashApplication(r, crashInfo);
7022 }
7023
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007024 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007025 IBinder app,
7026 int violationMask,
7027 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007028 ProcessRecord r = findAppProcess(app, "StrictMode");
7029 if (r == null) {
7030 return;
7031 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007032
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007033 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007034 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007035 boolean logIt = true;
7036 synchronized (mAlreadyLoggedViolatedStacks) {
7037 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7038 logIt = false;
7039 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007040 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007041 // the relative pain numbers, without logging all
7042 // the stack traces repeatedly. We'd want to do
7043 // likewise in the client code, which also does
7044 // dup suppression, before the Binder call.
7045 } else {
7046 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7047 mAlreadyLoggedViolatedStacks.clear();
7048 }
7049 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7050 }
7051 }
7052 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007053 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007054 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007055 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007056
7057 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7058 AppErrorResult result = new AppErrorResult();
7059 synchronized (this) {
7060 final long origId = Binder.clearCallingIdentity();
7061
7062 Message msg = Message.obtain();
7063 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7064 HashMap<String, Object> data = new HashMap<String, Object>();
7065 data.put("result", result);
7066 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007067 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007068 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007069 msg.obj = data;
7070 mHandler.sendMessage(msg);
7071
7072 Binder.restoreCallingIdentity(origId);
7073 }
7074 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007075 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007076 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007077 }
7078
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007079 // Depending on the policy in effect, there could be a bunch of
7080 // these in quick succession so we try to batch these together to
7081 // minimize disk writes, number of dropbox entries, and maximize
7082 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007083 private void logStrictModeViolationToDropBox(
7084 ProcessRecord process,
7085 StrictMode.ViolationInfo info) {
7086 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007087 return;
7088 }
7089 final boolean isSystemApp = process == null ||
7090 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7091 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7092 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7093 final DropBoxManager dbox = (DropBoxManager)
7094 mContext.getSystemService(Context.DROPBOX_SERVICE);
7095
7096 // Exit early if the dropbox isn't configured to accept this report type.
7097 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7098
7099 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007100 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007101 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7102 synchronized (sb) {
7103 bufferWasEmpty = sb.length() == 0;
7104 appendDropBoxProcessHeaders(process, sb);
7105 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7106 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007107 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7108 if (info.violationNumThisLoop != 0) {
7109 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7110 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007111 if (info.numAnimationsRunning != 0) {
7112 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7113 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007114 if (info.broadcastIntentAction != null) {
7115 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7116 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007117 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007118 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007119 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007120 if (info.numInstances != -1) {
7121 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7122 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007123 if (info.tags != null) {
7124 for (String tag : info.tags) {
7125 sb.append("Span-Tag: ").append(tag).append("\n");
7126 }
7127 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007128 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007129 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7130 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007131 }
7132 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007133
7134 // Only buffer up to ~64k. Various logging bits truncate
7135 // things at 128k.
7136 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007137 }
7138
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007139 // Flush immediately if the buffer's grown too large, or this
7140 // is a non-system app. Non-system apps are isolated with a
7141 // different tag & policy and not batched.
7142 //
7143 // Batching is useful during internal testing with
7144 // StrictMode settings turned up high. Without batching,
7145 // thousands of separate files could be created on boot.
7146 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007147 new Thread("Error dump: " + dropboxTag) {
7148 @Override
7149 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007150 String report;
7151 synchronized (sb) {
7152 report = sb.toString();
7153 sb.delete(0, sb.length());
7154 sb.trimToSize();
7155 }
7156 if (report.length() != 0) {
7157 dbox.addText(dropboxTag, report);
7158 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007159 }
7160 }.start();
7161 return;
7162 }
7163
7164 // System app batching:
7165 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007166 // An existing dropbox-writing thread is outstanding, so
7167 // we don't need to start it up. The existing thread will
7168 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007169 return;
7170 }
7171
7172 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7173 // (After this point, we shouldn't access AMS internal data structures.)
7174 new Thread("Error dump: " + dropboxTag) {
7175 @Override
7176 public void run() {
7177 // 5 second sleep to let stacks arrive and be batched together
7178 try {
7179 Thread.sleep(5000); // 5 seconds
7180 } catch (InterruptedException e) {}
7181
7182 String errorReport;
7183 synchronized (mStrictModeBuffer) {
7184 errorReport = mStrictModeBuffer.toString();
7185 if (errorReport.length() == 0) {
7186 return;
7187 }
7188 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7189 mStrictModeBuffer.trimToSize();
7190 }
7191 dbox.addText(dropboxTag, errorReport);
7192 }
7193 }.start();
7194 }
7195
Dan Egnor60d87622009-12-16 16:32:58 -08007196 /**
7197 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7198 * @param app object of the crashing app, null for the system server
7199 * @param tag reported by the caller
7200 * @param crashInfo describing the context of the error
7201 * @return true if the process should exit immediately (WTF is fatal)
7202 */
7203 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007204 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007205 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007206
7207 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7208 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007209 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007210 tag, crashInfo.exceptionMessage);
7211
Dan Egnor42471dd2010-01-07 17:25:22 -08007212 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007213
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007214 if (r != null && r.pid != Process.myPid() &&
7215 Settings.Secure.getInt(mContext.getContentResolver(),
7216 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007217 crashApplication(r, crashInfo);
7218 return true;
7219 } else {
7220 return false;
7221 }
7222 }
7223
7224 /**
7225 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7226 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7227 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007228 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007229 if (app == null) {
7230 return null;
7231 }
7232
7233 synchronized (this) {
7234 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7235 final int NA = apps.size();
7236 for (int ia=0; ia<NA; ia++) {
7237 ProcessRecord p = apps.valueAt(ia);
7238 if (p.thread != null && p.thread.asBinder() == app) {
7239 return p;
7240 }
7241 }
7242 }
7243
Dianne Hackborncb44d962011-03-10 17:02:27 -08007244 Slog.w(TAG, "Can't find mystery application for " + reason
7245 + " from pid=" + Binder.getCallingPid()
7246 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007247 return null;
7248 }
7249 }
7250
7251 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007252 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7253 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007254 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007255 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007256 // Watchdog thread ends up invoking this function (with
7257 // a null ProcessRecord) to add the stack file to dropbox.
7258 // Do not acquire a lock on this (am) in such cases, as it
7259 // could cause a potential deadlock, if and when watchdog
7260 // is invoked due to unavailability of lock on am and it
7261 // would prevent watchdog from killing system_server.
7262 if (process == null) {
7263 sb.append("Process: system_server\n");
7264 return;
7265 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007266 // Note: ProcessRecord 'process' is guarded by the service
7267 // instance. (notably process.pkgList, which could otherwise change
7268 // concurrently during execution of this method)
7269 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007270 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007271 sb.append("Process: system_server\n");
7272 } else {
7273 sb.append("Process: ").append(process.processName).append("\n");
7274 }
Dan Egnora455d192010-03-12 08:52:28 -08007275 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007276 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007277 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7278 for (String pkg : process.pkgList) {
7279 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007280 try {
Dan Egnora455d192010-03-12 08:52:28 -08007281 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7282 if (pi != null) {
7283 sb.append(" v").append(pi.versionCode);
7284 if (pi.versionName != null) {
7285 sb.append(" (").append(pi.versionName).append(")");
7286 }
7287 }
7288 } catch (RemoteException e) {
7289 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007290 }
Dan Egnora455d192010-03-12 08:52:28 -08007291 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007292 }
Dan Egnora455d192010-03-12 08:52:28 -08007293 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007294 }
7295
7296 private static String processClass(ProcessRecord process) {
7297 if (process == null || process.pid == MY_PID) {
7298 return "system_server";
7299 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7300 return "system_app";
7301 } else {
7302 return "data_app";
7303 }
7304 }
7305
7306 /**
7307 * Write a description of an error (crash, WTF, ANR) to the drop box.
7308 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7309 * @param process which caused the error, null means the system server
7310 * @param activity which triggered the error, null if unknown
7311 * @param parent activity related to the error, null if unknown
7312 * @param subject line related to the error, null if absent
7313 * @param report in long form describing the error, null if absent
7314 * @param logFile to include in the report, null if none
7315 * @param crashInfo giving an application stack trace, null if absent
7316 */
7317 public void addErrorToDropBox(String eventType,
7318 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7319 final String report, final File logFile,
7320 final ApplicationErrorReport.CrashInfo crashInfo) {
7321 // NOTE -- this must never acquire the ActivityManagerService lock,
7322 // otherwise the watchdog may be prevented from resetting the system.
7323
7324 final String dropboxTag = processClass(process) + "_" + eventType;
7325 final DropBoxManager dbox = (DropBoxManager)
7326 mContext.getSystemService(Context.DROPBOX_SERVICE);
7327
7328 // Exit early if the dropbox isn't configured to accept this report type.
7329 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7330
7331 final StringBuilder sb = new StringBuilder(1024);
7332 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007333 if (activity != null) {
7334 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7335 }
7336 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7337 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7338 }
7339 if (parent != null && parent != activity) {
7340 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7341 }
7342 if (subject != null) {
7343 sb.append("Subject: ").append(subject).append("\n");
7344 }
7345 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007346 if (Debug.isDebuggerConnected()) {
7347 sb.append("Debugger: Connected\n");
7348 }
Dan Egnora455d192010-03-12 08:52:28 -08007349 sb.append("\n");
7350
7351 // Do the rest in a worker thread to avoid blocking the caller on I/O
7352 // (After this point, we shouldn't access AMS internal data structures.)
7353 Thread worker = new Thread("Error dump: " + dropboxTag) {
7354 @Override
7355 public void run() {
7356 if (report != null) {
7357 sb.append(report);
7358 }
7359 if (logFile != null) {
7360 try {
7361 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7362 } catch (IOException e) {
7363 Slog.e(TAG, "Error reading " + logFile, e);
7364 }
7365 }
7366 if (crashInfo != null && crashInfo.stackTrace != null) {
7367 sb.append(crashInfo.stackTrace);
7368 }
7369
7370 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7371 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7372 if (lines > 0) {
7373 sb.append("\n");
7374
7375 // Merge several logcat streams, and take the last N lines
7376 InputStreamReader input = null;
7377 try {
7378 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7379 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7380 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7381
7382 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7383 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7384 input = new InputStreamReader(logcat.getInputStream());
7385
7386 int num;
7387 char[] buf = new char[8192];
7388 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7389 } catch (IOException e) {
7390 Slog.e(TAG, "Error running logcat", e);
7391 } finally {
7392 if (input != null) try { input.close(); } catch (IOException e) {}
7393 }
7394 }
7395
7396 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007397 }
Dan Egnora455d192010-03-12 08:52:28 -08007398 };
7399
7400 if (process == null || process.pid == MY_PID) {
7401 worker.run(); // We may be about to die -- need to run this synchronously
7402 } else {
7403 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007404 }
7405 }
7406
7407 /**
7408 * Bring up the "unexpected error" dialog box for a crashing app.
7409 * Deal with edge cases (intercepts from instrumented applications,
7410 * ActivityController, error intent receivers, that sort of thing).
7411 * @param r the application crashing
7412 * @param crashInfo describing the failure
7413 */
7414 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007415 long timeMillis = System.currentTimeMillis();
7416 String shortMsg = crashInfo.exceptionClassName;
7417 String longMsg = crashInfo.exceptionMessage;
7418 String stackTrace = crashInfo.stackTrace;
7419 if (shortMsg != null && longMsg != null) {
7420 longMsg = shortMsg + ": " + longMsg;
7421 } else if (shortMsg != null) {
7422 longMsg = shortMsg;
7423 }
7424
Dan Egnor60d87622009-12-16 16:32:58 -08007425 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007426 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007427 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007428 try {
7429 String name = r != null ? r.processName : null;
7430 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007431 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007432 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007433 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 + " at watcher's request");
7435 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007436 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 }
7438 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007439 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007440 }
7441 }
7442
7443 final long origId = Binder.clearCallingIdentity();
7444
7445 // If this process is running instrumentation, finish it.
7446 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007447 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007448 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007449 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7450 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007451 Bundle info = new Bundle();
7452 info.putString("shortMsg", shortMsg);
7453 info.putString("longMsg", longMsg);
7454 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7455 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007456 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 }
7458
Dan Egnor60d87622009-12-16 16:32:58 -08007459 // If we can't identify the process or it's already exceeded its crash quota,
7460 // quit right away without showing a crash dialog.
7461 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007463 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007464 }
7465
7466 Message msg = Message.obtain();
7467 msg.what = SHOW_ERROR_MSG;
7468 HashMap data = new HashMap();
7469 data.put("result", result);
7470 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 msg.obj = data;
7472 mHandler.sendMessage(msg);
7473
7474 Binder.restoreCallingIdentity(origId);
7475 }
7476
7477 int res = result.get();
7478
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007479 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007480 synchronized (this) {
7481 if (r != null) {
7482 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7483 SystemClock.uptimeMillis());
7484 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007485 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007486 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007487 }
7488 }
7489
7490 if (appErrorIntent != null) {
7491 try {
7492 mContext.startActivity(appErrorIntent);
7493 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007494 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007497 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007498
7499 Intent createAppErrorIntentLocked(ProcessRecord r,
7500 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7501 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007502 if (report == null) {
7503 return null;
7504 }
7505 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7506 result.setComponent(r.errorReportReceiver);
7507 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7508 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7509 return result;
7510 }
7511
Dan Egnorb7f03672009-12-09 16:22:32 -08007512 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7513 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007514 if (r.errorReportReceiver == null) {
7515 return null;
7516 }
7517
7518 if (!r.crashing && !r.notResponding) {
7519 return null;
7520 }
7521
Dan Egnorb7f03672009-12-09 16:22:32 -08007522 ApplicationErrorReport report = new ApplicationErrorReport();
7523 report.packageName = r.info.packageName;
7524 report.installerPackageName = r.errorReportReceiver.getPackageName();
7525 report.processName = r.processName;
7526 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007527 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007528
Dan Egnorb7f03672009-12-09 16:22:32 -08007529 if (r.crashing) {
7530 report.type = ApplicationErrorReport.TYPE_CRASH;
7531 report.crashInfo = crashInfo;
7532 } else if (r.notResponding) {
7533 report.type = ApplicationErrorReport.TYPE_ANR;
7534 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007535
Dan Egnorb7f03672009-12-09 16:22:32 -08007536 report.anrInfo.activity = r.notRespondingReport.tag;
7537 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7538 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007539 }
7540
Dan Egnorb7f03672009-12-09 16:22:32 -08007541 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007542 }
7543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007544 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7545 // assume our apps are happy - lazy create the list
7546 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7547
7548 synchronized (this) {
7549
7550 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007551 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7552 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007553 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7554 // This one's in trouble, so we'll generate a report for it
7555 // crashes are higher priority (in case there's a crash *and* an anr)
7556 ActivityManager.ProcessErrorStateInfo report = null;
7557 if (app.crashing) {
7558 report = app.crashingReport;
7559 } else if (app.notResponding) {
7560 report = app.notRespondingReport;
7561 }
7562
7563 if (report != null) {
7564 if (errList == null) {
7565 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7566 }
7567 errList.add(report);
7568 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007569 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007570 " crashing = " + app.crashing +
7571 " notResponding = " + app.notResponding);
7572 }
7573 }
7574 }
7575 }
7576
7577 return errList;
7578 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007579
7580 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7581 if (adj >= ProcessList.EMPTY_APP_ADJ) {
7582 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7583 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7584 if (currApp != null) {
7585 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7586 }
7587 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7588 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7589 if (currApp != null) {
7590 currApp.lru = 0;
7591 }
7592 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7593 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
7594 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7595 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7596 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7597 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7598 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7599 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7600 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7601 } else {
7602 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7603 }
7604 }
7605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007606 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7607 // Lazy instantiation of list
7608 List<ActivityManager.RunningAppProcessInfo> runList = null;
7609 synchronized (this) {
7610 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007611 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7612 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007613 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7614 // Generate process state info for running application
7615 ActivityManager.RunningAppProcessInfo currApp =
7616 new ActivityManager.RunningAppProcessInfo(app.processName,
7617 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007618 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007619 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007620 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007621 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007622 if (app.persistent) {
7623 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007626 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007627 currApp.importanceReasonCode = app.adjTypeCode;
7628 if (app.adjSource instanceof ProcessRecord) {
7629 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007630 currApp.importanceReasonImportance = oomAdjToImportance(
7631 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007632 } else if (app.adjSource instanceof ActivityRecord) {
7633 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007634 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7635 }
7636 if (app.adjTarget instanceof ComponentName) {
7637 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7638 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007639 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007640 // + " lru=" + currApp.lru);
7641 if (runList == null) {
7642 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7643 }
7644 runList.add(currApp);
7645 }
7646 }
7647 }
7648 return runList;
7649 }
7650
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007651 public List<ApplicationInfo> getRunningExternalApplications() {
7652 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7653 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7654 if (runningApps != null && runningApps.size() > 0) {
7655 Set<String> extList = new HashSet<String>();
7656 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7657 if (app.pkgList != null) {
7658 for (String pkg : app.pkgList) {
7659 extList.add(pkg);
7660 }
7661 }
7662 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007663 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007664 for (String pkg : extList) {
7665 try {
7666 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7667 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7668 retList.add(info);
7669 }
7670 } catch (RemoteException e) {
7671 }
7672 }
7673 }
7674 return retList;
7675 }
7676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007677 @Override
7678 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007679 if (checkCallingPermission(android.Manifest.permission.DUMP)
7680 != PackageManager.PERMISSION_GRANTED) {
7681 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7682 + Binder.getCallingPid()
7683 + ", uid=" + Binder.getCallingUid()
7684 + " without permission "
7685 + android.Manifest.permission.DUMP);
7686 return;
7687 }
7688
7689 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007690 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007691
7692 int opti = 0;
7693 while (opti < args.length) {
7694 String opt = args[opti];
7695 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7696 break;
7697 }
7698 opti++;
7699 if ("-a".equals(opt)) {
7700 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007701 } else if ("-c".equals(opt)) {
7702 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007703 } else if ("-h".equals(opt)) {
7704 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007705 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007706 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007707 pw.println(" a[ctivities]: activity stack state");
7708 pw.println(" b[roadcasts]: broadcast state");
7709 pw.println(" i[ntents]: pending intent state");
7710 pw.println(" p[rocesses]: process state");
7711 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007712 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7713 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007714 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007715 pw.println(" all: dump all activities");
7716 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007717 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007718 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7719 pw.println(" a partial substring in a component name, a");
7720 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007721 pw.println(" -a: include all available server state.");
7722 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007723 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007724 } else {
7725 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007726 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007727 }
7728
7729 // Is the caller requesting to dump a particular piece of data?
7730 if (opti < args.length) {
7731 String cmd = args[opti];
7732 opti++;
7733 if ("activities".equals(cmd) || "a".equals(cmd)) {
7734 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007735 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007737 return;
7738 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7739 synchronized (this) {
7740 dumpBroadcastsLocked(fd, pw, args, opti, true);
7741 }
7742 return;
7743 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7744 synchronized (this) {
7745 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7746 }
7747 return;
7748 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7749 synchronized (this) {
7750 dumpProcessesLocked(fd, pw, args, opti, true);
7751 }
7752 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007753 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7754 synchronized (this) {
7755 dumpOomLocked(fd, pw, args, opti, true);
7756 }
7757 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007758 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7759 synchronized (this) {
7760 dumpProvidersLocked(fd, pw, args, opti, true);
7761 }
7762 return;
7763 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007764 String[] newArgs;
7765 String name;
7766 if (opti >= args.length) {
7767 name = null;
7768 newArgs = EMPTY_STRING_ARRAY;
7769 } else {
7770 name = args[opti];
7771 opti++;
7772 newArgs = new String[args.length - opti];
7773 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7774 }
7775 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7776 pw.println("No services match: " + name);
7777 pw.println("Use -h for help.");
7778 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007779 return;
7780 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7781 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007782 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007783 }
7784 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007785 } else {
7786 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007787 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7788 pw.println("Bad activity command, or no activities match: " + cmd);
7789 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007790 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007791 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007792 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007793 }
7794
7795 // No piece of data specified, dump everything.
7796 synchronized (this) {
7797 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007798 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799 if (needSep) {
7800 pw.println(" ");
7801 }
7802 if (dumpAll) {
7803 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007804 }
7805 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7806 if (needSep) {
7807 pw.println(" ");
7808 }
7809 if (dumpAll) {
7810 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007811 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007812 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007813 if (needSep) {
7814 pw.println(" ");
7815 }
7816 if (dumpAll) {
7817 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007818 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007819 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007820 if (needSep) {
7821 pw.println(" ");
7822 }
7823 if (dumpAll) {
7824 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007825 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007826 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007827 if (needSep) {
7828 pw.println(" ");
7829 }
7830 if (dumpAll) {
7831 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007832 }
7833 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7834 }
7835 }
7836
7837 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007838 int opti, boolean dumpAll, boolean dumpClient) {
7839 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7840 pw.println(" Main stack:");
7841 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007842 pw.println(" ");
7843 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007844 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007845 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007846 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007847 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007848 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7849 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007850 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007851 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007852 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007853 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007854 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7855 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007856 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007857 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7858 pw.println(" ");
7859 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007860 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7861 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007862 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007863 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007864 pw.println(" ");
7865 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007866 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7867 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007870 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007871 if (mMainStack.mPausingActivity != null) {
7872 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7873 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007874 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007875 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007876 if (dumpAll) {
7877 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7878 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7879 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007880
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007881 if (mRecentTasks.size() > 0) {
7882 pw.println();
7883 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007884
7885 final int N = mRecentTasks.size();
7886 for (int i=0; i<N; i++) {
7887 TaskRecord tr = mRecentTasks.get(i);
7888 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7889 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007890 if (dumpAll) {
7891 mRecentTasks.get(i).dump(pw, " ");
7892 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007893 }
7894 }
7895
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007896 if (dumpAll) {
7897 pw.println(" ");
7898 pw.println(" mCurTask: " + mCurTask);
7899 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900
7901 return true;
7902 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007903
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007904 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7905 int opti, boolean dumpAll) {
7906 boolean needSep = false;
7907 int numPers = 0;
7908
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007909 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7910
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007912 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7913 final int NA = procs.size();
7914 for (int ia=0; ia<NA; ia++) {
7915 if (!needSep) {
7916 pw.println(" All known processes:");
7917 needSep = true;
7918 }
7919 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007920 pw.print(r.persistent ? " *PERS*" : " *APP*");
7921 pw.print(" UID "); pw.print(procs.keyAt(ia));
7922 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007923 r.dump(pw, " ");
7924 if (r.persistent) {
7925 numPers++;
7926 }
7927 }
7928 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 }
7930
7931 if (mLruProcesses.size() > 0) {
7932 if (needSep) pw.println(" ");
7933 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007934 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007935 dumpProcessOomList(pw, this, mLruProcesses, " ",
7936 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007937 needSep = true;
7938 }
7939
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007940 if (dumpAll) {
7941 synchronized (mPidsSelfLocked) {
7942 if (mPidsSelfLocked.size() > 0) {
7943 if (needSep) pw.println(" ");
7944 needSep = true;
7945 pw.println(" PID mappings:");
7946 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7947 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7948 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007950 }
7951 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007952 }
7953
7954 if (mForegroundProcesses.size() > 0) {
7955 if (needSep) pw.println(" ");
7956 needSep = true;
7957 pw.println(" Foreground Processes:");
7958 for (int i=0; i<mForegroundProcesses.size(); i++) {
7959 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7960 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007961 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007962 }
7963
7964 if (mPersistentStartingProcesses.size() > 0) {
7965 if (needSep) pw.println(" ");
7966 needSep = true;
7967 pw.println(" Persisent processes that are starting:");
7968 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007969 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007971
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007972 if (mRemovedProcesses.size() > 0) {
7973 if (needSep) pw.println(" ");
7974 needSep = true;
7975 pw.println(" Processes that are being removed:");
7976 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007977 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007978 }
7979
7980 if (mProcessesOnHold.size() > 0) {
7981 if (needSep) pw.println(" ");
7982 needSep = true;
7983 pw.println(" Processes that are on old until the system is ready:");
7984 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007985 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987
Dianne Hackborn287952c2010-09-22 22:34:31 -07007988 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007989
7990 if (mProcessCrashTimes.getMap().size() > 0) {
7991 if (needSep) pw.println(" ");
7992 needSep = true;
7993 pw.println(" Time since processes crashed:");
7994 long now = SystemClock.uptimeMillis();
7995 for (Map.Entry<String, SparseArray<Long>> procs
7996 : mProcessCrashTimes.getMap().entrySet()) {
7997 SparseArray<Long> uids = procs.getValue();
7998 final int N = uids.size();
7999 for (int i=0; i<N; i++) {
8000 pw.print(" Process "); pw.print(procs.getKey());
8001 pw.print(" uid "); pw.print(uids.keyAt(i));
8002 pw.print(": last crashed ");
8003 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008004 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008005 }
8006 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008008
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008009 if (mBadProcesses.getMap().size() > 0) {
8010 if (needSep) pw.println(" ");
8011 needSep = true;
8012 pw.println(" Bad processes:");
8013 for (Map.Entry<String, SparseArray<Long>> procs
8014 : mBadProcesses.getMap().entrySet()) {
8015 SparseArray<Long> uids = procs.getValue();
8016 final int N = uids.size();
8017 for (int i=0; i<N; i++) {
8018 pw.print(" Bad process "); pw.print(procs.getKey());
8019 pw.print(" uid "); pw.print(uids.keyAt(i));
8020 pw.print(": crashed at time ");
8021 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008022 }
8023 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008025
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008026 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008027 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008028 if (mHeavyWeightProcess != null) {
8029 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8030 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008031 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008032 if (dumpAll) {
8033 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008034 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008035 pw.println(" mScreenCompatPackages:");
8036 for (Map.Entry<String, Integer> entry
8037 : mCompatModePackages.getPackages().entrySet()) {
8038 String pkg = entry.getKey();
8039 int mode = entry.getValue();
8040 pw.print(" "); pw.print(pkg); pw.print(": ");
8041 pw.print(mode); pw.println();
8042 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008043 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008044 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008045 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8046 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8047 || mOrigWaitForDebugger) {
8048 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8049 + " mDebugTransient=" + mDebugTransient
8050 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8051 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008052 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8053 || mProfileFd != null) {
8054 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8055 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8056 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8057 + mAutoStopProfiler);
8058 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008059 if (mAlwaysFinishActivities || mController != null) {
8060 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8061 + " mController=" + mController);
8062 }
8063 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008065 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008066 + " mProcessesReady=" + mProcessesReady
8067 + " mSystemReady=" + mSystemReady);
8068 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008069 + " mBooted=" + mBooted
8070 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008071 pw.print(" mLastPowerCheckRealtime=");
8072 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8073 pw.println("");
8074 pw.print(" mLastPowerCheckUptime=");
8075 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8076 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008077 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8078 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008079 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008081
8082 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008083 }
8084
Dianne Hackborn287952c2010-09-22 22:34:31 -07008085 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8086 int opti, boolean needSep, boolean dumpAll) {
8087 if (mProcessesToGc.size() > 0) {
8088 if (needSep) pw.println(" ");
8089 needSep = true;
8090 pw.println(" Processes that are waiting to GC:");
8091 long now = SystemClock.uptimeMillis();
8092 for (int i=0; i<mProcessesToGc.size(); i++) {
8093 ProcessRecord proc = mProcessesToGc.get(i);
8094 pw.print(" Process "); pw.println(proc);
8095 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8096 pw.print(", last gced=");
8097 pw.print(now-proc.lastRequestedGc);
8098 pw.print(" ms ago, last lowMem=");
8099 pw.print(now-proc.lastLowMemory);
8100 pw.println(" ms ago");
8101
8102 }
8103 }
8104 return needSep;
8105 }
8106
8107 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8108 int opti, boolean dumpAll) {
8109 boolean needSep = false;
8110
8111 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008112 if (needSep) pw.println(" ");
8113 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008114 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008115 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8116 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8117 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8118 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8119 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8120 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8121 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8122 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8123 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8124 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8125 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008126
8127 if (needSep) pw.println(" ");
8128 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008129 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008130 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008131 "Proc", "PERS", true);
8132 needSep = true;
8133 }
8134
8135 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8136
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008137 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008138 pw.println(" mHomeProcess: " + mHomeProcess);
8139 if (mHeavyWeightProcess != null) {
8140 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8141 }
8142
8143 return true;
8144 }
8145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 /**
8147 * There are three ways to call this:
8148 * - no service specified: dump all the services
8149 * - a flattened component name that matched an existing service was specified as the
8150 * first arg: dump that one service
8151 * - the first arg isn't the flattened component name of an existing service:
8152 * dump all services whose component contains the first arg as a substring
8153 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008154 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8155 int opti, boolean dumpAll) {
8156 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008157
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008158 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008159 synchronized (this) {
8160 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008161 services.add(r1);
8162 }
8163 }
8164 } else {
8165 ComponentName componentName = name != null
8166 ? ComponentName.unflattenFromString(name) : null;
8167 int objectId = 0;
8168 if (componentName == null) {
8169 // Not a '/' separated full component name; maybe an object ID?
8170 try {
8171 objectId = Integer.parseInt(name, 16);
8172 name = null;
8173 componentName = null;
8174 } catch (RuntimeException e) {
8175 }
8176 }
8177
8178 synchronized (this) {
8179 for (ServiceRecord r1 : mServices.values()) {
8180 if (componentName != null) {
8181 if (r1.name.equals(componentName)) {
8182 services.add(r1);
8183 }
8184 } else if (name != null) {
8185 if (r1.name.flattenToString().contains(name)) {
8186 services.add(r1);
8187 }
8188 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008189 services.add(r1);
8190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008191 }
8192 }
8193 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008194
8195 if (services.size() <= 0) {
8196 return false;
8197 }
8198
8199 boolean needSep = false;
8200 for (int i=0; i<services.size(); i++) {
8201 if (needSep) {
8202 pw.println();
8203 }
8204 needSep = true;
8205 dumpService("", fd, pw, services.get(i), args, dumpAll);
8206 }
8207 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208 }
8209
8210 /**
8211 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8212 * there is a thread associated with the service.
8213 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008214 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8215 final ServiceRecord r, String[] args, boolean dumpAll) {
8216 String innerPrefix = prefix + " ";
8217 synchronized (this) {
8218 pw.print(prefix); pw.print("SERVICE ");
8219 pw.print(r.shortName); pw.print(" ");
8220 pw.print(Integer.toHexString(System.identityHashCode(r)));
8221 pw.print(" pid=");
8222 if (r.app != null) pw.println(r.app.pid);
8223 else pw.println("(not running)");
8224 if (dumpAll) {
8225 r.dump(pw, innerPrefix);
8226 }
8227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008228 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008229 pw.print(prefix); pw.println(" Client:");
8230 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008231 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008232 TransferPipe tp = new TransferPipe();
8233 try {
8234 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8235 tp.setBufferPrefix(prefix + " ");
8236 tp.go(fd);
8237 } finally {
8238 tp.kill();
8239 }
8240 } catch (IOException e) {
8241 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008242 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008243 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008244 }
8245 }
8246 }
8247
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008248 static class ItemMatcher {
8249 ArrayList<ComponentName> components;
8250 ArrayList<String> strings;
8251 ArrayList<Integer> objects;
8252 boolean all;
8253
8254 ItemMatcher() {
8255 all = true;
8256 }
8257
8258 void build(String name) {
8259 ComponentName componentName = ComponentName.unflattenFromString(name);
8260 if (componentName != null) {
8261 if (components == null) {
8262 components = new ArrayList<ComponentName>();
8263 }
8264 components.add(componentName);
8265 all = false;
8266 } else {
8267 int objectId = 0;
8268 // Not a '/' separated full component name; maybe an object ID?
8269 try {
8270 objectId = Integer.parseInt(name, 16);
8271 if (objects == null) {
8272 objects = new ArrayList<Integer>();
8273 }
8274 objects.add(objectId);
8275 all = false;
8276 } catch (RuntimeException e) {
8277 // Not an integer; just do string match.
8278 if (strings == null) {
8279 strings = new ArrayList<String>();
8280 }
8281 strings.add(name);
8282 all = false;
8283 }
8284 }
8285 }
8286
8287 int build(String[] args, int opti) {
8288 for (; opti<args.length; opti++) {
8289 String name = args[opti];
8290 if ("--".equals(name)) {
8291 return opti+1;
8292 }
8293 build(name);
8294 }
8295 return opti;
8296 }
8297
8298 boolean match(Object object, ComponentName comp) {
8299 if (all) {
8300 return true;
8301 }
8302 if (components != null) {
8303 for (int i=0; i<components.size(); i++) {
8304 if (components.get(i).equals(comp)) {
8305 return true;
8306 }
8307 }
8308 }
8309 if (objects != null) {
8310 for (int i=0; i<objects.size(); i++) {
8311 if (System.identityHashCode(object) == objects.get(i)) {
8312 return true;
8313 }
8314 }
8315 }
8316 if (strings != null) {
8317 String flat = comp.flattenToString();
8318 for (int i=0; i<strings.size(); i++) {
8319 if (flat.contains(strings.get(i))) {
8320 return true;
8321 }
8322 }
8323 }
8324 return false;
8325 }
8326 }
8327
Dianne Hackborn625ac272010-09-17 18:29:22 -07008328 /**
8329 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008330 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008331 * - the cmd arg isn't the flattened component name of an existing activity:
8332 * dump all activity whose component contains the cmd as a substring
8333 * - A hex number of the ActivityRecord object instance.
8334 */
8335 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8336 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008337 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008338
8339 if ("all".equals(name)) {
8340 synchronized (this) {
8341 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008342 activities.add(r1);
8343 }
8344 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008345 } else if ("top".equals(name)) {
8346 synchronized (this) {
8347 final int N = mMainStack.mHistory.size();
8348 if (N > 0) {
8349 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8350 }
8351 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008352 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008353 ItemMatcher matcher = new ItemMatcher();
8354 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008355
8356 synchronized (this) {
8357 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008358 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008359 activities.add(r1);
8360 }
8361 }
8362 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008363 }
8364
8365 if (activities.size() <= 0) {
8366 return false;
8367 }
8368
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008369 String[] newArgs = new String[args.length - opti];
8370 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8371
Dianne Hackborn30d71892010-12-11 10:37:55 -08008372 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008373 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008374 for (int i=activities.size()-1; i>=0; i--) {
8375 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008376 if (needSep) {
8377 pw.println();
8378 }
8379 needSep = true;
8380 synchronized (this) {
8381 if (lastTask != r.task) {
8382 lastTask = r.task;
8383 pw.print("TASK "); pw.print(lastTask.affinity);
8384 pw.print(" id="); pw.println(lastTask.taskId);
8385 if (dumpAll) {
8386 lastTask.dump(pw, " ");
8387 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008388 }
8389 }
8390 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008391 }
8392 return true;
8393 }
8394
8395 /**
8396 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8397 * there is a thread associated with the activity.
8398 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008399 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008400 final ActivityRecord r, String[] args, boolean dumpAll) {
8401 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008402 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008403 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8404 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8405 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008406 if (r.app != null) pw.println(r.app.pid);
8407 else pw.println("(not running)");
8408 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008409 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008410 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008411 }
8412 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008413 // flush anything that is already in the PrintWriter since the thread is going
8414 // to write to the file descriptor directly
8415 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008416 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008417 TransferPipe tp = new TransferPipe();
8418 try {
8419 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8420 innerPrefix, args);
8421 tp.go(fd);
8422 } finally {
8423 tp.kill();
8424 }
8425 } catch (IOException e) {
8426 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008427 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008428 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008429 }
8430 }
8431 }
8432
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008433 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8434 int opti, boolean dumpAll) {
8435 boolean needSep = false;
8436
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008437 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008438 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008439 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008440 pw.println(" Registered Receivers:");
8441 Iterator it = mRegisteredReceivers.values().iterator();
8442 while (it.hasNext()) {
8443 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008444 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008445 r.dump(pw, " ");
8446 }
8447 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008448
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008449 pw.println();
8450 pw.println(" Receiver Resolver Table:");
8451 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008452 needSep = true;
8453 }
8454
8455 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8456 || mPendingBroadcast != null) {
8457 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008458 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008459 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008460 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008461 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8462 pw.println(" Broadcast #" + i + ":");
8463 mParallelBroadcasts.get(i).dump(pw, " ");
8464 }
8465 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008466 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008467 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008468 }
8469 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8470 pw.println(" Serialized Broadcast #" + i + ":");
8471 mOrderedBroadcasts.get(i).dump(pw, " ");
8472 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008473 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008474 pw.println(" Pending broadcast:");
8475 if (mPendingBroadcast != null) {
8476 mPendingBroadcast.dump(pw, " ");
8477 } else {
8478 pw.println(" (null)");
8479 }
8480 needSep = true;
8481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008483 if (needSep) {
8484 pw.println();
8485 }
8486 pw.println(" Historical broadcasts:");
8487 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8488 BroadcastRecord r = mBroadcastHistory[i];
8489 if (r == null) {
8490 break;
8491 }
8492 if (dumpAll) {
8493 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8494 r.dump(pw, " ");
8495 } else {
8496 if (i >= 50) {
8497 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008498 break;
8499 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008500 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008501 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008502 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008503 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008504
8505 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008506 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008507 pw.println(" Sticky broadcasts:");
8508 StringBuilder sb = new StringBuilder(128);
8509 for (Map.Entry<String, ArrayList<Intent>> ent
8510 : mStickyBroadcasts.entrySet()) {
8511 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008512 if (dumpAll) {
8513 pw.println(":");
8514 ArrayList<Intent> intents = ent.getValue();
8515 final int N = intents.size();
8516 for (int i=0; i<N; i++) {
8517 sb.setLength(0);
8518 sb.append(" Intent: ");
8519 intents.get(i).toShortString(sb, true, false);
8520 pw.println(sb.toString());
8521 Bundle bundle = intents.get(i).getExtras();
8522 if (bundle != null) {
8523 pw.print(" ");
8524 pw.println(bundle.toString());
8525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008526 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008527 } else {
8528 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008529 }
8530 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008531 needSep = true;
8532 }
8533
8534 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008535 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008536 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008537 pw.println(" mHandler:");
8538 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008539 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008540 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008541
8542 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008543 }
8544
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008545 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008546 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008547 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008549 ItemMatcher matcher = new ItemMatcher();
8550 matcher.build(args, opti);
8551
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008552 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8553 if (mServices.size() > 0) {
8554 pw.println(" Active services:");
8555 long nowReal = SystemClock.elapsedRealtime();
8556 Iterator<ServiceRecord> it = mServices.values().iterator();
8557 needSep = false;
8558 while (it.hasNext()) {
8559 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008560 if (!matcher.match(r, r.name)) {
8561 continue;
8562 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008563 if (needSep) {
8564 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008565 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008566 pw.print(" * "); pw.println(r);
8567 if (dumpAll) {
8568 r.dump(pw, " ");
8569 needSep = true;
8570 } else {
8571 pw.print(" app="); pw.println(r.app);
8572 pw.print(" created=");
8573 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8574 pw.print(" started="); pw.print(r.startRequested);
8575 pw.print(" connections="); pw.println(r.connections.size());
8576 }
8577 if (dumpClient && r.app != null && r.app.thread != null) {
8578 pw.println(" Client:");
8579 pw.flush();
8580 try {
8581 TransferPipe tp = new TransferPipe();
8582 try {
8583 r.app.thread.dumpService(
8584 tp.getWriteFd().getFileDescriptor(), r, args);
8585 tp.setBufferPrefix(" ");
8586 // Short timeout, since blocking here can
8587 // deadlock with the application.
8588 tp.go(fd, 2000);
8589 } finally {
8590 tp.kill();
8591 }
8592 } catch (IOException e) {
8593 pw.println(" Failure while dumping the service: " + e);
8594 } catch (RemoteException e) {
8595 pw.println(" Got a RemoteException while dumping the service");
8596 }
8597 needSep = true;
8598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008599 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008600 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008602
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008603 if (mPendingServices.size() > 0) {
8604 if (needSep) pw.println(" ");
8605 pw.println(" Pending services:");
8606 for (int i=0; i<mPendingServices.size(); i++) {
8607 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008608 if (!matcher.match(r, r.name)) {
8609 continue;
8610 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008611 pw.print(" * Pending "); pw.println(r);
8612 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008613 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008614 needSep = true;
8615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008616
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008617 if (mRestartingServices.size() > 0) {
8618 if (needSep) pw.println(" ");
8619 pw.println(" Restarting services:");
8620 for (int i=0; i<mRestartingServices.size(); i++) {
8621 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008622 if (!matcher.match(r, r.name)) {
8623 continue;
8624 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008625 pw.print(" * Restarting "); pw.println(r);
8626 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008627 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008628 needSep = true;
8629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008630
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008631 if (mStoppingServices.size() > 0) {
8632 if (needSep) pw.println(" ");
8633 pw.println(" Stopping services:");
8634 for (int i=0; i<mStoppingServices.size(); i++) {
8635 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008636 if (!matcher.match(r, r.name)) {
8637 continue;
8638 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008639 pw.print(" * Stopping "); pw.println(r);
8640 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008642 needSep = true;
8643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008645 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008646 if (mServiceConnections.size() > 0) {
8647 if (needSep) pw.println(" ");
8648 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008649 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008650 = mServiceConnections.values().iterator();
8651 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008652 ArrayList<ConnectionRecord> r = it.next();
8653 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008654 ConnectionRecord cr = r.get(i);
8655 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8656 continue;
8657 }
8658 pw.print(" * "); pw.println(cr);
8659 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008661 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008662 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008663 }
8664 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008665
8666 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667 }
8668
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008669 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8670 int opti, boolean dumpAll) {
8671 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008672
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008673 ItemMatcher matcher = new ItemMatcher();
8674 matcher.build(args, opti);
8675
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008676 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8677 if (mProvidersByClass.size() > 0) {
8678 if (needSep) pw.println(" ");
8679 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008680 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008681 = mProvidersByClass.entrySet().iterator();
8682 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008683 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008684 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008685 ComponentName comp = e.getKey();
8686 String cls = comp.getClassName();
8687 int end = cls.lastIndexOf('.');
8688 if (end > 0 && end < (cls.length()-2)) {
8689 cls = cls.substring(end+1);
8690 }
8691 if (!matcher.match(r, comp)) {
8692 continue;
8693 }
8694 pw.print(" * "); pw.print(cls); pw.print(" (");
8695 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008696 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008697 pw.println();
8698 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008699 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008700 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008701 if (r.app != null) {
8702 pw.println(":");
8703 pw.print(" "); pw.println(r.app);
8704 } else {
8705 pw.println();
8706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008709 needSep = true;
8710 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008711
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008712 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008713 if (mProvidersByName.size() > 0) {
8714 pw.println(" ");
8715 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008716 Iterator<Map.Entry<String, ContentProviderRecord>> it
8717 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008718 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008719 Map.Entry<String, ContentProviderRecord> e = it.next();
8720 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008721 if (!matcher.match(r, r.name)) {
8722 continue;
8723 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008724 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8725 pw.println(r);
8726 }
8727 needSep = true;
8728 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008730
8731 if (mLaunchingProviders.size() > 0) {
8732 if (needSep) pw.println(" ");
8733 pw.println(" Launching content providers:");
8734 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8735 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8736 pw.println(mLaunchingProviders.get(i));
8737 }
8738 needSep = true;
8739 }
8740
8741 if (mGrantedUriPermissions.size() > 0) {
8742 pw.println();
8743 pw.println("Granted Uri Permissions:");
8744 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8745 int uid = mGrantedUriPermissions.keyAt(i);
8746 HashMap<Uri, UriPermission> perms
8747 = mGrantedUriPermissions.valueAt(i);
8748 pw.print(" * UID "); pw.print(uid);
8749 pw.println(" holds:");
8750 for (UriPermission perm : perms.values()) {
8751 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008752 if (dumpAll) {
8753 perm.dump(pw, " ");
8754 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008755 }
8756 }
8757 needSep = true;
8758 }
8759
8760 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 }
8762
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008763 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8764 int opti, boolean dumpAll) {
8765 boolean needSep = false;
8766
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008767 if (this.mIntentSenderRecords.size() > 0) {
8768 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8769 Iterator<WeakReference<PendingIntentRecord>> it
8770 = mIntentSenderRecords.values().iterator();
8771 while (it.hasNext()) {
8772 WeakReference<PendingIntentRecord> ref = it.next();
8773 PendingIntentRecord rec = ref != null ? ref.get(): null;
8774 needSep = true;
8775 if (rec != null) {
8776 pw.print(" * "); pw.println(rec);
8777 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008778 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008779 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008780 } else {
8781 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008782 }
8783 }
8784 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008785
8786 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008787 }
8788
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008789 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8790 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008791 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008792 boolean needNL = false;
8793 final String innerPrefix = prefix + " ";
8794 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008795 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008796 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008797 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008798 if (needNL) {
8799 pw.println(" ");
8800 needNL = false;
8801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008802 if (lastTask != r.task) {
8803 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008804 pw.print(prefix);
8805 pw.print(full ? "* " : " ");
8806 pw.println(lastTask);
8807 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008808 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008809 } else if (complete) {
8810 // Complete + brief == give a summary. Isn't that obvious?!?
8811 if (lastTask.intent != null) {
8812 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8813 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008816 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8817 pw.print(" #"); pw.print(i); pw.print(": ");
8818 pw.println(r);
8819 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008820 r.dump(pw, innerPrefix);
8821 } else if (complete) {
8822 // Complete + brief == give a summary. Isn't that obvious?!?
8823 pw.print(innerPrefix); pw.println(r.intent);
8824 if (r.app != null) {
8825 pw.print(innerPrefix); pw.println(r.app);
8826 }
8827 }
8828 if (client && r.app != null && r.app.thread != null) {
8829 // flush anything that is already in the PrintWriter since the thread is going
8830 // to write to the file descriptor directly
8831 pw.flush();
8832 try {
8833 TransferPipe tp = new TransferPipe();
8834 try {
8835 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8836 innerPrefix, args);
8837 // Short timeout, since blocking here can
8838 // deadlock with the application.
8839 tp.go(fd, 2000);
8840 } finally {
8841 tp.kill();
8842 }
8843 } catch (IOException e) {
8844 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8845 } catch (RemoteException e) {
8846 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8847 }
8848 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008850 }
8851 }
8852
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008853 private static String buildOomTag(String prefix, String space, int val, int base) {
8854 if (val == base) {
8855 if (space == null) return prefix;
8856 return prefix + " ";
8857 }
8858 return prefix + "+" + Integer.toString(val-base);
8859 }
8860
8861 private static final int dumpProcessList(PrintWriter pw,
8862 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008863 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008864 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008865 final int N = list.size()-1;
8866 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008867 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008868 pw.println(String.format("%s%s #%2d: %s",
8869 prefix, (r.persistent ? persistentLabel : normalLabel),
8870 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008871 if (r.persistent) {
8872 numPers++;
8873 }
8874 }
8875 return numPers;
8876 }
8877
Dianne Hackborn287952c2010-09-22 22:34:31 -07008878 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008879 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008880 String prefix, String normalLabel, String persistentLabel,
8881 boolean inclDetails) {
8882
Dianne Hackborn905577f2011-09-07 18:31:28 -07008883 ArrayList<Pair<ProcessRecord, Integer>> list
8884 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8885 for (int i=0; i<origList.size(); i++) {
8886 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8887 }
8888
8889 Comparator<Pair<ProcessRecord, Integer>> comparator
8890 = new Comparator<Pair<ProcessRecord, Integer>>() {
8891 @Override
8892 public int compare(Pair<ProcessRecord, Integer> object1,
8893 Pair<ProcessRecord, Integer> object2) {
8894 if (object1.first.setAdj != object2.first.setAdj) {
8895 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8896 }
8897 if (object1.second.intValue() != object2.second.intValue()) {
8898 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8899 }
8900 return 0;
8901 }
8902 };
8903
8904 Collections.sort(list, comparator);
8905
Dianne Hackborn287952c2010-09-22 22:34:31 -07008906 final long curRealtime = SystemClock.elapsedRealtime();
8907 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8908 final long curUptime = SystemClock.uptimeMillis();
8909 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8910
8911 final int N = list.size()-1;
8912 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008913 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008914 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008915 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8916 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8917 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8918 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8919 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8920 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8921 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8922 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8923 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8924 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8925 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8926 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8927 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8928 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8929 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8930 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8931 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8932 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8933 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8934 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8935 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8936 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008937 } else {
8938 oomAdj = Integer.toString(r.setAdj);
8939 }
8940 String schedGroup;
8941 switch (r.setSchedGroup) {
8942 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8943 schedGroup = "B";
8944 break;
8945 case Process.THREAD_GROUP_DEFAULT:
8946 schedGroup = "F";
8947 break;
8948 default:
8949 schedGroup = Integer.toString(r.setSchedGroup);
8950 break;
8951 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008952 String foreground;
8953 if (r.foregroundActivities) {
8954 foreground = "A";
8955 } else if (r.foregroundServices) {
8956 foreground = "S";
8957 } else {
8958 foreground = " ";
8959 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008960 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008961 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07008962 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008963 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008964 if (r.adjSource != null || r.adjTarget != null) {
8965 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008966 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008967 if (r.adjTarget instanceof ComponentName) {
8968 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8969 } else if (r.adjTarget != null) {
8970 pw.print(r.adjTarget.toString());
8971 } else {
8972 pw.print("{null}");
8973 }
8974 pw.print("<=");
8975 if (r.adjSource instanceof ProcessRecord) {
8976 pw.print("Proc{");
8977 pw.print(((ProcessRecord)r.adjSource).toShortString());
8978 pw.println("}");
8979 } else if (r.adjSource != null) {
8980 pw.println(r.adjSource.toString());
8981 } else {
8982 pw.println("{null}");
8983 }
8984 }
8985 if (inclDetails) {
8986 pw.print(prefix);
8987 pw.print(" ");
8988 pw.print("oom: max="); pw.print(r.maxAdj);
8989 pw.print(" hidden="); pw.print(r.hiddenAdj);
8990 pw.print(" curRaw="); pw.print(r.curRawAdj);
8991 pw.print(" setRaw="); pw.print(r.setRawAdj);
8992 pw.print(" cur="); pw.print(r.curAdj);
8993 pw.print(" set="); pw.println(r.setAdj);
8994 pw.print(prefix);
8995 pw.print(" ");
8996 pw.print("keeping="); pw.print(r.keeping);
8997 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008998 pw.print(" empty="); pw.print(r.empty);
8999 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009000
9001 if (!r.keeping) {
9002 if (r.lastWakeTime != 0) {
9003 long wtime;
9004 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9005 synchronized (stats) {
9006 wtime = stats.getProcessWakeTime(r.info.uid,
9007 r.pid, curRealtime);
9008 }
9009 long timeUsed = wtime - r.lastWakeTime;
9010 pw.print(prefix);
9011 pw.print(" ");
9012 pw.print("keep awake over ");
9013 TimeUtils.formatDuration(realtimeSince, pw);
9014 pw.print(" used ");
9015 TimeUtils.formatDuration(timeUsed, pw);
9016 pw.print(" (");
9017 pw.print((timeUsed*100)/realtimeSince);
9018 pw.println("%)");
9019 }
9020 if (r.lastCpuTime != 0) {
9021 long timeUsed = r.curCpuTime - r.lastCpuTime;
9022 pw.print(prefix);
9023 pw.print(" ");
9024 pw.print("run cpu over ");
9025 TimeUtils.formatDuration(uptimeSince, pw);
9026 pw.print(" used ");
9027 TimeUtils.formatDuration(timeUsed, pw);
9028 pw.print(" (");
9029 pw.print((timeUsed*100)/uptimeSince);
9030 pw.println("%)");
9031 }
9032 }
9033 }
9034 }
9035 }
9036
Dianne Hackbornb437e092011-08-05 17:50:29 -07009037 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009038 ArrayList<ProcessRecord> procs;
9039 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009040 if (args != null && args.length > start
9041 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009042 procs = new ArrayList<ProcessRecord>();
9043 int pid = -1;
9044 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009045 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009046 } catch (NumberFormatException e) {
9047
9048 }
9049 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9050 ProcessRecord proc = mLruProcesses.get(i);
9051 if (proc.pid == pid) {
9052 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009053 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009054 procs.add(proc);
9055 }
9056 }
9057 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009058 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009059 return null;
9060 }
9061 } else {
9062 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9063 }
9064 }
9065 return procs;
9066 }
9067
9068 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9069 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009070 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009071 if (procs == null) {
9072 return;
9073 }
9074
9075 long uptime = SystemClock.uptimeMillis();
9076 long realtime = SystemClock.elapsedRealtime();
9077 pw.println("Applications Graphics Acceleration Info:");
9078 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9079
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009080 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9081 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009082 if (r.thread != null) {
9083 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9084 pw.flush();
9085 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009086 TransferPipe tp = new TransferPipe();
9087 try {
9088 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9089 tp.go(fd);
9090 } finally {
9091 tp.kill();
9092 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009093 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009094 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009095 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009096 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009097 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009098 pw.flush();
9099 }
9100 }
9101 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009102 }
9103
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009104 final static class MemItem {
9105 final String label;
9106 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009107 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009108
9109 public MemItem(String _label, long _pss) {
9110 label = _label;
9111 pss = _pss;
9112 }
9113 }
9114
Dianne Hackbornb437e092011-08-05 17:50:29 -07009115 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9116 boolean sort) {
9117 if (sort) {
9118 Collections.sort(items, new Comparator<MemItem>() {
9119 @Override
9120 public int compare(MemItem lhs, MemItem rhs) {
9121 if (lhs.pss < rhs.pss) {
9122 return 1;
9123 } else if (lhs.pss > rhs.pss) {
9124 return -1;
9125 }
9126 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009127 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009128 });
9129 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009130
9131 for (int i=0; i<items.size(); i++) {
9132 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009133 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9134 if (mi.subitems != null) {
9135 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9136 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009137 }
9138 }
9139
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009140 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9141 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009142 boolean dumpAll = false;
9143
9144 int opti = 0;
9145 while (opti < args.length) {
9146 String opt = args[opti];
9147 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9148 break;
9149 }
9150 opti++;
9151 if ("-a".equals(opt)) {
9152 dumpAll = true;
9153 } else if ("-h".equals(opt)) {
9154 pw.println("meminfo dump options: [-a] [process]");
9155 pw.println(" -a: include all available information for each process.");
9156 pw.println("If [process] is specified it can be the name or ");
9157 pw.println("pid of a specific process to dump.");
9158 return;
9159 } else {
9160 pw.println("Unknown argument: " + opt + "; use -h for help");
9161 }
9162 }
9163
9164 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009165 if (procs == null) {
9166 return;
9167 }
9168
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009169 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009170 long uptime = SystemClock.uptimeMillis();
9171 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009172
9173 if (procs.size() == 1 || isCheckinRequest) {
9174 dumpAll = true;
9175 }
9176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177 if (isCheckinRequest) {
9178 // short checkin version
9179 pw.println(uptime + "," + realtime);
9180 pw.flush();
9181 } else {
9182 pw.println("Applications Memory Usage (kB):");
9183 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9184 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009185
Dianne Hackbornb437e092011-08-05 17:50:29 -07009186 String[] innerArgs = new String[args.length-opti];
9187 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9188
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009189 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9190 long nativePss=0, dalvikPss=0, otherPss=0;
9191 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9192
Dianne Hackbornb437e092011-08-05 17:50:29 -07009193 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009194 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9195 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9196 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009197 };
9198 final String[] oomLabel = new String[] {
9199 "System", "Persistent", "Foreground",
9200 "Visible", "Perceptible", "Heavy Weight",
9201 "Backup", "Services", "Home", "Background"
9202 };
9203 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009204 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009205
9206 long totalPss = 0;
9207
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009208 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9209 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009210 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009211 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009212 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9213 pw.flush();
9214 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009215 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009216 if (dumpAll) {
9217 try {
9218 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9219 } catch (RemoteException e) {
9220 if (!isCheckinRequest) {
9221 pw.println("Got RemoteException!");
9222 pw.flush();
9223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009224 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009225 } else {
9226 mi = new Debug.MemoryInfo();
9227 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009228 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009229
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009230 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009231 long myTotalPss = mi.getTotalPss();
9232 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009233 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9234 myTotalPss);
9235 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009236
9237 nativePss += mi.nativePss;
9238 dalvikPss += mi.dalvikPss;
9239 otherPss += mi.otherPss;
9240 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9241 long mem = mi.getOtherPss(j);
9242 miscPss[j] += mem;
9243 otherPss -= mem;
9244 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009245
9246 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9247 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9248 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009249 if (oomProcs[oomIndex] == null) {
9250 oomProcs[oomIndex] = new ArrayList<MemItem>();
9251 }
9252 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009253 break;
9254 }
9255 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009257 }
9258 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009259
9260 if (!isCheckinRequest && procs.size() > 1) {
9261 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9262
9263 catMems.add(new MemItem("Native", nativePss));
9264 catMems.add(new MemItem("Dalvik", dalvikPss));
9265 catMems.add(new MemItem("Unknown", otherPss));
9266 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9267 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9268 }
9269
Dianne Hackbornb437e092011-08-05 17:50:29 -07009270 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9271 for (int j=0; j<oomPss.length; j++) {
9272 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009273 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9274 item.subitems = oomProcs[j];
9275 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009276 }
9277 }
9278
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009279 pw.println();
9280 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009281 dumpMemItems(pw, " ", procMems, true);
9282 pw.println();
9283 pw.println("Total PSS by OOM adjustment:");
9284 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009285 pw.println();
9286 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009287 dumpMemItems(pw, " ", catMems, true);
9288 pw.println();
9289 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009291 }
9292
9293 /**
9294 * Searches array of arguments for the specified string
9295 * @param args array of argument strings
9296 * @param value value to search for
9297 * @return true if the value is contained in the array
9298 */
9299 private static boolean scanArgs(String[] args, String value) {
9300 if (args != null) {
9301 for (String arg : args) {
9302 if (value.equals(arg)) {
9303 return true;
9304 }
9305 }
9306 }
9307 return false;
9308 }
9309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009310 private final void killServicesLocked(ProcessRecord app,
9311 boolean allowRestart) {
9312 // Report disconnected services.
9313 if (false) {
9314 // XXX we are letting the client link to the service for
9315 // death notifications.
9316 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009317 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009319 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009320 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009321 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009322 = r.connections.values().iterator();
9323 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009324 ArrayList<ConnectionRecord> cl = jt.next();
9325 for (int i=0; i<cl.size(); i++) {
9326 ConnectionRecord c = cl.get(i);
9327 if (c.binding.client != app) {
9328 try {
9329 //c.conn.connected(r.className, null);
9330 } catch (Exception e) {
9331 // todo: this should be asynchronous!
9332 Slog.w(TAG, "Exception thrown disconnected servce "
9333 + r.shortName
9334 + " from app " + app.processName, e);
9335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009336 }
9337 }
9338 }
9339 }
9340 }
9341 }
9342 }
9343
9344 // Clean up any connections this application has to other services.
9345 if (app.connections.size() > 0) {
9346 Iterator<ConnectionRecord> it = app.connections.iterator();
9347 while (it.hasNext()) {
9348 ConnectionRecord r = it.next();
9349 removeConnectionLocked(r, app, null);
9350 }
9351 }
9352 app.connections.clear();
9353
9354 if (app.services.size() != 0) {
9355 // Any services running in the application need to be placed
9356 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009357 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009358 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009359 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009360 synchronized (sr.stats.getBatteryStats()) {
9361 sr.stats.stopLaunchedLocked();
9362 }
9363 sr.app = null;
9364 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009365 if (mStoppingServices.remove(sr)) {
9366 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9367 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009368
9369 boolean hasClients = sr.bindings.size() > 0;
9370 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 Iterator<IntentBindRecord> bindings
9372 = sr.bindings.values().iterator();
9373 while (bindings.hasNext()) {
9374 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009375 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 + ": shouldUnbind=" + b.hasBound);
9377 b.binder = null;
9378 b.requested = b.received = b.hasBound = false;
9379 }
9380 }
9381
Dianne Hackborn070783f2010-12-29 16:46:28 -08009382 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9383 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009384 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009385 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009386 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009387 sr.crashCount, sr.shortName, app.pid);
9388 bringDownServiceLocked(sr, true);
9389 } else if (!allowRestart) {
9390 bringDownServiceLocked(sr, true);
9391 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009392 boolean canceled = scheduleServiceRestartLocked(sr, true);
9393
9394 // Should the service remain running? Note that in the
9395 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009396 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009397 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9398 if (sr.pendingStarts.size() == 0) {
9399 sr.startRequested = false;
9400 if (!hasClients) {
9401 // Whoops, no reason to restart!
9402 bringDownServiceLocked(sr, true);
9403 }
9404 }
9405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009406 }
9407 }
9408
9409 if (!allowRestart) {
9410 app.services.clear();
9411 }
9412 }
9413
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009414 // Make sure we have no more records on the stopping list.
9415 int i = mStoppingServices.size();
9416 while (i > 0) {
9417 i--;
9418 ServiceRecord sr = mStoppingServices.get(i);
9419 if (sr.app == app) {
9420 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009421 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009422 }
9423 }
9424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 app.executingServices.clear();
9426 }
9427
9428 private final void removeDyingProviderLocked(ProcessRecord proc,
9429 ContentProviderRecord cpr) {
9430 synchronized (cpr) {
9431 cpr.launchingApp = null;
9432 cpr.notifyAll();
9433 }
9434
9435 mProvidersByClass.remove(cpr.info.name);
9436 String names[] = cpr.info.authority.split(";");
9437 for (int j = 0; j < names.length; j++) {
9438 mProvidersByName.remove(names[j]);
9439 }
9440
9441 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9442 while (cit.hasNext()) {
9443 ProcessRecord capp = cit.next();
9444 if (!capp.persistent && capp.thread != null
9445 && capp.pid != 0
9446 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009447 Slog.i(TAG, "Kill " + capp.processName
9448 + " (pid " + capp.pid + "): provider " + cpr.info.name
9449 + " in dying process " + proc.processName);
9450 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9451 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009452 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009453 }
9454 }
9455
9456 mLaunchingProviders.remove(cpr);
9457 }
9458
9459 /**
9460 * Main code for cleaning up a process when it has gone away. This is
9461 * called both as a result of the process dying, or directly when stopping
9462 * a process when running in single process mode.
9463 */
9464 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009465 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009466 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009467 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009468 }
9469
Dianne Hackborn36124872009-10-08 16:22:03 -07009470 mProcessesToGc.remove(app);
9471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009472 // Dismiss any open dialogs.
9473 if (app.crashDialog != null) {
9474 app.crashDialog.dismiss();
9475 app.crashDialog = null;
9476 }
9477 if (app.anrDialog != null) {
9478 app.anrDialog.dismiss();
9479 app.anrDialog = null;
9480 }
9481 if (app.waitDialog != null) {
9482 app.waitDialog.dismiss();
9483 app.waitDialog = null;
9484 }
9485
9486 app.crashing = false;
9487 app.notResponding = false;
9488
9489 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009490 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 app.thread = null;
9492 app.forcingToForeground = null;
9493 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009494 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009495 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009496 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009498 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009499
9500 boolean restart = false;
9501
9502 int NL = mLaunchingProviders.size();
9503
9504 // Remove published content providers.
9505 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009506 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009507 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009508 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 cpr.provider = null;
9510 cpr.app = null;
9511
9512 // See if someone is waiting for this provider... in which
9513 // case we don't remove it, but just let it restart.
9514 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009515 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009516 for (; i<NL; i++) {
9517 if (mLaunchingProviders.get(i) == cpr) {
9518 restart = true;
9519 break;
9520 }
9521 }
9522 } else {
9523 i = NL;
9524 }
9525
9526 if (i >= NL) {
9527 removeDyingProviderLocked(app, cpr);
9528 NL = mLaunchingProviders.size();
9529 }
9530 }
9531 app.pubProviders.clear();
9532 }
9533
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009534 // Take care of any launching providers waiting for this process.
9535 if (checkAppInLaunchingProvidersLocked(app, false)) {
9536 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009537 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009539 // Unregister from connected content providers.
9540 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009541 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009542 while (it.hasNext()) {
9543 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9544 cpr.clients.remove(app);
9545 }
9546 app.conProviders.clear();
9547 }
9548
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009549 // At this point there may be remaining entries in mLaunchingProviders
9550 // where we were the only one waiting, so they are no longer of use.
9551 // Look for these and clean up if found.
9552 // XXX Commented out for now. Trying to figure out a way to reproduce
9553 // the actual situation to identify what is actually going on.
9554 if (false) {
9555 for (int i=0; i<NL; i++) {
9556 ContentProviderRecord cpr = (ContentProviderRecord)
9557 mLaunchingProviders.get(i);
9558 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9559 synchronized (cpr) {
9560 cpr.launchingApp = null;
9561 cpr.notifyAll();
9562 }
9563 }
9564 }
9565 }
9566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 skipCurrentReceiverLocked(app);
9568
9569 // Unregister any receivers.
9570 if (app.receivers.size() > 0) {
9571 Iterator<ReceiverList> it = app.receivers.iterator();
9572 while (it.hasNext()) {
9573 removeReceiverLocked(it.next());
9574 }
9575 app.receivers.clear();
9576 }
9577
Christopher Tate181fafa2009-05-14 11:12:14 -07009578 // If the app is undergoing backup, tell the backup manager about it
9579 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009580 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009581 try {
9582 IBackupManager bm = IBackupManager.Stub.asInterface(
9583 ServiceManager.getService(Context.BACKUP_SERVICE));
9584 bm.agentDisconnected(app.info.packageName);
9585 } catch (RemoteException e) {
9586 // can't happen; backup manager is local
9587 }
9588 }
9589
Jeff Sharkey287bd832011-05-28 19:36:26 -07009590 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009592 // If the caller is restarting this app, then leave it in its
9593 // current lists and let the caller take care of it.
9594 if (restarting) {
9595 return;
9596 }
9597
9598 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009599 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009600 "Removing non-persistent process during cleanup: " + app);
9601 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009602 if (mHeavyWeightProcess == app) {
9603 mHeavyWeightProcess = null;
9604 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606 } else if (!app.removed) {
9607 // This app is persistent, so we need to keep its record around.
9608 // If it is not already on the pending app list, add it there
9609 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009610 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9611 mPersistentStartingProcesses.add(app);
9612 restart = true;
9613 }
9614 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009615 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9616 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009617 mProcessesOnHold.remove(app);
9618
The Android Open Source Project4df24232009-03-05 14:34:35 -08009619 if (app == mHomeProcess) {
9620 mHomeProcess = null;
9621 }
9622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009623 if (restart) {
9624 // We have components that still need to be running in the
9625 // process, so re-launch it.
9626 mProcessNames.put(app.processName, app.info.uid, app);
9627 startProcessLocked(app, "restart", app.processName);
9628 } else if (app.pid > 0 && app.pid != MY_PID) {
9629 // Goodbye!
9630 synchronized (mPidsSelfLocked) {
9631 mPidsSelfLocked.remove(app.pid);
9632 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9633 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009634 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009635 }
9636 }
9637
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009638 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9639 // Look through the content providers we are waiting to have launched,
9640 // and if any run in this process then either schedule a restart of
9641 // the process or kill the client waiting for it if this process has
9642 // gone bad.
9643 int NL = mLaunchingProviders.size();
9644 boolean restart = false;
9645 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009646 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009647 if (cpr.launchingApp == app) {
9648 if (!alwaysBad && !app.bad) {
9649 restart = true;
9650 } else {
9651 removeDyingProviderLocked(app, cpr);
9652 NL = mLaunchingProviders.size();
9653 }
9654 }
9655 }
9656 return restart;
9657 }
9658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009659 // =========================================================
9660 // SERVICES
9661 // =========================================================
9662
9663 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9664 ActivityManager.RunningServiceInfo info =
9665 new ActivityManager.RunningServiceInfo();
9666 info.service = r.name;
9667 if (r.app != null) {
9668 info.pid = r.app.pid;
9669 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009670 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009671 info.process = r.processName;
9672 info.foreground = r.isForeground;
9673 info.activeSince = r.createTime;
9674 info.started = r.startRequested;
9675 info.clientCount = r.connections.size();
9676 info.crashCount = r.crashCount;
9677 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009678 if (r.isForeground) {
9679 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9680 }
9681 if (r.startRequested) {
9682 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9683 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009684 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009685 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9686 }
9687 if (r.app != null && r.app.persistent) {
9688 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9689 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009690
9691 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9692 for (int i=0; i<connl.size(); i++) {
9693 ConnectionRecord conn = connl.get(i);
9694 if (conn.clientLabel != 0) {
9695 info.clientPackage = conn.binding.client.info.packageName;
9696 info.clientLabel = conn.clientLabel;
9697 return info;
9698 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009699 }
9700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009701 return info;
9702 }
9703
9704 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9705 int flags) {
9706 synchronized (this) {
9707 ArrayList<ActivityManager.RunningServiceInfo> res
9708 = new ArrayList<ActivityManager.RunningServiceInfo>();
9709
9710 if (mServices.size() > 0) {
9711 Iterator<ServiceRecord> it = mServices.values().iterator();
9712 while (it.hasNext() && res.size() < maxNum) {
9713 res.add(makeRunningServiceInfoLocked(it.next()));
9714 }
9715 }
9716
9717 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9718 ServiceRecord r = mRestartingServices.get(i);
9719 ActivityManager.RunningServiceInfo info =
9720 makeRunningServiceInfoLocked(r);
9721 info.restarting = r.nextRestartTime;
9722 res.add(info);
9723 }
9724
9725 return res;
9726 }
9727 }
9728
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009729 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9730 synchronized (this) {
9731 ServiceRecord r = mServices.get(name);
9732 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009733 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9734 for (int i=0; i<conn.size(); i++) {
9735 if (conn.get(i).clientIntent != null) {
9736 return conn.get(i).clientIntent;
9737 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009738 }
9739 }
9740 }
9741 }
9742 return null;
9743 }
9744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 private final ServiceRecord findServiceLocked(ComponentName name,
9746 IBinder token) {
9747 ServiceRecord r = mServices.get(name);
9748 return r == token ? r : null;
9749 }
9750
9751 private final class ServiceLookupResult {
9752 final ServiceRecord record;
9753 final String permission;
9754
9755 ServiceLookupResult(ServiceRecord _record, String _permission) {
9756 record = _record;
9757 permission = _permission;
9758 }
9759 };
9760
9761 private ServiceLookupResult findServiceLocked(Intent service,
9762 String resolvedType) {
9763 ServiceRecord r = null;
9764 if (service.getComponent() != null) {
9765 r = mServices.get(service.getComponent());
9766 }
9767 if (r == null) {
9768 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9769 r = mServicesByIntent.get(filter);
9770 }
9771
9772 if (r == null) {
9773 try {
9774 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009775 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009776 service, resolvedType, 0);
9777 ServiceInfo sInfo =
9778 rInfo != null ? rInfo.serviceInfo : null;
9779 if (sInfo == null) {
9780 return null;
9781 }
9782
9783 ComponentName name = new ComponentName(
9784 sInfo.applicationInfo.packageName, sInfo.name);
9785 r = mServices.get(name);
9786 } catch (RemoteException ex) {
9787 // pm is in same process, this will never happen.
9788 }
9789 }
9790 if (r != null) {
9791 int callingPid = Binder.getCallingPid();
9792 int callingUid = Binder.getCallingUid();
9793 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009794 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009795 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009796 if (!r.exported) {
9797 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9798 + " from pid=" + callingPid
9799 + ", uid=" + callingUid
9800 + " that is not exported from uid " + r.appInfo.uid);
9801 return new ServiceLookupResult(null, "not exported from uid "
9802 + r.appInfo.uid);
9803 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009804 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009805 + " from pid=" + callingPid
9806 + ", uid=" + callingUid
9807 + " requires " + r.permission);
9808 return new ServiceLookupResult(null, r.permission);
9809 }
9810 return new ServiceLookupResult(r, null);
9811 }
9812 return null;
9813 }
9814
9815 private class ServiceRestarter implements Runnable {
9816 private ServiceRecord mService;
9817
9818 void setService(ServiceRecord service) {
9819 mService = service;
9820 }
9821
9822 public void run() {
9823 synchronized(ActivityManagerService.this) {
9824 performServiceRestartLocked(mService);
9825 }
9826 }
9827 }
9828
9829 private ServiceLookupResult retrieveServiceLocked(Intent service,
9830 String resolvedType, int callingPid, int callingUid) {
9831 ServiceRecord r = null;
9832 if (service.getComponent() != null) {
9833 r = mServices.get(service.getComponent());
9834 }
9835 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9836 r = mServicesByIntent.get(filter);
9837 if (r == null) {
9838 try {
9839 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009840 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009841 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009842 ServiceInfo sInfo =
9843 rInfo != null ? rInfo.serviceInfo : null;
9844 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009845 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 ": not found");
9847 return null;
9848 }
9849
9850 ComponentName name = new ComponentName(
9851 sInfo.applicationInfo.packageName, sInfo.name);
9852 r = mServices.get(name);
9853 if (r == null) {
9854 filter = new Intent.FilterComparison(service.cloneFilter());
9855 ServiceRestarter res = new ServiceRestarter();
9856 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9857 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9858 synchronized (stats) {
9859 ss = stats.getServiceStatsLocked(
9860 sInfo.applicationInfo.uid, sInfo.packageName,
9861 sInfo.name);
9862 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009863 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 res.setService(r);
9865 mServices.put(name, r);
9866 mServicesByIntent.put(filter, r);
9867
9868 // Make sure this component isn't in the pending list.
9869 int N = mPendingServices.size();
9870 for (int i=0; i<N; i++) {
9871 ServiceRecord pr = mPendingServices.get(i);
9872 if (pr.name.equals(name)) {
9873 mPendingServices.remove(i);
9874 i--;
9875 N--;
9876 }
9877 }
9878 }
9879 } catch (RemoteException ex) {
9880 // pm is in same process, this will never happen.
9881 }
9882 }
9883 if (r != null) {
9884 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009885 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009886 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009887 if (!r.exported) {
9888 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9889 + " from pid=" + callingPid
9890 + ", uid=" + callingUid
9891 + " that is not exported from uid " + r.appInfo.uid);
9892 return new ServiceLookupResult(null, "not exported from uid "
9893 + r.appInfo.uid);
9894 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009895 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009896 + " from pid=" + callingPid
9897 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 + " requires " + r.permission);
9899 return new ServiceLookupResult(null, r.permission);
9900 }
9901 return new ServiceLookupResult(r, null);
9902 }
9903 return null;
9904 }
9905
Dianne Hackborn287952c2010-09-22 22:34:31 -07009906 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9907 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9908 + why + " of " + r + " in app " + r.app);
9909 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9910 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911 long now = SystemClock.uptimeMillis();
9912 if (r.executeNesting == 0 && r.app != null) {
9913 if (r.app.executingServices.size() == 0) {
9914 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9915 msg.obj = r.app;
9916 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9917 }
9918 r.app.executingServices.add(r);
9919 }
9920 r.executeNesting++;
9921 r.executingStart = now;
9922 }
9923
9924 private final void sendServiceArgsLocked(ServiceRecord r,
9925 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009926 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 if (N == 0) {
9928 return;
9929 }
9930
Dianne Hackborn39792d22010-08-19 18:01:52 -07009931 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009932 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009933 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009934 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9935 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009936 if (si.intent == null && N > 1) {
9937 // If somehow we got a dummy null intent in the middle,
9938 // then skip it. DO NOT skip a null intent when it is
9939 // the only one in the list -- this is to support the
9940 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009941 continue;
9942 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009943 si.deliveredTime = SystemClock.uptimeMillis();
9944 r.deliveredStarts.add(si);
9945 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009946 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009947 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009948 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009949 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009950 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009951 if (!oomAdjusted) {
9952 oomAdjusted = true;
9953 updateOomAdjLocked(r.app);
9954 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009955 int flags = 0;
9956 if (si.deliveryCount > 0) {
9957 flags |= Service.START_FLAG_RETRY;
9958 }
9959 if (si.doneExecutingCount > 0) {
9960 flags |= Service.START_FLAG_REDELIVERY;
9961 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009962 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009963 } catch (RemoteException e) {
9964 // Remote process gone... we'll let the normal cleanup take
9965 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009966 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009967 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009969 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009970 break;
9971 }
9972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009973 }
9974
9975 private final boolean requestServiceBindingLocked(ServiceRecord r,
9976 IntentBindRecord i, boolean rebind) {
9977 if (r.app == null || r.app.thread == null) {
9978 // If service is not currently running, can't yet bind.
9979 return false;
9980 }
9981 if ((!i.requested || rebind) && i.apps.size() > 0) {
9982 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009983 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9985 if (!rebind) {
9986 i.requested = true;
9987 }
9988 i.hasBound = true;
9989 i.doRebind = false;
9990 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009991 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 return false;
9993 }
9994 }
9995 return true;
9996 }
9997
9998 private final void requestServiceBindingsLocked(ServiceRecord r) {
9999 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10000 while (bindings.hasNext()) {
10001 IntentBindRecord i = bindings.next();
10002 if (!requestServiceBindingLocked(r, i, false)) {
10003 break;
10004 }
10005 }
10006 }
10007
10008 private final void realStartServiceLocked(ServiceRecord r,
10009 ProcessRecord app) throws RemoteException {
10010 if (app.thread == null) {
10011 throw new RemoteException();
10012 }
10013
10014 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010015 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016
10017 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010018 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010019 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020
10021 boolean created = false;
10022 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010023 mStringBuilder.setLength(0);
10024 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010025 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010026 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010027 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010028 synchronized (r.stats.getBatteryStats()) {
10029 r.stats.startLaunchedLocked();
10030 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010031 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010032 app.thread.scheduleCreateService(r, r.serviceInfo,
10033 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010034 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010035 created = true;
10036 } finally {
10037 if (!created) {
10038 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010039 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010040 }
10041 }
10042
10043 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010044
10045 // If the service is in the started state, and there are no
10046 // pending arguments, then fake up one so its onStartCommand() will
10047 // be called.
10048 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010049 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10050 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010051 }
10052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010053 sendServiceArgsLocked(r, true);
10054 }
10055
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010056 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10057 boolean allowCancel) {
10058 boolean canceled = false;
10059
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010060 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010061 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010062 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010063
Dianne Hackborn070783f2010-12-29 16:46:28 -080010064 if ((r.serviceInfo.applicationInfo.flags
10065 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10066 minDuration /= 4;
10067 }
10068
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010069 // Any delivered but not yet finished starts should be put back
10070 // on the pending list.
10071 final int N = r.deliveredStarts.size();
10072 if (N > 0) {
10073 for (int i=N-1; i>=0; i--) {
10074 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010075 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010076 if (si.intent == null) {
10077 // We'll generate this again if needed.
10078 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10079 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10080 r.pendingStarts.add(0, si);
10081 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10082 dur *= 2;
10083 if (minDuration < dur) minDuration = dur;
10084 if (resetTime < dur) resetTime = dur;
10085 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010086 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010087 + r.name);
10088 canceled = true;
10089 }
10090 }
10091 r.deliveredStarts.clear();
10092 }
10093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010094 r.totalRestartCount++;
10095 if (r.restartDelay == 0) {
10096 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010097 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098 } else {
10099 // If it has been a "reasonably long time" since the service
10100 // was started, then reset our restart duration back to
10101 // the beginning, so we don't infinitely increase the duration
10102 // on a service that just occasionally gets killed (which is
10103 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010104 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010106 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010108 if ((r.serviceInfo.applicationInfo.flags
10109 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10110 // Services in peristent processes will restart much more
10111 // quickly, since they are pretty important. (Think SystemUI).
10112 r.restartDelay += minDuration/2;
10113 } else {
10114 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10115 if (r.restartDelay < minDuration) {
10116 r.restartDelay = minDuration;
10117 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010118 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010119 }
10120 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010121
10122 r.nextRestartTime = now + r.restartDelay;
10123
10124 // Make sure that we don't end up restarting a bunch of services
10125 // all at the same time.
10126 boolean repeat;
10127 do {
10128 repeat = false;
10129 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10130 ServiceRecord r2 = mRestartingServices.get(i);
10131 if (r2 != r && r.nextRestartTime
10132 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10133 && r.nextRestartTime
10134 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10135 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10136 r.restartDelay = r.nextRestartTime - now;
10137 repeat = true;
10138 break;
10139 }
10140 }
10141 } while (repeat);
10142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010143 if (!mRestartingServices.contains(r)) {
10144 mRestartingServices.add(r);
10145 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010146
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010147 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010149 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010150 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010151 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010152 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010153 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010154 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010155 r.shortName, r.restartDelay);
10156
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010157 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158 }
10159
10160 final void performServiceRestartLocked(ServiceRecord r) {
10161 if (!mRestartingServices.contains(r)) {
10162 return;
10163 }
10164 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10165 }
10166
10167 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10168 if (r.restartDelay == 0) {
10169 return false;
10170 }
10171 r.resetRestartCounter();
10172 mRestartingServices.remove(r);
10173 mHandler.removeCallbacks(r.restarter);
10174 return true;
10175 }
10176
10177 private final boolean bringUpServiceLocked(ServiceRecord r,
10178 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010179 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010180 //r.dump(" ");
10181
Dianne Hackborn36124872009-10-08 16:22:03 -070010182 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010183 sendServiceArgsLocked(r, false);
10184 return true;
10185 }
10186
10187 if (!whileRestarting && r.restartDelay > 0) {
10188 // If waiting for a restart, then do nothing.
10189 return true;
10190 }
10191
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010192 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010194 // We are now bringing the service up, so no longer in the
10195 // restarting state.
10196 mRestartingServices.remove(r);
10197
Dianne Hackborne7f97212011-02-24 14:40:20 -080010198 // Service is now being launched, its package can't be stopped.
10199 try {
10200 AppGlobals.getPackageManager().setPackageStoppedState(
10201 r.packageName, false);
10202 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010203 } catch (IllegalArgumentException e) {
10204 Slog.w(TAG, "Failed trying to unstop package "
10205 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010206 }
10207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 final String appName = r.processName;
10209 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10210 if (app != null && app.thread != null) {
10211 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010212 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213 realStartServiceLocked(r, app);
10214 return true;
10215 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010216 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010217 }
10218
10219 // If a dead object exception was thrown -- fall through to
10220 // restart the application.
10221 }
10222
Dianne Hackborn36124872009-10-08 16:22:03 -070010223 // Not running -- get it started, and enqueue this service record
10224 // to be executed when the app comes up.
10225 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10226 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010227 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010228 + r.appInfo.packageName + "/"
10229 + r.appInfo.uid + " for service "
10230 + r.intent.getIntent() + ": process is bad");
10231 bringDownServiceLocked(r, true);
10232 return false;
10233 }
10234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010235 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010236 mPendingServices.add(r);
10237 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 return true;
10240 }
10241
10242 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010243 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 //r.dump(" ");
10245
10246 // Does it still need to run?
10247 if (!force && r.startRequested) {
10248 return;
10249 }
10250 if (r.connections.size() > 0) {
10251 if (!force) {
10252 // XXX should probably keep a count of the number of auto-create
10253 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010254 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010255 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010256 ArrayList<ConnectionRecord> cr = it.next();
10257 for (int i=0; i<cr.size(); i++) {
10258 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10259 return;
10260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 }
10262 }
10263 }
10264
10265 // Report to all of the connections that the service is no longer
10266 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010267 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010268 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010269 ArrayList<ConnectionRecord> c = it.next();
10270 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010271 ConnectionRecord cr = c.get(i);
10272 // There is still a connection to the service that is
10273 // being brought down. Mark it as dead.
10274 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010275 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010276 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010277 } catch (Exception e) {
10278 Slog.w(TAG, "Failure disconnecting service " + r.name +
10279 " to connection " + c.get(i).conn.asBinder() +
10280 " (in " + c.get(i).binding.client.processName + ")", e);
10281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010282 }
10283 }
10284 }
10285
10286 // Tell the service that it has been unbound.
10287 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10288 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10289 while (it.hasNext()) {
10290 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010291 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010292 + ": hasBound=" + ibr.hasBound);
10293 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10294 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010295 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 updateOomAdjLocked(r.app);
10297 ibr.hasBound = false;
10298 r.app.thread.scheduleUnbindService(r,
10299 ibr.intent.getIntent());
10300 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010301 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 + r.shortName, e);
10303 serviceDoneExecutingLocked(r, true);
10304 }
10305 }
10306 }
10307 }
10308
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010309 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010310 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010311 System.identityHashCode(r), r.shortName,
10312 (r.app != null) ? r.app.pid : -1);
10313
10314 mServices.remove(r.name);
10315 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010316 r.totalRestartCount = 0;
10317 unscheduleServiceRestartLocked(r);
10318
10319 // Also make sure it is not on the pending list.
10320 int N = mPendingServices.size();
10321 for (int i=0; i<N; i++) {
10322 if (mPendingServices.get(i) == r) {
10323 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010324 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010325 i--;
10326 N--;
10327 }
10328 }
10329
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010330 r.cancelNotification();
10331 r.isForeground = false;
10332 r.foregroundId = 0;
10333 r.foregroundNoti = null;
10334
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010335 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010336 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010337 r.pendingStarts.clear();
10338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010339 if (r.app != null) {
10340 synchronized (r.stats.getBatteryStats()) {
10341 r.stats.stopLaunchedLocked();
10342 }
10343 r.app.services.remove(r);
10344 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010345 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010346 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010347 mStoppingServices.add(r);
10348 updateOomAdjLocked(r.app);
10349 r.app.thread.scheduleStopService(r);
10350 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010351 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010352 + r.shortName, e);
10353 serviceDoneExecutingLocked(r, true);
10354 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010355 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010356 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010357 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010358 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 }
10360 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010361 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010362 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010363 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010364
10365 if (r.bindings.size() > 0) {
10366 r.bindings.clear();
10367 }
10368
10369 if (r.restarter instanceof ServiceRestarter) {
10370 ((ServiceRestarter)r.restarter).setService(null);
10371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 }
10373
10374 ComponentName startServiceLocked(IApplicationThread caller,
10375 Intent service, String resolvedType,
10376 int callingPid, int callingUid) {
10377 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010378 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 + " type=" + resolvedType + " args=" + service.getExtras());
10380
10381 if (caller != null) {
10382 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10383 if (callerApp == null) {
10384 throw new SecurityException(
10385 "Unable to find app for caller " + caller
10386 + " (pid=" + Binder.getCallingPid()
10387 + ") when starting service " + service);
10388 }
10389 }
10390
10391 ServiceLookupResult res =
10392 retrieveServiceLocked(service, resolvedType,
10393 callingPid, callingUid);
10394 if (res == null) {
10395 return null;
10396 }
10397 if (res.record == null) {
10398 return new ComponentName("!", res.permission != null
10399 ? res.permission : "private to package");
10400 }
10401 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010402 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10403 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010405 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 }
10407 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010408 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010409 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010410 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 r.lastActivity = SystemClock.uptimeMillis();
10412 synchronized (r.stats.getBatteryStats()) {
10413 r.stats.startRunningLocked();
10414 }
10415 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10416 return new ComponentName("!", "Service process is bad");
10417 }
10418 return r.name;
10419 }
10420 }
10421
10422 public ComponentName startService(IApplicationThread caller, Intent service,
10423 String resolvedType) {
10424 // Refuse possible leaked file descriptors
10425 if (service != null && service.hasFileDescriptors() == true) {
10426 throw new IllegalArgumentException("File descriptors passed in Intent");
10427 }
10428
10429 synchronized(this) {
10430 final int callingPid = Binder.getCallingPid();
10431 final int callingUid = Binder.getCallingUid();
10432 final long origId = Binder.clearCallingIdentity();
10433 ComponentName res = startServiceLocked(caller, service,
10434 resolvedType, callingPid, callingUid);
10435 Binder.restoreCallingIdentity(origId);
10436 return res;
10437 }
10438 }
10439
10440 ComponentName startServiceInPackage(int uid,
10441 Intent service, String resolvedType) {
10442 synchronized(this) {
10443 final long origId = Binder.clearCallingIdentity();
10444 ComponentName res = startServiceLocked(null, service,
10445 resolvedType, -1, uid);
10446 Binder.restoreCallingIdentity(origId);
10447 return res;
10448 }
10449 }
10450
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010451 private void stopServiceLocked(ServiceRecord service) {
10452 synchronized (service.stats.getBatteryStats()) {
10453 service.stats.stopRunningLocked();
10454 }
10455 service.startRequested = false;
10456 service.callStart = false;
10457 bringDownServiceLocked(service, false);
10458 }
10459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010460 public int stopService(IApplicationThread caller, Intent service,
10461 String resolvedType) {
10462 // Refuse possible leaked file descriptors
10463 if (service != null && service.hasFileDescriptors() == true) {
10464 throw new IllegalArgumentException("File descriptors passed in Intent");
10465 }
10466
10467 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010468 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 + " type=" + resolvedType);
10470
10471 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10472 if (caller != null && callerApp == null) {
10473 throw new SecurityException(
10474 "Unable to find app for caller " + caller
10475 + " (pid=" + Binder.getCallingPid()
10476 + ") when stopping service " + service);
10477 }
10478
10479 // If this service is active, make sure it is stopped.
10480 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10481 if (r != null) {
10482 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010483 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010484 try {
10485 stopServiceLocked(r.record);
10486 } finally {
10487 Binder.restoreCallingIdentity(origId);
10488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 return 1;
10490 }
10491 return -1;
10492 }
10493 }
10494
10495 return 0;
10496 }
10497
10498 public IBinder peekService(Intent service, String resolvedType) {
10499 // Refuse possible leaked file descriptors
10500 if (service != null && service.hasFileDescriptors() == true) {
10501 throw new IllegalArgumentException("File descriptors passed in Intent");
10502 }
10503
10504 IBinder ret = null;
10505
10506 synchronized(this) {
10507 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10508
10509 if (r != null) {
10510 // r.record is null if findServiceLocked() failed the caller permission check
10511 if (r.record == null) {
10512 throw new SecurityException(
10513 "Permission Denial: Accessing service " + r.record.name
10514 + " from pid=" + Binder.getCallingPid()
10515 + ", uid=" + Binder.getCallingUid()
10516 + " requires " + r.permission);
10517 }
10518 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10519 if (ib != null) {
10520 ret = ib.binder;
10521 }
10522 }
10523 }
10524
10525 return ret;
10526 }
10527
10528 public boolean stopServiceToken(ComponentName className, IBinder token,
10529 int startId) {
10530 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010531 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010532 + " " + token + " startId=" + startId);
10533 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010534 if (r != null) {
10535 if (startId >= 0) {
10536 // Asked to only stop if done with all work. Note that
10537 // to avoid leaks, we will take this as dropping all
10538 // start items up to and including this one.
10539 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10540 if (si != null) {
10541 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010542 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10543 cur.removeUriPermissionsLocked();
10544 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010545 break;
10546 }
10547 }
10548 }
10549
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010550 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010551 return false;
10552 }
10553
10554 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010555 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010556 + " is last, but have " + r.deliveredStarts.size()
10557 + " remaining args");
10558 }
10559 }
10560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010561 synchronized (r.stats.getBatteryStats()) {
10562 r.stats.stopRunningLocked();
10563 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010564 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010565 }
10566 final long origId = Binder.clearCallingIdentity();
10567 bringDownServiceLocked(r, false);
10568 Binder.restoreCallingIdentity(origId);
10569 return true;
10570 }
10571 }
10572 return false;
10573 }
10574
10575 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010576 int id, Notification notification, boolean removeNotification) {
10577 final long origId = Binder.clearCallingIdentity();
10578 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010579 synchronized(this) {
10580 ServiceRecord r = findServiceLocked(className, token);
10581 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010582 if (id != 0) {
10583 if (notification == null) {
10584 throw new IllegalArgumentException("null notification");
10585 }
10586 if (r.foregroundId != id) {
10587 r.cancelNotification();
10588 r.foregroundId = id;
10589 }
10590 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10591 r.foregroundNoti = notification;
10592 r.isForeground = true;
10593 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010594 if (r.app != null) {
10595 updateServiceForegroundLocked(r.app, true);
10596 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010597 } else {
10598 if (r.isForeground) {
10599 r.isForeground = false;
10600 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010601 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010602 updateServiceForegroundLocked(r.app, true);
10603 }
10604 }
10605 if (removeNotification) {
10606 r.cancelNotification();
10607 r.foregroundId = 0;
10608 r.foregroundNoti = null;
10609 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010610 }
10611 }
10612 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010613 } finally {
10614 Binder.restoreCallingIdentity(origId);
10615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010616 }
10617
10618 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10619 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010620 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010621 if (sr.isForeground) {
10622 anyForeground = true;
10623 break;
10624 }
10625 }
10626 if (anyForeground != proc.foregroundServices) {
10627 proc.foregroundServices = anyForeground;
10628 if (oomAdj) {
10629 updateOomAdjLocked();
10630 }
10631 }
10632 }
10633
10634 public int bindService(IApplicationThread caller, IBinder token,
10635 Intent service, String resolvedType,
10636 IServiceConnection connection, int flags) {
10637 // Refuse possible leaked file descriptors
10638 if (service != null && service.hasFileDescriptors() == true) {
10639 throw new IllegalArgumentException("File descriptors passed in Intent");
10640 }
10641
10642 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010643 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 + " type=" + resolvedType + " conn=" + connection.asBinder()
10645 + " flags=0x" + Integer.toHexString(flags));
10646 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10647 if (callerApp == null) {
10648 throw new SecurityException(
10649 "Unable to find app for caller " + caller
10650 + " (pid=" + Binder.getCallingPid()
10651 + ") when binding service " + service);
10652 }
10653
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010654 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010655 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010656 activity = mMainStack.isInStackLocked(token);
10657 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010658 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 return 0;
10660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010661 }
10662
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010663 int clientLabel = 0;
10664 PendingIntent clientIntent = null;
10665
10666 if (callerApp.info.uid == Process.SYSTEM_UID) {
10667 // Hacky kind of thing -- allow system stuff to tell us
10668 // what they are, so we can report this elsewhere for
10669 // others to know why certain services are running.
10670 try {
10671 clientIntent = (PendingIntent)service.getParcelableExtra(
10672 Intent.EXTRA_CLIENT_INTENT);
10673 } catch (RuntimeException e) {
10674 }
10675 if (clientIntent != null) {
10676 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10677 if (clientLabel != 0) {
10678 // There are no useful extras in the intent, trash them.
10679 // System code calling with this stuff just needs to know
10680 // this will happen.
10681 service = service.cloneFilter();
10682 }
10683 }
10684 }
10685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010686 ServiceLookupResult res =
10687 retrieveServiceLocked(service, resolvedType,
10688 Binder.getCallingPid(), Binder.getCallingUid());
10689 if (res == null) {
10690 return 0;
10691 }
10692 if (res.record == null) {
10693 return -1;
10694 }
10695 ServiceRecord s = res.record;
10696
10697 final long origId = Binder.clearCallingIdentity();
10698
10699 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010700 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010701 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010702 }
10703
10704 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10705 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010706 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010707
10708 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010709 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10710 if (clist == null) {
10711 clist = new ArrayList<ConnectionRecord>();
10712 s.connections.put(binder, clist);
10713 }
10714 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010715 b.connections.add(c);
10716 if (activity != null) {
10717 if (activity.connections == null) {
10718 activity.connections = new HashSet<ConnectionRecord>();
10719 }
10720 activity.connections.add(c);
10721 }
10722 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010723 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10724 b.client.hasAboveClient = true;
10725 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010726 clist = mServiceConnections.get(binder);
10727 if (clist == null) {
10728 clist = new ArrayList<ConnectionRecord>();
10729 mServiceConnections.put(binder, clist);
10730 }
10731 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010732
10733 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10734 s.lastActivity = SystemClock.uptimeMillis();
10735 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10736 return 0;
10737 }
10738 }
10739
10740 if (s.app != null) {
10741 // This could have made the service more important.
10742 updateOomAdjLocked(s.app);
10743 }
10744
Joe Onorato8a9b2202010-02-26 18:56:32 -080010745 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010746 + ": received=" + b.intent.received
10747 + " apps=" + b.intent.apps.size()
10748 + " doRebind=" + b.intent.doRebind);
10749
10750 if (s.app != null && b.intent.received) {
10751 // Service is already running, so we can immediately
10752 // publish the connection.
10753 try {
10754 c.conn.connected(s.name, b.intent.binder);
10755 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010756 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010757 + " to connection " + c.conn.asBinder()
10758 + " (in " + c.binding.client.processName + ")", e);
10759 }
10760
10761 // If this is the first app connected back to this binding,
10762 // and the service had previously asked to be told when
10763 // rebound, then do so.
10764 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10765 requestServiceBindingLocked(s, b.intent, true);
10766 }
10767 } else if (!b.intent.requested) {
10768 requestServiceBindingLocked(s, b.intent, false);
10769 }
10770
10771 Binder.restoreCallingIdentity(origId);
10772 }
10773
10774 return 1;
10775 }
10776
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010777 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010778 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 IBinder binder = c.conn.asBinder();
10780 AppBindRecord b = c.binding;
10781 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010782 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10783 if (clist != null) {
10784 clist.remove(c);
10785 if (clist.size() == 0) {
10786 s.connections.remove(binder);
10787 }
10788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010789 b.connections.remove(c);
10790 if (c.activity != null && c.activity != skipAct) {
10791 if (c.activity.connections != null) {
10792 c.activity.connections.remove(c);
10793 }
10794 }
10795 if (b.client != skipApp) {
10796 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010797 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10798 b.client.updateHasAboveClientLocked();
10799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010801 clist = mServiceConnections.get(binder);
10802 if (clist != null) {
10803 clist.remove(c);
10804 if (clist.size() == 0) {
10805 mServiceConnections.remove(binder);
10806 }
10807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010808
10809 if (b.connections.size() == 0) {
10810 b.intent.apps.remove(b.client);
10811 }
10812
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010813 if (!c.serviceDead) {
10814 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10815 + ": shouldUnbind=" + b.intent.hasBound);
10816 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10817 && b.intent.hasBound) {
10818 try {
10819 bumpServiceExecutingLocked(s, "unbind");
10820 updateOomAdjLocked(s.app);
10821 b.intent.hasBound = false;
10822 // Assume the client doesn't want to know about a rebind;
10823 // we will deal with that later if it asks for one.
10824 b.intent.doRebind = false;
10825 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10826 } catch (Exception e) {
10827 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10828 serviceDoneExecutingLocked(s, true);
10829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010830 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010831
10832 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10833 bringDownServiceLocked(s, false);
10834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010835 }
10836 }
10837
10838 public boolean unbindService(IServiceConnection connection) {
10839 synchronized (this) {
10840 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010841 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010842 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10843 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010844 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845 + connection.asBinder());
10846 return false;
10847 }
10848
10849 final long origId = Binder.clearCallingIdentity();
10850
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010851 while (clist.size() > 0) {
10852 ConnectionRecord r = clist.get(0);
10853 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010854
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010855 if (r.binding.service.app != null) {
10856 // This could have made the service less important.
10857 updateOomAdjLocked(r.binding.service.app);
10858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010859 }
10860
10861 Binder.restoreCallingIdentity(origId);
10862 }
10863
10864 return true;
10865 }
10866
10867 public void publishService(IBinder token, Intent intent, IBinder service) {
10868 // Refuse possible leaked file descriptors
10869 if (intent != null && intent.hasFileDescriptors() == true) {
10870 throw new IllegalArgumentException("File descriptors passed in Intent");
10871 }
10872
10873 synchronized(this) {
10874 if (!(token instanceof ServiceRecord)) {
10875 throw new IllegalArgumentException("Invalid service token");
10876 }
10877 ServiceRecord r = (ServiceRecord)token;
10878
10879 final long origId = Binder.clearCallingIdentity();
10880
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010881 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010882 + " " + intent + ": " + service);
10883 if (r != null) {
10884 Intent.FilterComparison filter
10885 = new Intent.FilterComparison(intent);
10886 IntentBindRecord b = r.bindings.get(filter);
10887 if (b != null && !b.received) {
10888 b.binder = service;
10889 b.requested = true;
10890 b.received = true;
10891 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010892 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010893 = r.connections.values().iterator();
10894 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010895 ArrayList<ConnectionRecord> clist = it.next();
10896 for (int i=0; i<clist.size(); i++) {
10897 ConnectionRecord c = clist.get(i);
10898 if (!filter.equals(c.binding.intent.intent)) {
10899 if (DEBUG_SERVICE) Slog.v(
10900 TAG, "Not publishing to: " + c);
10901 if (DEBUG_SERVICE) Slog.v(
10902 TAG, "Bound intent: " + c.binding.intent.intent);
10903 if (DEBUG_SERVICE) Slog.v(
10904 TAG, "Published intent: " + intent);
10905 continue;
10906 }
10907 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10908 try {
10909 c.conn.connected(r.name, service);
10910 } catch (Exception e) {
10911 Slog.w(TAG, "Failure sending service " + r.name +
10912 " to connection " + c.conn.asBinder() +
10913 " (in " + c.binding.client.processName + ")", e);
10914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 }
10916 }
10917 }
10918 }
10919
10920 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10921
10922 Binder.restoreCallingIdentity(origId);
10923 }
10924 }
10925 }
10926
10927 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10928 // Refuse possible leaked file descriptors
10929 if (intent != null && intent.hasFileDescriptors() == true) {
10930 throw new IllegalArgumentException("File descriptors passed in Intent");
10931 }
10932
10933 synchronized(this) {
10934 if (!(token instanceof ServiceRecord)) {
10935 throw new IllegalArgumentException("Invalid service token");
10936 }
10937 ServiceRecord r = (ServiceRecord)token;
10938
10939 final long origId = Binder.clearCallingIdentity();
10940
10941 if (r != null) {
10942 Intent.FilterComparison filter
10943 = new Intent.FilterComparison(intent);
10944 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010945 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010946 + " at " + b + ": apps="
10947 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010948
10949 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010950 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010951 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010952 // Applications have already bound since the last
10953 // unbind, so just rebind right here.
10954 requestServiceBindingLocked(r, b, true);
10955 } else {
10956 // Note to tell the service the next time there is
10957 // a new client.
10958 b.doRebind = true;
10959 }
10960 }
10961
Per Edelberg78f9fff2010-08-30 20:01:35 +020010962 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963
10964 Binder.restoreCallingIdentity(origId);
10965 }
10966 }
10967 }
10968
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010969 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010970 synchronized(this) {
10971 if (!(token instanceof ServiceRecord)) {
10972 throw new IllegalArgumentException("Invalid service token");
10973 }
10974 ServiceRecord r = (ServiceRecord)token;
10975 boolean inStopping = mStoppingServices.contains(token);
10976 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010977 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010978 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 + " with incorrect token: given " + token
10980 + ", expected " + r);
10981 return;
10982 }
10983
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010984 if (type == 1) {
10985 // This is a call from a service start... take care of
10986 // book-keeping.
10987 r.callStart = true;
10988 switch (res) {
10989 case Service.START_STICKY_COMPATIBILITY:
10990 case Service.START_STICKY: {
10991 // We are done with the associated start arguments.
10992 r.findDeliveredStart(startId, true);
10993 // Don't stop if killed.
10994 r.stopIfKilled = false;
10995 break;
10996 }
10997 case Service.START_NOT_STICKY: {
10998 // We are done with the associated start arguments.
10999 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011000 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011001 // There is no more work, and this service
11002 // doesn't want to hang around if killed.
11003 r.stopIfKilled = true;
11004 }
11005 break;
11006 }
11007 case Service.START_REDELIVER_INTENT: {
11008 // We'll keep this item until they explicitly
11009 // call stop for it, but keep track of the fact
11010 // that it was delivered.
11011 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11012 if (si != null) {
11013 si.deliveryCount = 0;
11014 si.doneExecutingCount++;
11015 // Don't stop if killed.
11016 r.stopIfKilled = true;
11017 }
11018 break;
11019 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011020 case Service.START_TASK_REMOVED_COMPLETE: {
11021 // Special processing for onTaskRemoved(). Don't
11022 // impact normal onStartCommand() processing.
11023 r.findDeliveredStart(startId, true);
11024 break;
11025 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011026 default:
11027 throw new IllegalArgumentException(
11028 "Unknown service start result: " + res);
11029 }
11030 if (res == Service.START_STICKY_COMPATIBILITY) {
11031 r.callStart = false;
11032 }
11033 }
11034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 final long origId = Binder.clearCallingIdentity();
11036 serviceDoneExecutingLocked(r, inStopping);
11037 Binder.restoreCallingIdentity(origId);
11038 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011039 Slog.w(TAG, "Done executing unknown service from pid "
11040 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011041 }
11042 }
11043 }
11044
11045 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011046 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11047 + ": nesting=" + r.executeNesting
11048 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011049 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 r.executeNesting--;
11051 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011052 if (DEBUG_SERVICE) Slog.v(TAG,
11053 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011054 r.app.executingServices.remove(r);
11055 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011056 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11057 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011058 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11059 }
11060 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011061 if (DEBUG_SERVICE) Slog.v(TAG,
11062 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011063 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011064 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 }
11066 updateOomAdjLocked(r.app);
11067 }
11068 }
11069
11070 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011071 String anrMessage = null;
11072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011073 synchronized(this) {
11074 if (proc.executingServices.size() == 0 || proc.thread == null) {
11075 return;
11076 }
11077 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11078 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11079 ServiceRecord timeout = null;
11080 long nextTime = 0;
11081 while (it.hasNext()) {
11082 ServiceRecord sr = it.next();
11083 if (sr.executingStart < maxTime) {
11084 timeout = sr;
11085 break;
11086 }
11087 if (sr.executingStart > nextTime) {
11088 nextTime = sr.executingStart;
11089 }
11090 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011091 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011092 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011093 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011094 } else {
11095 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11096 msg.obj = proc;
11097 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11098 }
11099 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011100
11101 if (anrMessage != null) {
11102 appNotResponding(proc, null, null, anrMessage);
11103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011104 }
11105
11106 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011107 // BACKUP AND RESTORE
11108 // =========================================================
11109
11110 // Cause the target app to be launched if necessary and its backup agent
11111 // instantiated. The backup agent will invoke backupAgentCreated() on the
11112 // activity manager to announce its creation.
11113 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011114 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011115 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11116
11117 synchronized(this) {
11118 // !!! TODO: currently no check here that we're already bound
11119 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11120 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11121 synchronized (stats) {
11122 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11123 }
11124
Dianne Hackborne7f97212011-02-24 14:40:20 -080011125 // Backup agent is now in use, its package can't be stopped.
11126 try {
11127 AppGlobals.getPackageManager().setPackageStoppedState(
11128 app.packageName, false);
11129 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011130 } catch (IllegalArgumentException e) {
11131 Slog.w(TAG, "Failed trying to unstop package "
11132 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011133 }
11134
Christopher Tate181fafa2009-05-14 11:12:14 -070011135 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011136 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11137 ? new ComponentName(app.packageName, app.backupAgentName)
11138 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011139 // startProcessLocked() returns existing proc's record if it's already running
11140 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011141 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011142 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011143 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011144 return false;
11145 }
11146
11147 r.app = proc;
11148 mBackupTarget = r;
11149 mBackupAppName = app.packageName;
11150
Christopher Tate6fa95972009-06-05 18:43:55 -070011151 // Try not to kill the process during backup
11152 updateOomAdjLocked(proc);
11153
Christopher Tate181fafa2009-05-14 11:12:14 -070011154 // If the process is already attached, schedule the creation of the backup agent now.
11155 // If it is not yet live, this will be done when it attaches to the framework.
11156 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011157 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011158 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011159 proc.thread.scheduleCreateBackupAgent(app,
11160 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011161 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011162 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011163 }
11164 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011165 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011166 }
11167 // Invariants: at this point, the target app process exists and the application
11168 // is either already running or in the process of coming up. mBackupTarget and
11169 // mBackupAppName describe the app, so that when it binds back to the AM we
11170 // know that it's scheduled for a backup-agent operation.
11171 }
11172
11173 return true;
11174 }
11175
11176 // A backup agent has just come up
11177 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011178 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011179 + " = " + agent);
11180
11181 synchronized(this) {
11182 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011183 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011184 return;
11185 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011186 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011187
Dianne Hackborn06740692010-09-22 22:46:21 -070011188 long oldIdent = Binder.clearCallingIdentity();
11189 try {
11190 IBackupManager bm = IBackupManager.Stub.asInterface(
11191 ServiceManager.getService(Context.BACKUP_SERVICE));
11192 bm.agentConnected(agentPackageName, agent);
11193 } catch (RemoteException e) {
11194 // can't happen; the backup manager service is local
11195 } catch (Exception e) {
11196 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11197 e.printStackTrace();
11198 } finally {
11199 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011200 }
11201 }
11202
11203 // done with this agent
11204 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011205 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011206 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011207 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011208 return;
11209 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011210
11211 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011212 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011213 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011214 return;
11215 }
11216
Christopher Tate181fafa2009-05-14 11:12:14 -070011217 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011218 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011219 return;
11220 }
11221
Christopher Tate6fa95972009-06-05 18:43:55 -070011222 ProcessRecord proc = mBackupTarget.app;
11223 mBackupTarget = null;
11224 mBackupAppName = null;
11225
11226 // Not backing this app up any more; reset its OOM adjustment
11227 updateOomAdjLocked(proc);
11228
Christopher Tatec7b31e32009-06-10 15:49:30 -070011229 // If the app crashed during backup, 'thread' will be null here
11230 if (proc.thread != null) {
11231 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011232 proc.thread.scheduleDestroyBackupAgent(appInfo,
11233 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011234 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011235 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011236 e.printStackTrace();
11237 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011238 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011239 }
11240 }
11241 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011242 // BROADCASTS
11243 // =========================================================
11244
Josh Bartel7f208742010-02-25 11:01:44 -060011245 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011246 List cur) {
11247 final ContentResolver resolver = mContext.getContentResolver();
11248 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11249 if (list == null) {
11250 return cur;
11251 }
11252 int N = list.size();
11253 for (int i=0; i<N; i++) {
11254 Intent intent = list.get(i);
11255 if (filter.match(resolver, intent, true, TAG) >= 0) {
11256 if (cur == null) {
11257 cur = new ArrayList<Intent>();
11258 }
11259 cur.add(intent);
11260 }
11261 }
11262 return cur;
11263 }
11264
11265 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011266 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011267 + mBroadcastsScheduled);
11268
11269 if (mBroadcastsScheduled) {
11270 return;
11271 }
11272 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11273 mBroadcastsScheduled = true;
11274 }
11275
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011276 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011277 IIntentReceiver receiver, IntentFilter filter, String permission) {
11278 synchronized(this) {
11279 ProcessRecord callerApp = null;
11280 if (caller != null) {
11281 callerApp = getRecordForAppLocked(caller);
11282 if (callerApp == null) {
11283 throw new SecurityException(
11284 "Unable to find app for caller " + caller
11285 + " (pid=" + Binder.getCallingPid()
11286 + ") when registering receiver " + receiver);
11287 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011288 if (callerApp.info.uid != Process.SYSTEM_UID &&
11289 !callerApp.pkgList.contains(callerPackage)) {
11290 throw new SecurityException("Given caller package " + callerPackage
11291 + " is not running in process " + callerApp);
11292 }
11293 } else {
11294 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011295 }
11296
11297 List allSticky = null;
11298
11299 // Look for any matching sticky broadcasts...
11300 Iterator actions = filter.actionsIterator();
11301 if (actions != null) {
11302 while (actions.hasNext()) {
11303 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011304 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011305 }
11306 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011307 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011308 }
11309
11310 // The first sticky in the list is returned directly back to
11311 // the client.
11312 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11313
Joe Onorato8a9b2202010-02-26 18:56:32 -080011314 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011315 + ": " + sticky);
11316
11317 if (receiver == null) {
11318 return sticky;
11319 }
11320
11321 ReceiverList rl
11322 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11323 if (rl == null) {
11324 rl = new ReceiverList(this, callerApp,
11325 Binder.getCallingPid(),
11326 Binder.getCallingUid(), receiver);
11327 if (rl.app != null) {
11328 rl.app.receivers.add(rl);
11329 } else {
11330 try {
11331 receiver.asBinder().linkToDeath(rl, 0);
11332 } catch (RemoteException e) {
11333 return sticky;
11334 }
11335 rl.linkedToDeath = true;
11336 }
11337 mRegisteredReceivers.put(receiver.asBinder(), rl);
11338 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011339 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011340 rl.add(bf);
11341 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011342 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011343 }
11344 mReceiverResolver.addFilter(bf);
11345
11346 // Enqueue broadcasts for all existing stickies that match
11347 // this filter.
11348 if (allSticky != null) {
11349 ArrayList receivers = new ArrayList();
11350 receivers.add(bf);
11351
11352 int N = allSticky.size();
11353 for (int i=0; i<N; i++) {
11354 Intent intent = (Intent)allSticky.get(i);
11355 BroadcastRecord r = new BroadcastRecord(intent, null,
11356 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011357 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011358 if (mParallelBroadcasts.size() == 0) {
11359 scheduleBroadcastsLocked();
11360 }
11361 mParallelBroadcasts.add(r);
11362 }
11363 }
11364
11365 return sticky;
11366 }
11367 }
11368
11369 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011370 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371
11372 boolean doNext = false;
11373
11374 synchronized(this) {
11375 ReceiverList rl
11376 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11377 if (rl != null) {
11378 if (rl.curBroadcast != null) {
11379 BroadcastRecord r = rl.curBroadcast;
11380 doNext = finishReceiverLocked(
11381 receiver.asBinder(), r.resultCode, r.resultData,
11382 r.resultExtras, r.resultAbort, true);
11383 }
11384
11385 if (rl.app != null) {
11386 rl.app.receivers.remove(rl);
11387 }
11388 removeReceiverLocked(rl);
11389 if (rl.linkedToDeath) {
11390 rl.linkedToDeath = false;
11391 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11392 }
11393 }
11394 }
11395
11396 if (!doNext) {
11397 return;
11398 }
11399
11400 final long origId = Binder.clearCallingIdentity();
11401 processNextBroadcast(false);
11402 trimApplications();
11403 Binder.restoreCallingIdentity(origId);
11404 }
11405
11406 void removeReceiverLocked(ReceiverList rl) {
11407 mRegisteredReceivers.remove(rl.receiver.asBinder());
11408 int N = rl.size();
11409 for (int i=0; i<N; i++) {
11410 mReceiverResolver.removeFilter(rl.get(i));
11411 }
11412 }
11413
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011414 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11415 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11416 ProcessRecord r = mLruProcesses.get(i);
11417 if (r.thread != null) {
11418 try {
11419 r.thread.dispatchPackageBroadcast(cmd, packages);
11420 } catch (RemoteException ex) {
11421 }
11422 }
11423 }
11424 }
11425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011426 private final int broadcastIntentLocked(ProcessRecord callerApp,
11427 String callerPackage, Intent intent, String resolvedType,
11428 IIntentReceiver resultTo, int resultCode, String resultData,
11429 Bundle map, String requiredPermission,
11430 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11431 intent = new Intent(intent);
11432
Dianne Hackborne7f97212011-02-24 14:40:20 -080011433 // By default broadcasts do not go to stopped apps.
11434 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11435
Joe Onorato8a9b2202010-02-26 18:56:32 -080011436 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011437 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11438 + " ordered=" + ordered);
11439 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011440 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011441 }
11442
11443 // Handle special intents: if this broadcast is from the package
11444 // manager about a package being removed, we need to remove all of
11445 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011446 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011447 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011448 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11449 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011450 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451 || uidRemoved) {
11452 if (checkComponentPermission(
11453 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011454 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011455 == PackageManager.PERMISSION_GRANTED) {
11456 if (uidRemoved) {
11457 final Bundle intentExtras = intent.getExtras();
11458 final int uid = intentExtras != null
11459 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11460 if (uid >= 0) {
11461 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11462 synchronized (bs) {
11463 bs.removeUidStatsLocked(uid);
11464 }
11465 }
11466 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011467 // If resources are unvailble just force stop all
11468 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011469 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011470 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11471 if (list != null && (list.length > 0)) {
11472 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011473 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011474 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011475 sendPackageBroadcastLocked(
11476 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011477 }
11478 } else {
11479 Uri data = intent.getData();
11480 String ssp;
11481 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11482 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11483 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011484 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011485 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011486 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011487 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11488 new String[] {ssp});
11489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011490 }
11491 }
11492 }
11493 } else {
11494 String msg = "Permission Denial: " + intent.getAction()
11495 + " broadcast from " + callerPackage + " (pid=" + callingPid
11496 + ", uid=" + callingUid + ")"
11497 + " requires "
11498 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011499 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500 throw new SecurityException(msg);
11501 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011502
11503 // Special case for adding a package: by default turn on compatibility
11504 // mode.
11505 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011506 Uri data = intent.getData();
11507 String ssp;
11508 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11509 mCompatModePackages.handlePackageAddedLocked(ssp,
11510 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011512 }
11513
11514 /*
11515 * If this is the time zone changed action, queue up a message that will reset the timezone
11516 * of all currently running processes. This message will get queued up before the broadcast
11517 * happens.
11518 */
11519 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11520 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11521 }
11522
Robert Greenwalt03595d02010-11-02 14:08:23 -070011523 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11524 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11525 }
11526
Robert Greenwalt434203a2010-10-11 16:00:27 -070011527 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11528 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11529 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11530 }
11531
Dianne Hackborn854060af2009-07-09 18:14:31 -070011532 /*
11533 * Prevent non-system code (defined here to be non-persistent
11534 * processes) from sending protected broadcasts.
11535 */
11536 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11537 || callingUid == Process.SHELL_UID || callingUid == 0) {
11538 // Always okay.
11539 } else if (callerApp == null || !callerApp.persistent) {
11540 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011541 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011542 intent.getAction())) {
11543 String msg = "Permission Denial: not allowed to send broadcast "
11544 + intent.getAction() + " from pid="
11545 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011546 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011547 throw new SecurityException(msg);
11548 }
11549 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011550 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011551 return BROADCAST_SUCCESS;
11552 }
11553 }
11554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011555 // Add to the sticky list if requested.
11556 if (sticky) {
11557 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11558 callingPid, callingUid)
11559 != PackageManager.PERMISSION_GRANTED) {
11560 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11561 + callingPid + ", uid=" + callingUid
11562 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011563 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564 throw new SecurityException(msg);
11565 }
11566 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011567 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011568 + " and enforce permission " + requiredPermission);
11569 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11570 }
11571 if (intent.getComponent() != null) {
11572 throw new SecurityException(
11573 "Sticky broadcasts can't target a specific component");
11574 }
11575 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11576 if (list == null) {
11577 list = new ArrayList<Intent>();
11578 mStickyBroadcasts.put(intent.getAction(), list);
11579 }
11580 int N = list.size();
11581 int i;
11582 for (i=0; i<N; i++) {
11583 if (intent.filterEquals(list.get(i))) {
11584 // This sticky already exists, replace it.
11585 list.set(i, new Intent(intent));
11586 break;
11587 }
11588 }
11589 if (i >= N) {
11590 list.add(new Intent(intent));
11591 }
11592 }
11593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011594 // Figure out who all will receive this broadcast.
11595 List receivers = null;
11596 List<BroadcastFilter> registeredReceivers = null;
11597 try {
11598 if (intent.getComponent() != null) {
11599 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011600 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011601 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011602 if (ai != null) {
11603 receivers = new ArrayList();
11604 ResolveInfo ri = new ResolveInfo();
11605 ri.activityInfo = ai;
11606 receivers.add(ri);
11607 }
11608 } else {
11609 // Need to resolve the intent to interested receivers...
11610 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11611 == 0) {
11612 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011613 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011614 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011615 }
Mihai Preda074edef2009-05-18 17:13:31 +020011616 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011617 }
11618 } catch (RemoteException ex) {
11619 // pm is in same process, this will never happen.
11620 }
11621
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011622 final boolean replacePending =
11623 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11624
Joe Onorato8a9b2202010-02-26 18:56:32 -080011625 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011626 + " replacePending=" + replacePending);
11627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011628 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11629 if (!ordered && NR > 0) {
11630 // If we are not serializing this broadcast, then send the
11631 // registered receivers separately so they don't wait for the
11632 // components to be launched.
11633 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11634 callerPackage, callingPid, callingUid, requiredPermission,
11635 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011636 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011637 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011638 TAG, "Enqueueing parallel broadcast " + r
11639 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011640 boolean replaced = false;
11641 if (replacePending) {
11642 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11643 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011644 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011645 "***** DROPPING PARALLEL: " + intent);
11646 mParallelBroadcasts.set(i, r);
11647 replaced = true;
11648 break;
11649 }
11650 }
11651 }
11652 if (!replaced) {
11653 mParallelBroadcasts.add(r);
11654 scheduleBroadcastsLocked();
11655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011656 registeredReceivers = null;
11657 NR = 0;
11658 }
11659
11660 // Merge into one list.
11661 int ir = 0;
11662 if (receivers != null) {
11663 // A special case for PACKAGE_ADDED: do not allow the package
11664 // being added to see this broadcast. This prevents them from
11665 // using this as a back door to get run as soon as they are
11666 // installed. Maybe in the future we want to have a special install
11667 // broadcast or such for apps, but we'd like to deliberately make
11668 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011669 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011670 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11671 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11672 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011673 Uri data = intent.getData();
11674 if (data != null) {
11675 String pkgName = data.getSchemeSpecificPart();
11676 if (pkgName != null) {
11677 skipPackages = new String[] { pkgName };
11678 }
11679 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011680 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011681 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011682 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011683 if (skipPackages != null && (skipPackages.length > 0)) {
11684 for (String skipPackage : skipPackages) {
11685 if (skipPackage != null) {
11686 int NT = receivers.size();
11687 for (int it=0; it<NT; it++) {
11688 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11689 if (curt.activityInfo.packageName.equals(skipPackage)) {
11690 receivers.remove(it);
11691 it--;
11692 NT--;
11693 }
11694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011695 }
11696 }
11697 }
11698
11699 int NT = receivers != null ? receivers.size() : 0;
11700 int it = 0;
11701 ResolveInfo curt = null;
11702 BroadcastFilter curr = null;
11703 while (it < NT && ir < NR) {
11704 if (curt == null) {
11705 curt = (ResolveInfo)receivers.get(it);
11706 }
11707 if (curr == null) {
11708 curr = registeredReceivers.get(ir);
11709 }
11710 if (curr.getPriority() >= curt.priority) {
11711 // Insert this broadcast record into the final list.
11712 receivers.add(it, curr);
11713 ir++;
11714 curr = null;
11715 it++;
11716 NT++;
11717 } else {
11718 // Skip to the next ResolveInfo in the final list.
11719 it++;
11720 curt = null;
11721 }
11722 }
11723 }
11724 while (ir < NR) {
11725 if (receivers == null) {
11726 receivers = new ArrayList();
11727 }
11728 receivers.add(registeredReceivers.get(ir));
11729 ir++;
11730 }
11731
11732 if ((receivers != null && receivers.size() > 0)
11733 || resultTo != null) {
11734 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11735 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011736 receivers, resultTo, resultCode, resultData, map, ordered,
11737 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011738 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011739 TAG, "Enqueueing ordered broadcast " + r
11740 + ": prev had " + mOrderedBroadcasts.size());
11741 if (DEBUG_BROADCAST) {
11742 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011743 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011744 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011745 boolean replaced = false;
11746 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011747 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011748 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011749 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011750 "***** DROPPING ORDERED: " + intent);
11751 mOrderedBroadcasts.set(i, r);
11752 replaced = true;
11753 break;
11754 }
11755 }
11756 }
11757 if (!replaced) {
11758 mOrderedBroadcasts.add(r);
11759 scheduleBroadcastsLocked();
11760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011761 }
11762
11763 return BROADCAST_SUCCESS;
11764 }
11765
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011766 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011767 // Refuse possible leaked file descriptors
11768 if (intent != null && intent.hasFileDescriptors() == true) {
11769 throw new IllegalArgumentException("File descriptors passed in Intent");
11770 }
11771
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011772 int flags = intent.getFlags();
11773
11774 if (!mProcessesReady) {
11775 // if the caller really truly claims to know what they're doing, go
11776 // ahead and allow the broadcast without launching any receivers
11777 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11778 intent = new Intent(intent);
11779 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11780 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11781 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11782 + " before boot completion");
11783 throw new IllegalStateException("Cannot broadcast before boot completed");
11784 }
11785 }
11786
11787 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11788 throw new IllegalArgumentException(
11789 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11790 }
11791
11792 return intent;
11793 }
11794
11795 public final int broadcastIntent(IApplicationThread caller,
11796 Intent intent, String resolvedType, IIntentReceiver resultTo,
11797 int resultCode, String resultData, Bundle map,
11798 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011800 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011802 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11803 final int callingPid = Binder.getCallingPid();
11804 final int callingUid = Binder.getCallingUid();
11805 final long origId = Binder.clearCallingIdentity();
11806 int res = broadcastIntentLocked(callerApp,
11807 callerApp != null ? callerApp.info.packageName : null,
11808 intent, resolvedType, resultTo,
11809 resultCode, resultData, map, requiredPermission, serialized,
11810 sticky, callingPid, callingUid);
11811 Binder.restoreCallingIdentity(origId);
11812 return res;
11813 }
11814 }
11815
11816 int broadcastIntentInPackage(String packageName, int uid,
11817 Intent intent, String resolvedType, IIntentReceiver resultTo,
11818 int resultCode, String resultData, Bundle map,
11819 String requiredPermission, boolean serialized, boolean sticky) {
11820 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011821 intent = verifyBroadcastLocked(intent);
11822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011823 final long origId = Binder.clearCallingIdentity();
11824 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11825 resultTo, resultCode, resultData, map, requiredPermission,
11826 serialized, sticky, -1, uid);
11827 Binder.restoreCallingIdentity(origId);
11828 return res;
11829 }
11830 }
11831
11832 public final void unbroadcastIntent(IApplicationThread caller,
11833 Intent intent) {
11834 // Refuse possible leaked file descriptors
11835 if (intent != null && intent.hasFileDescriptors() == true) {
11836 throw new IllegalArgumentException("File descriptors passed in Intent");
11837 }
11838
11839 synchronized(this) {
11840 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11841 != PackageManager.PERMISSION_GRANTED) {
11842 String msg = "Permission Denial: unbroadcastIntent() from pid="
11843 + Binder.getCallingPid()
11844 + ", uid=" + Binder.getCallingUid()
11845 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011846 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011847 throw new SecurityException(msg);
11848 }
11849 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11850 if (list != null) {
11851 int N = list.size();
11852 int i;
11853 for (i=0; i<N; i++) {
11854 if (intent.filterEquals(list.get(i))) {
11855 list.remove(i);
11856 break;
11857 }
11858 }
11859 }
11860 }
11861 }
11862
11863 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11864 String resultData, Bundle resultExtras, boolean resultAbort,
11865 boolean explicit) {
11866 if (mOrderedBroadcasts.size() == 0) {
11867 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011868 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011869 }
11870 return false;
11871 }
11872 BroadcastRecord r = mOrderedBroadcasts.get(0);
11873 if (r.receiver == null) {
11874 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011875 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011876 }
11877 return false;
11878 }
11879 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011880 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011881 return false;
11882 }
11883 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011884 r.state = BroadcastRecord.IDLE;
11885 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011887 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011888 }
11889 }
11890 r.receiver = null;
11891 r.intent.setComponent(null);
11892 if (r.curApp != null) {
11893 r.curApp.curReceiver = null;
11894 }
11895 if (r.curFilter != null) {
11896 r.curFilter.receiverList.curBroadcast = null;
11897 }
11898 r.curFilter = null;
11899 r.curApp = null;
11900 r.curComponent = null;
11901 r.curReceiver = null;
11902 mPendingBroadcast = null;
11903
11904 r.resultCode = resultCode;
11905 r.resultData = resultData;
11906 r.resultExtras = resultExtras;
11907 r.resultAbort = resultAbort;
11908
11909 // We will process the next receiver right now if this is finishing
11910 // an app receiver (which is always asynchronous) or after we have
11911 // come back from calling a receiver.
11912 return state == BroadcastRecord.APP_RECEIVE
11913 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11914 }
11915
11916 public void finishReceiver(IBinder who, int resultCode, String resultData,
11917 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011918 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011919
11920 // Refuse possible leaked file descriptors
11921 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11922 throw new IllegalArgumentException("File descriptors passed in Bundle");
11923 }
11924
11925 boolean doNext;
11926
11927 final long origId = Binder.clearCallingIdentity();
11928
11929 synchronized(this) {
11930 doNext = finishReceiverLocked(
11931 who, resultCode, resultData, resultExtras, resultAbort, true);
11932 }
11933
11934 if (doNext) {
11935 processNextBroadcast(false);
11936 }
11937 trimApplications();
11938
11939 Binder.restoreCallingIdentity(origId);
11940 }
11941
Jeff Brown4d94a762010-09-23 11:33:28 -070011942 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011943 if (r.nextReceiver > 0) {
11944 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11945 if (curReceiver instanceof BroadcastFilter) {
11946 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011947 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011948 System.identityHashCode(r),
11949 r.intent.getAction(),
11950 r.nextReceiver - 1,
11951 System.identityHashCode(bf));
11952 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011953 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954 System.identityHashCode(r),
11955 r.intent.getAction(),
11956 r.nextReceiver - 1,
11957 ((ResolveInfo)curReceiver).toString());
11958 }
11959 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011960 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011961 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011962 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011963 System.identityHashCode(r),
11964 r.intent.getAction(),
11965 r.nextReceiver,
11966 "NONE");
11967 }
11968 }
11969
Jeff Brown4d94a762010-09-23 11:33:28 -070011970 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11971 if (! mPendingBroadcastTimeoutMessage) {
11972 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11973 mHandler.sendMessageAtTime(msg, timeoutTime);
11974 mPendingBroadcastTimeoutMessage = true;
11975 }
11976 }
11977
11978 private final void cancelBroadcastTimeoutLocked() {
11979 if (mPendingBroadcastTimeoutMessage) {
11980 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11981 mPendingBroadcastTimeoutMessage = false;
11982 }
11983 }
11984
11985 private final void broadcastTimeoutLocked(boolean fromMsg) {
11986 if (fromMsg) {
11987 mPendingBroadcastTimeoutMessage = false;
11988 }
11989
11990 if (mOrderedBroadcasts.size() == 0) {
11991 return;
11992 }
11993
11994 long now = SystemClock.uptimeMillis();
11995 BroadcastRecord r = mOrderedBroadcasts.get(0);
11996 if (fromMsg) {
11997 if (mDidDexOpt) {
11998 // Delay timeouts until dexopt finishes.
11999 mDidDexOpt = false;
12000 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12001 setBroadcastTimeoutLocked(timeoutTime);
12002 return;
12003 }
12004 if (! mProcessesReady) {
12005 // Only process broadcast timeouts if the system is ready. That way
12006 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12007 // to do heavy lifting for system up.
12008 return;
12009 }
12010
12011 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12012 if (timeoutTime > now) {
12013 // We can observe premature timeouts because we do not cancel and reset the
12014 // broadcast timeout message after each receiver finishes. Instead, we set up
12015 // an initial timeout then kick it down the road a little further as needed
12016 // when it expires.
12017 if (DEBUG_BROADCAST) Slog.v(TAG,
12018 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12019 + timeoutTime);
12020 setBroadcastTimeoutLocked(timeoutTime);
12021 return;
12022 }
12023 }
12024
12025 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12026 + ", started " + (now - r.receiverTime) + "ms ago");
12027 r.receiverTime = now;
12028 r.anrCount++;
12029
12030 // Current receiver has passed its expiration date.
12031 if (r.nextReceiver <= 0) {
12032 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12033 return;
12034 }
12035
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012036 ProcessRecord app = null;
12037 String anrMessage = null;
12038
Jeff Brown4d94a762010-09-23 11:33:28 -070012039 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12040 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12041 logBroadcastReceiverDiscardLocked(r);
12042 if (curReceiver instanceof BroadcastFilter) {
12043 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12044 if (bf.receiverList.pid != 0
12045 && bf.receiverList.pid != MY_PID) {
12046 synchronized (this.mPidsSelfLocked) {
12047 app = this.mPidsSelfLocked.get(
12048 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012050 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012051 } else {
12052 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012053 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012054
Jeff Brown4d94a762010-09-23 11:33:28 -070012055 if (app != null) {
12056 anrMessage = "Broadcast of " + r.intent.toString();
12057 }
12058
12059 if (mPendingBroadcast == r) {
12060 mPendingBroadcast = null;
12061 }
12062
12063 // Move on to the next receiver.
12064 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12065 r.resultExtras, r.resultAbort, true);
12066 scheduleBroadcastsLocked();
12067
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012068 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012069 // Post the ANR to the handler since we do not want to process ANRs while
12070 // potentially holding our lock.
12071 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012072 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012073 }
12074
12075 private final void processCurBroadcastLocked(BroadcastRecord r,
12076 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012077 if (DEBUG_BROADCAST) Slog.v(TAG,
12078 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012079 if (app.thread == null) {
12080 throw new RemoteException();
12081 }
12082 r.receiver = app.thread.asBinder();
12083 r.curApp = app;
12084 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012085 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012086
12087 // Tell the application to launch this receiver.
12088 r.intent.setComponent(r.curComponent);
12089
12090 boolean started = false;
12091 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012092 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012093 "Delivering to component " + r.curComponent
12094 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012095 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012096 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012097 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012098 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012099 if (DEBUG_BROADCAST) Slog.v(TAG,
12100 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012101 started = true;
12102 } finally {
12103 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012104 if (DEBUG_BROADCAST) Slog.v(TAG,
12105 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012106 r.receiver = null;
12107 r.curApp = null;
12108 app.curReceiver = null;
12109 }
12110 }
12111
12112 }
12113
Jeff Brown4d94a762010-09-23 11:33:28 -070012114 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012115 Intent intent, int resultCode, String data, Bundle extras,
12116 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012117 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118 if (app != null && app.thread != null) {
12119 // If we have an app thread, do the call through that so it is
12120 // correctly ordered with other one-way calls.
12121 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012122 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012123 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012124 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012125 }
12126 }
12127
Jeff Brown4d94a762010-09-23 11:33:28 -070012128 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012129 BroadcastFilter filter, boolean ordered) {
12130 boolean skip = false;
12131 if (filter.requiredPermission != null) {
12132 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012133 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012134 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012135 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012136 + r.intent.toString()
12137 + " from " + r.callerPackage + " (pid="
12138 + r.callingPid + ", uid=" + r.callingUid + ")"
12139 + " requires " + filter.requiredPermission
12140 + " due to registered receiver " + filter);
12141 skip = true;
12142 }
12143 }
12144 if (r.requiredPermission != null) {
12145 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012146 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012147 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012148 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 + r.intent.toString()
12150 + " to " + filter.receiverList.app
12151 + " (pid=" + filter.receiverList.pid
12152 + ", uid=" + filter.receiverList.uid + ")"
12153 + " requires " + r.requiredPermission
12154 + " due to sender " + r.callerPackage
12155 + " (uid " + r.callingUid + ")");
12156 skip = true;
12157 }
12158 }
12159
12160 if (!skip) {
12161 // If this is not being sent as an ordered broadcast, then we
12162 // don't want to touch the fields that keep track of the current
12163 // state of ordered broadcasts.
12164 if (ordered) {
12165 r.receiver = filter.receiverList.receiver.asBinder();
12166 r.curFilter = filter;
12167 filter.receiverList.curBroadcast = r;
12168 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012169 if (filter.receiverList.app != null) {
12170 // Bump hosting application to no longer be in background
12171 // scheduling class. Note that we can't do that if there
12172 // isn't an app... but we can only be in that case for
12173 // things that directly call the IActivityManager API, which
12174 // are already core system stuff so don't matter for this.
12175 r.curApp = filter.receiverList.app;
12176 filter.receiverList.app.curReceiver = r;
12177 updateOomAdjLocked();
12178 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012179 }
12180 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012181 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012182 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012183 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012184 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012185 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012186 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012187 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012188 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012189 if (ordered) {
12190 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12191 }
12192 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012193 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012194 if (ordered) {
12195 r.receiver = null;
12196 r.curFilter = null;
12197 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012198 if (filter.receiverList.app != null) {
12199 filter.receiverList.app.curReceiver = null;
12200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 }
12202 }
12203 }
12204 }
12205
Dianne Hackborn12527f92009-11-11 17:39:50 -080012206 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12207 if (r.callingUid < 0) {
12208 // This was from a registerReceiver() call; ignore it.
12209 return;
12210 }
12211 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12212 MAX_BROADCAST_HISTORY-1);
12213 r.finishTime = SystemClock.uptimeMillis();
12214 mBroadcastHistory[0] = r;
12215 }
12216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012217 private final void processNextBroadcast(boolean fromMsg) {
12218 synchronized(this) {
12219 BroadcastRecord r;
12220
Joe Onorato8a9b2202010-02-26 18:56:32 -080012221 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012222 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012223 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224
12225 updateCpuStats();
12226
12227 if (fromMsg) {
12228 mBroadcastsScheduled = false;
12229 }
12230
12231 // First, deliver any non-serialized broadcasts right away.
12232 while (mParallelBroadcasts.size() > 0) {
12233 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012234 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012235 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012236 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012237 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012238 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012239 for (int i=0; i<N; i++) {
12240 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012241 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012242 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012243 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012244 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012245 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012246 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012247 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012248 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012249 }
12250
12251 // Now take care of the next serialized one...
12252
12253 // If we are waiting for a process to come up to handle the next
12254 // broadcast, then do nothing at this point. Just in case, we
12255 // check that the process we're waiting for still exists.
12256 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012257 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012258 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012259 + mPendingBroadcast.curApp);
12260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012261
12262 boolean isDead;
12263 synchronized (mPidsSelfLocked) {
12264 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12265 }
12266 if (!isDead) {
12267 // It's still alive, so keep waiting
12268 return;
12269 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012270 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012271 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012272 mPendingBroadcast.state = BroadcastRecord.IDLE;
12273 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012274 mPendingBroadcast = null;
12275 }
12276 }
12277
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012278 boolean looped = false;
12279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012280 do {
12281 if (mOrderedBroadcasts.size() == 0) {
12282 // No more broadcasts pending, so all done!
12283 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012284 if (looped) {
12285 // If we had finished the last ordered broadcast, then
12286 // make sure all processes have correct oom and sched
12287 // adjustments.
12288 updateOomAdjLocked();
12289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012290 return;
12291 }
12292 r = mOrderedBroadcasts.get(0);
12293 boolean forceReceive = false;
12294
12295 // Ensure that even if something goes awry with the timeout
12296 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012297 // and continue to make progress.
12298 //
12299 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012300 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012301 // one time heavy lifting after system upgrades and can take
12302 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012303 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012304 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012305 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012306 if ((numReceivers > 0) &&
12307 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012308 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012309 + " now=" + now
12310 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012311 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012312 + " intent=" + r.intent
12313 + " numReceivers=" + numReceivers
12314 + " nextReceiver=" + r.nextReceiver
12315 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012316 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012317 forceReceive = true;
12318 r.state = BroadcastRecord.IDLE;
12319 }
12320 }
12321
12322 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012323 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012324 "processNextBroadcast() called when not idle (state="
12325 + r.state + ")");
12326 return;
12327 }
12328
12329 if (r.receivers == null || r.nextReceiver >= numReceivers
12330 || r.resultAbort || forceReceive) {
12331 // No more receivers for this broadcast! Send the final
12332 // result if requested...
12333 if (r.resultTo != null) {
12334 try {
12335 if (DEBUG_BROADCAST) {
12336 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012337 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 + " seq=" + seq + " app=" + r.callerApp);
12339 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012340 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012342 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012343 // Set this to null so that the reference
12344 // (local and remote) isnt kept in the mBroadcastHistory.
12345 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012346 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012347 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012348 }
12349 }
12350
Joe Onorato8a9b2202010-02-26 18:56:32 -080012351 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012352 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012353
Joe Onorato8a9b2202010-02-26 18:56:32 -080012354 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012355 + r);
12356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012357 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012358 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 mOrderedBroadcasts.remove(0);
12360 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012361 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012362 continue;
12363 }
12364 } while (r == null);
12365
12366 // Get the next receiver...
12367 int recIdx = r.nextReceiver++;
12368
12369 // Keep track of when this receiver started, and make sure there
12370 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012371 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012372 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012373 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012374 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012375 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012376 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012377 }
12378 if (! mPendingBroadcastTimeoutMessage) {
12379 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012380 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012381 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12382 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012383 }
12384
12385 Object nextReceiver = r.receivers.get(recIdx);
12386 if (nextReceiver instanceof BroadcastFilter) {
12387 // Simple case: this is a registered receiver who gets
12388 // a direct call.
12389 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012390 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012391 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012392 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012393 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012394 if (r.receiver == null || !r.ordered) {
12395 // The receiver has already finished, so schedule to
12396 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012397 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12398 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012399 r.state = BroadcastRecord.IDLE;
12400 scheduleBroadcastsLocked();
12401 }
12402 return;
12403 }
12404
12405 // Hard case: need to instantiate the receiver, possibly
12406 // starting its application process to host it.
12407
12408 ResolveInfo info =
12409 (ResolveInfo)nextReceiver;
12410
12411 boolean skip = false;
12412 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012413 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12414 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012415 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012416 if (!info.activityInfo.exported) {
12417 Slog.w(TAG, "Permission Denial: broadcasting "
12418 + r.intent.toString()
12419 + " from " + r.callerPackage + " (pid=" + r.callingPid
12420 + ", uid=" + r.callingUid + ")"
12421 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12422 + " due to receiver " + info.activityInfo.packageName
12423 + "/" + info.activityInfo.name);
12424 } else {
12425 Slog.w(TAG, "Permission Denial: broadcasting "
12426 + r.intent.toString()
12427 + " from " + r.callerPackage + " (pid=" + r.callingPid
12428 + ", uid=" + r.callingUid + ")"
12429 + " requires " + info.activityInfo.permission
12430 + " due to receiver " + info.activityInfo.packageName
12431 + "/" + info.activityInfo.name);
12432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012433 skip = true;
12434 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012435 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012436 r.requiredPermission != null) {
12437 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012438 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012439 checkPermission(r.requiredPermission,
12440 info.activityInfo.applicationInfo.packageName);
12441 } catch (RemoteException e) {
12442 perm = PackageManager.PERMISSION_DENIED;
12443 }
12444 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012445 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012446 + r.intent + " to "
12447 + info.activityInfo.applicationInfo.packageName
12448 + " requires " + r.requiredPermission
12449 + " due to sender " + r.callerPackage
12450 + " (uid " + r.callingUid + ")");
12451 skip = true;
12452 }
12453 }
12454 if (r.curApp != null && r.curApp.crashing) {
12455 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012456 if (DEBUG_BROADCAST) Slog.v(TAG,
12457 "Skipping deliver ordered " + r + " to " + r.curApp
12458 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 skip = true;
12460 }
12461
12462 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012463 if (DEBUG_BROADCAST) Slog.v(TAG,
12464 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012465 r.receiver = null;
12466 r.curFilter = null;
12467 r.state = BroadcastRecord.IDLE;
12468 scheduleBroadcastsLocked();
12469 return;
12470 }
12471
12472 r.state = BroadcastRecord.APP_RECEIVE;
12473 String targetProcess = info.activityInfo.processName;
12474 r.curComponent = new ComponentName(
12475 info.activityInfo.applicationInfo.packageName,
12476 info.activityInfo.name);
12477 r.curReceiver = info.activityInfo;
12478
Dianne Hackborne7f97212011-02-24 14:40:20 -080012479 // Broadcast is being executed, its package can't be stopped.
12480 try {
12481 AppGlobals.getPackageManager().setPackageStoppedState(
12482 r.curComponent.getPackageName(), false);
12483 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012484 } catch (IllegalArgumentException e) {
12485 Slog.w(TAG, "Failed trying to unstop package "
12486 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012487 }
12488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012489 // Is this receiver's application already running?
12490 ProcessRecord app = getProcessRecordLocked(targetProcess,
12491 info.activityInfo.applicationInfo.uid);
12492 if (app != null && app.thread != null) {
12493 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012494 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012495 processCurBroadcastLocked(r, app);
12496 return;
12497 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012498 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012499 + r.curComponent, e);
12500 }
12501
12502 // If a dead object exception was thrown -- fall through to
12503 // restart the application.
12504 }
12505
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012506 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012507 if (DEBUG_BROADCAST) Slog.v(TAG,
12508 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 if ((r.curApp=startProcessLocked(targetProcess,
12510 info.activityInfo.applicationInfo, true,
12511 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012512 "broadcast", r.curComponent,
12513 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12514 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012515 // Ah, this recipient is unavailable. Finish it if necessary,
12516 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012517 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012518 + info.activityInfo.applicationInfo.packageName + "/"
12519 + info.activityInfo.applicationInfo.uid + " for broadcast "
12520 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012521 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012522 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12523 r.resultExtras, r.resultAbort, true);
12524 scheduleBroadcastsLocked();
12525 r.state = BroadcastRecord.IDLE;
12526 return;
12527 }
12528
12529 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012530 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012531 }
12532 }
12533
12534 // =========================================================
12535 // INSTRUMENTATION
12536 // =========================================================
12537
12538 public boolean startInstrumentation(ComponentName className,
12539 String profileFile, int flags, Bundle arguments,
12540 IInstrumentationWatcher watcher) {
12541 // Refuse possible leaked file descriptors
12542 if (arguments != null && arguments.hasFileDescriptors()) {
12543 throw new IllegalArgumentException("File descriptors passed in Bundle");
12544 }
12545
12546 synchronized(this) {
12547 InstrumentationInfo ii = null;
12548 ApplicationInfo ai = null;
12549 try {
12550 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012551 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012552 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012553 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012554 } catch (PackageManager.NameNotFoundException e) {
12555 }
12556 if (ii == null) {
12557 reportStartInstrumentationFailure(watcher, className,
12558 "Unable to find instrumentation info for: " + className);
12559 return false;
12560 }
12561 if (ai == null) {
12562 reportStartInstrumentationFailure(watcher, className,
12563 "Unable to find instrumentation target package: " + ii.targetPackage);
12564 return false;
12565 }
12566
12567 int match = mContext.getPackageManager().checkSignatures(
12568 ii.targetPackage, ii.packageName);
12569 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12570 String msg = "Permission Denial: starting instrumentation "
12571 + className + " from pid="
12572 + Binder.getCallingPid()
12573 + ", uid=" + Binder.getCallingPid()
12574 + " not allowed because package " + ii.packageName
12575 + " does not have a signature matching the target "
12576 + ii.targetPackage;
12577 reportStartInstrumentationFailure(watcher, className, msg);
12578 throw new SecurityException(msg);
12579 }
12580
12581 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012582 // Instrumentation can kill and relaunch even persistent processes
12583 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012584 ProcessRecord app = addAppLocked(ai);
12585 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012586 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012587 app.instrumentationProfileFile = profileFile;
12588 app.instrumentationArguments = arguments;
12589 app.instrumentationWatcher = watcher;
12590 app.instrumentationResultClass = className;
12591 Binder.restoreCallingIdentity(origId);
12592 }
12593
12594 return true;
12595 }
12596
12597 /**
12598 * Report errors that occur while attempting to start Instrumentation. Always writes the
12599 * error to the logs, but if somebody is watching, send the report there too. This enables
12600 * the "am" command to report errors with more information.
12601 *
12602 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12603 * @param cn The component name of the instrumentation.
12604 * @param report The error report.
12605 */
12606 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12607 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012608 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012609 try {
12610 if (watcher != null) {
12611 Bundle results = new Bundle();
12612 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12613 results.putString("Error", report);
12614 watcher.instrumentationStatus(cn, -1, results);
12615 }
12616 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012617 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012618 }
12619 }
12620
12621 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12622 if (app.instrumentationWatcher != null) {
12623 try {
12624 // NOTE: IInstrumentationWatcher *must* be oneway here
12625 app.instrumentationWatcher.instrumentationFinished(
12626 app.instrumentationClass,
12627 resultCode,
12628 results);
12629 } catch (RemoteException e) {
12630 }
12631 }
12632 app.instrumentationWatcher = null;
12633 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012634 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012635 app.instrumentationProfileFile = null;
12636 app.instrumentationArguments = null;
12637
Christopher Tate3dacd842011-08-19 14:56:15 -070012638 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012639 }
12640
12641 public void finishInstrumentation(IApplicationThread target,
12642 int resultCode, Bundle results) {
12643 // Refuse possible leaked file descriptors
12644 if (results != null && results.hasFileDescriptors()) {
12645 throw new IllegalArgumentException("File descriptors passed in Intent");
12646 }
12647
12648 synchronized(this) {
12649 ProcessRecord app = getRecordForAppLocked(target);
12650 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012651 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012652 return;
12653 }
12654 final long origId = Binder.clearCallingIdentity();
12655 finishInstrumentationLocked(app, resultCode, results);
12656 Binder.restoreCallingIdentity(origId);
12657 }
12658 }
12659
12660 // =========================================================
12661 // CONFIGURATION
12662 // =========================================================
12663
12664 public ConfigurationInfo getDeviceConfigurationInfo() {
12665 ConfigurationInfo config = new ConfigurationInfo();
12666 synchronized (this) {
12667 config.reqTouchScreen = mConfiguration.touchscreen;
12668 config.reqKeyboardType = mConfiguration.keyboard;
12669 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012670 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12671 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012672 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12673 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012674 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12675 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012676 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12677 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012678 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012679 }
12680 return config;
12681 }
12682
12683 public Configuration getConfiguration() {
12684 Configuration ci;
12685 synchronized(this) {
12686 ci = new Configuration(mConfiguration);
12687 }
12688 return ci;
12689 }
12690
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012691 public void updatePersistentConfiguration(Configuration values) {
12692 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12693 "updateConfiguration()");
12694 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12695 "updateConfiguration()");
12696 if (values == null) {
12697 throw new NullPointerException("Configuration must not be null");
12698 }
12699
12700 synchronized(this) {
12701 final long origId = Binder.clearCallingIdentity();
12702 updateConfigurationLocked(values, null, true);
12703 Binder.restoreCallingIdentity(origId);
12704 }
12705 }
12706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012707 public void updateConfiguration(Configuration values) {
12708 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12709 "updateConfiguration()");
12710
12711 synchronized(this) {
12712 if (values == null && mWindowManager != null) {
12713 // sentinel: fetch the current configuration from the window manager
12714 values = mWindowManager.computeNewConfiguration();
12715 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012716
12717 if (mWindowManager != null) {
12718 mProcessList.applyDisplaySize(mWindowManager);
12719 }
12720
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012721 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012722 if (values != null) {
12723 Settings.System.clearConfiguration(values);
12724 }
12725 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012726 Binder.restoreCallingIdentity(origId);
12727 }
12728 }
12729
12730 /**
12731 * Do either or both things: (1) change the current configuration, and (2)
12732 * make sure the given activity is running with the (now) current
12733 * configuration. Returns true if the activity has been left running, or
12734 * false if <var>starting</var> is being destroyed to match the new
12735 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012736 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012737 */
12738 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012739 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012740 int changes = 0;
12741
12742 boolean kept = true;
12743
12744 if (values != null) {
12745 Configuration newConfig = new Configuration(mConfiguration);
12746 changes = newConfig.updateFrom(values);
12747 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012748 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012749 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012750 }
12751
Doug Zongker2bec3d42009-12-04 12:52:44 -080012752 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753
12754 if (values.locale != null) {
12755 saveLocaleLocked(values.locale,
12756 !values.locale.equals(mConfiguration.locale),
12757 values.userSetLocale);
12758 }
12759
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012760 mConfigurationSeq++;
12761 if (mConfigurationSeq <= 0) {
12762 mConfigurationSeq = 1;
12763 }
12764 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012765 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012766 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012767
12768 AttributeCache ac = AttributeCache.instance();
12769 if (ac != null) {
12770 ac.updateConfiguration(mConfiguration);
12771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012772
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012773 // Make sure all resources in our process are updated
12774 // right now, so that anyone who is going to retrieve
12775 // resource values after we return will be sure to get
12776 // the new ones. This is especially important during
12777 // boot, where the first config change needs to guarantee
12778 // all resources have that config before following boot
12779 // code is executed.
12780 mSystemThread.applyConfigurationToResources(newConfig);
12781
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012782 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012783 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12784 msg.obj = new Configuration(mConfiguration);
12785 mHandler.sendMessage(msg);
12786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012787
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012788 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12789 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012790 try {
12791 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012792 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012793 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012794 app.thread.scheduleConfigurationChanged(mConfiguration);
12795 }
12796 } catch (Exception e) {
12797 }
12798 }
12799 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012800 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12801 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12803 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012804 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12805 broadcastIntentLocked(null, null,
12806 new Intent(Intent.ACTION_LOCALE_CHANGED),
12807 null, null, 0, null, null,
12808 null, false, false, MY_PID, Process.SYSTEM_UID);
12809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012810 }
12811 }
12812
12813 if (changes != 0 && starting == null) {
12814 // If the configuration changed, and the caller is not already
12815 // in the process of starting an activity, then find the top
12816 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012817 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012818 }
12819
12820 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012821 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012822 // And we need to make sure at this point that all other activities
12823 // are made visible with the correct configuration.
12824 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012825 }
12826
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012827 if (values != null && mWindowManager != null) {
12828 mWindowManager.setNewConfiguration(mConfiguration);
12829 }
12830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012831 return kept;
12832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012833
12834 /**
12835 * Save the locale. You must be inside a synchronized (this) block.
12836 */
12837 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12838 if(isDiff) {
12839 SystemProperties.set("user.language", l.getLanguage());
12840 SystemProperties.set("user.region", l.getCountry());
12841 }
12842
12843 if(isPersist) {
12844 SystemProperties.set("persist.sys.language", l.getLanguage());
12845 SystemProperties.set("persist.sys.country", l.getCountry());
12846 SystemProperties.set("persist.sys.localevar", l.getVariant());
12847 }
12848 }
12849
12850 // =========================================================
12851 // LIFETIME MANAGEMENT
12852 // =========================================================
12853
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012854 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12855 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012856 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012857 // This adjustment has already been computed. If we are calling
12858 // from the top, we may have already computed our adjustment with
12859 // an earlier hidden adjustment that isn't really for us... if
12860 // so, use the new hidden adjustment.
12861 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012862 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012863 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012864 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012865 }
12866
12867 if (app.thread == null) {
12868 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012869 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012870 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012871 }
12872
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012873 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12874 app.adjSource = null;
12875 app.adjTarget = null;
12876 app.empty = false;
12877 app.hidden = false;
12878
12879 final int activitiesSize = app.activities.size();
12880
Dianne Hackborn7d608422011-08-07 16:24:18 -070012881 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012882 // The max adjustment doesn't allow this app to be anything
12883 // below foreground, so it is not worth doing work for it.
12884 app.adjType = "fixed";
12885 app.adjSeq = mAdjSeq;
12886 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012887 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012888 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012889 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012890 // System process can do UI, and when they do we want to have
12891 // them trim their memory after the user leaves the UI. To
12892 // facilitate this, here we need to determine whether or not it
12893 // is currently showing UI.
12894 app.systemNoUi = true;
12895 if (app == TOP_APP) {
12896 app.systemNoUi = false;
12897 } else if (activitiesSize > 0) {
12898 for (int j = 0; j < activitiesSize; j++) {
12899 final ActivityRecord r = app.activities.get(j);
12900 if (r.visible) {
12901 app.systemNoUi = false;
12902 break;
12903 }
12904 }
12905 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012906 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012907 }
12908
12909 final boolean hadForegroundActivities = app.foregroundActivities;
12910
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012911 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012912 app.keeping = false;
12913 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012914
The Android Open Source Project4df24232009-03-05 14:34:35 -080012915 // Determine the importance of the process, starting with most
12916 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012917 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012918 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012919 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012920 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012921 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012922 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012923 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012924 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012925 } else if (app.instrumentationClass != null) {
12926 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012927 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012928 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012929 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012930 } else if (app.curReceiver != null ||
12931 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12932 // An app that is currently receiving a broadcast also
12933 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012934 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012935 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012936 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012937 } else if (app.executingServices.size() > 0) {
12938 // An app that is currently executing a service callback also
12939 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012940 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012941 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012942 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012943 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012944 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012945 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012946 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012947 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012948 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012949 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012950 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012951 // A very not-needed process. If this is lower in the lru list,
12952 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012953 adj = hiddenAdj;
12954 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012955 app.hidden = true;
12956 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012957 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012958 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012959
12960 // Examine all activities if not already foreground.
12961 if (!app.foregroundActivities && activitiesSize > 0) {
12962 for (int j = 0; j < activitiesSize; j++) {
12963 final ActivityRecord r = app.activities.get(j);
12964 if (r.visible) {
12965 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012966 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12967 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012968 app.adjType = "visible";
12969 }
12970 schedGroup = Process.THREAD_GROUP_DEFAULT;
12971 app.hidden = false;
12972 app.foregroundActivities = true;
12973 break;
12974 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12975 || r.state == ActivityState.STOPPING) {
12976 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012977 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12978 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012979 app.adjType = "stopping";
12980 }
12981 app.foregroundActivities = true;
12982 }
12983 }
12984 }
12985
Dianne Hackborn7d608422011-08-07 16:24:18 -070012986 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012987 if (app.foregroundServices) {
12988 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012989 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012990 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012991 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012992 } else if (app.forcingToForeground != null) {
12993 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012994 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012995 app.adjType = "force-foreground";
12996 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012997 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012998 }
12999 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013000
Dianne Hackborn7d608422011-08-07 16:24:18 -070013001 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013002 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013003 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013004 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13005 app.adjType = "heavy";
13006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007
Dianne Hackborn7d608422011-08-07 16:24:18 -070013008 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013009 // This process is hosting what we currently consider to be the
13010 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013011 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013012 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13013 app.adjType = "home";
13014 }
13015
Joe Onorato8a9b2202010-02-26 18:56:32 -080013016 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013017
The Android Open Source Project4df24232009-03-05 14:34:35 -080013018 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013019 // there are applications dependent on our services or providers, but
13020 // this gives us a baseline and makes sure we don't get into an
13021 // infinite recursion.
13022 app.adjSeq = mAdjSeq;
13023 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013024
Christopher Tate6fa95972009-06-05 18:43:55 -070013025 if (mBackupTarget != null && app == mBackupTarget.app) {
13026 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013027 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013028 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013029 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013030 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013031 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013032 }
13033 }
13034
Dianne Hackborn7d608422011-08-07 16:24:18 -070013035 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013036 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013037 final long now = SystemClock.uptimeMillis();
13038 // This process is more important if the top activity is
13039 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013040 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013041 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013042 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013043 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013044 if (app.hasShownUi) {
13045 // If this process has shown some UI, let it immediately
13046 // go to the LRU list because it may be pretty heavy with
13047 // UI stuff. We'll tag it with a label just to help
13048 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013049 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013050 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013051 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013052 } else {
13053 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13054 // This service has seen some activity within
13055 // recent memory, so we will keep its process ahead
13056 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013057 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13058 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013059 app.adjType = "started-services";
13060 app.hidden = false;
13061 }
13062 }
13063 // If we have let the service slide into the background
13064 // state, still have some text describing what it is doing
13065 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013066 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013067 app.adjType = "started-bg-services";
13068 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013069 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013070 // Don't kill this process because it is doing work; it
13071 // has said it is doing work.
13072 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013073 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013074 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013075 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013076 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013077 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013078 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013079 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013080 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013081 // XXX should compute this based on the max of
13082 // all connected clients.
13083 ConnectionRecord cr = clist.get(i);
13084 if (cr.binding.client == app) {
13085 // Binding to ourself is not interesting.
13086 continue;
13087 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013088 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013089 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013090 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013091 int myHiddenAdj = hiddenAdj;
13092 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013093 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013094 myHiddenAdj = client.hiddenAdj;
13095 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013096 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013097 }
13098 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013099 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013100 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013101 String adjType = null;
13102 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13103 // Not doing bind OOM management, so treat
13104 // this guy more like a started service.
13105 if (app.hasShownUi) {
13106 // If this process has shown some UI, let it immediately
13107 // go to the LRU list because it may be pretty heavy with
13108 // UI stuff. We'll tag it with a label just to help
13109 // debug and understand what is going on.
13110 if (adj > clientAdj) {
13111 adjType = "bound-bg-ui-services";
13112 }
13113 clientAdj = adj;
13114 } else {
13115 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13116 // This service has not seen activity within
13117 // recent memory, so allow it to drop to the
13118 // LRU list if there is no other reason to keep
13119 // it around. We'll also tag it with a label just
13120 // to help debug and undertand what is going on.
13121 if (adj > clientAdj) {
13122 adjType = "bound-bg-services";
13123 }
13124 clientAdj = adj;
13125 }
13126 }
13127 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013128 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013129 // If this process has recently shown UI, and
13130 // the process that is binding to it is less
13131 // important than being visible, then we don't
13132 // care about the binding as much as we care
13133 // about letting this process get into the LRU
13134 // list to be killed and restarted if needed for
13135 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013136 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013137 adjType = "bound-bg-ui-services";
13138 } else {
13139 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13140 |Context.BIND_IMPORTANT)) != 0) {
13141 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013142 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013143 adj = clientAdj;
13144 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013145 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013146 }
13147 if (!client.hidden) {
13148 app.hidden = false;
13149 }
13150 if (client.keeping) {
13151 app.keeping = true;
13152 }
13153 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013154 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013155 }
13156 if (adjType != null) {
13157 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013158 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13159 .REASON_SERVICE_IN_USE;
13160 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013161 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013162 app.adjTarget = s.name;
13163 }
13164 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13165 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13166 schedGroup = Process.THREAD_GROUP_DEFAULT;
13167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013168 }
13169 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013170 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13171 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013172 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013173 (a.visible || a.state == ActivityState.RESUMED
13174 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013175 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013176 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13177 schedGroup = Process.THREAD_GROUP_DEFAULT;
13178 }
13179 app.hidden = false;
13180 app.adjType = "service";
13181 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13182 .REASON_SERVICE_IN_USE;
13183 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013184 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013185 app.adjTarget = s.name;
13186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013188 }
13189 }
13190 }
13191 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013192
Dianne Hackborn287952c2010-09-22 22:34:31 -070013193 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013194 // would like to avoid killing it unless it would prevent the current
13195 // application from running. By default we put the process in
13196 // with the rest of the background processes; as we scan through
13197 // its services we may bump it up from there.
13198 if (adj > hiddenAdj) {
13199 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013200 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013201 app.adjType = "bg-services";
13202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013203 }
13204
Dianne Hackborn7d608422011-08-07 16:24:18 -070013205 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013206 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013207 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013208 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013209 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013210 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013211 if (cpr.clients.size() != 0) {
13212 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013213 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013214 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013215 if (client == app) {
13216 // Being our own client is not interesting.
13217 continue;
13218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013219 int myHiddenAdj = hiddenAdj;
13220 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013221 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013222 myHiddenAdj = client.hiddenAdj;
13223 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013224 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013225 }
13226 }
13227 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013228 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013229 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013230 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013231 app.adjType = "bg-ui-provider";
13232 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013233 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13234 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013235 app.adjType = "provider";
13236 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013237 if (!client.hidden) {
13238 app.hidden = false;
13239 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013240 if (client.keeping) {
13241 app.keeping = true;
13242 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013243 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13244 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013245 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013246 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013247 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013248 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013249 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13250 schedGroup = Process.THREAD_GROUP_DEFAULT;
13251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013252 }
13253 }
13254 // If the provider has external (non-framework) process
13255 // dependencies, ensure that its adjustment is at least
13256 // FOREGROUND_APP_ADJ.
13257 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013258 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13259 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013260 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013261 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013262 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013263 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013264 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013265 }
13266 }
13267 }
13268 }
13269
13270 app.curRawAdj = adj;
13271
Joe Onorato8a9b2202010-02-26 18:56:32 -080013272 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013273 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13274 if (adj > app.maxAdj) {
13275 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013276 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013277 schedGroup = Process.THREAD_GROUP_DEFAULT;
13278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013279 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013280 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013281 app.keeping = true;
13282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013283
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013284 if (app.hasAboveClient) {
13285 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13286 // then we need to drop its adjustment to be lower than the service's
13287 // in order to honor the request. We want to drop it by one adjustment
13288 // level... but there is special meaning applied to various levels so
13289 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013290 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013291 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013292 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13293 adj = ProcessList.VISIBLE_APP_ADJ;
13294 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13295 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13296 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13297 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13298 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013299 adj++;
13300 }
13301 }
13302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013303 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013304 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013305
13306 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013307 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13308 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013309 }
13310
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013311 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013312 }
13313
13314 /**
13315 * Ask a given process to GC right now.
13316 */
13317 final void performAppGcLocked(ProcessRecord app) {
13318 try {
13319 app.lastRequestedGc = SystemClock.uptimeMillis();
13320 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013321 if (app.reportLowMemory) {
13322 app.reportLowMemory = false;
13323 app.thread.scheduleLowMemory();
13324 } else {
13325 app.thread.processInBackground();
13326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013327 }
13328 } catch (Exception e) {
13329 // whatever.
13330 }
13331 }
13332
13333 /**
13334 * Returns true if things are idle enough to perform GCs.
13335 */
Josh Bartel7f208742010-02-25 11:01:44 -060013336 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013337 return mParallelBroadcasts.size() == 0
13338 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013339 && (mSleeping || (mMainStack.mResumedActivity != null &&
13340 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 }
13342
13343 /**
13344 * Perform GCs on all processes that are waiting for it, but only
13345 * if things are idle.
13346 */
13347 final void performAppGcsLocked() {
13348 final int N = mProcessesToGc.size();
13349 if (N <= 0) {
13350 return;
13351 }
Josh Bartel7f208742010-02-25 11:01:44 -060013352 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013353 while (mProcessesToGc.size() > 0) {
13354 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013355 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013356 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13357 <= SystemClock.uptimeMillis()) {
13358 // To avoid spamming the system, we will GC processes one
13359 // at a time, waiting a few seconds between each.
13360 performAppGcLocked(proc);
13361 scheduleAppGcsLocked();
13362 return;
13363 } else {
13364 // It hasn't been long enough since we last GCed this
13365 // process... put it in the list to wait for its time.
13366 addProcessToGcListLocked(proc);
13367 break;
13368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013369 }
13370 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013371
13372 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013373 }
13374 }
13375
13376 /**
13377 * If all looks good, perform GCs on all processes waiting for them.
13378 */
13379 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013380 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 performAppGcsLocked();
13382 return;
13383 }
13384 // Still not idle, wait some more.
13385 scheduleAppGcsLocked();
13386 }
13387
13388 /**
13389 * Schedule the execution of all pending app GCs.
13390 */
13391 final void scheduleAppGcsLocked() {
13392 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013393
13394 if (mProcessesToGc.size() > 0) {
13395 // Schedule a GC for the time to the next process.
13396 ProcessRecord proc = mProcessesToGc.get(0);
13397 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13398
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013399 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013400 long now = SystemClock.uptimeMillis();
13401 if (when < (now+GC_TIMEOUT)) {
13402 when = now + GC_TIMEOUT;
13403 }
13404 mHandler.sendMessageAtTime(msg, when);
13405 }
13406 }
13407
13408 /**
13409 * Add a process to the array of processes waiting to be GCed. Keeps the
13410 * list in sorted order by the last GC time. The process can't already be
13411 * on the list.
13412 */
13413 final void addProcessToGcListLocked(ProcessRecord proc) {
13414 boolean added = false;
13415 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13416 if (mProcessesToGc.get(i).lastRequestedGc <
13417 proc.lastRequestedGc) {
13418 added = true;
13419 mProcessesToGc.add(i+1, proc);
13420 break;
13421 }
13422 }
13423 if (!added) {
13424 mProcessesToGc.add(0, proc);
13425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013426 }
13427
13428 /**
13429 * Set up to ask a process to GC itself. This will either do it
13430 * immediately, or put it on the list of processes to gc the next
13431 * time things are idle.
13432 */
13433 final void scheduleAppGcLocked(ProcessRecord app) {
13434 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013435 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013436 return;
13437 }
13438 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013439 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013440 scheduleAppGcsLocked();
13441 }
13442 }
13443
Dianne Hackborn287952c2010-09-22 22:34:31 -070013444 final void checkExcessivePowerUsageLocked(boolean doKills) {
13445 updateCpuStatsNow();
13446
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013447 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013448 boolean doWakeKills = doKills;
13449 boolean doCpuKills = doKills;
13450 if (mLastPowerCheckRealtime == 0) {
13451 doWakeKills = false;
13452 }
13453 if (mLastPowerCheckUptime == 0) {
13454 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013455 }
13456 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013457 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013458 }
13459 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013460 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13461 final long curUptime = SystemClock.uptimeMillis();
13462 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13463 mLastPowerCheckRealtime = curRealtime;
13464 mLastPowerCheckUptime = curUptime;
13465 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13466 doWakeKills = false;
13467 }
13468 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13469 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013470 }
13471 int i = mLruProcesses.size();
13472 while (i > 0) {
13473 i--;
13474 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013475 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013476 long wtime;
13477 synchronized (stats) {
13478 wtime = stats.getProcessWakeTime(app.info.uid,
13479 app.pid, curRealtime);
13480 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013481 long wtimeUsed = wtime - app.lastWakeTime;
13482 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13483 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013484 StringBuilder sb = new StringBuilder(128);
13485 sb.append("Wake for ");
13486 app.toShortString(sb);
13487 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013488 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013489 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013490 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013491 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013492 sb.append((wtimeUsed*100)/realtimeSince);
13493 sb.append("%)");
13494 Slog.i(TAG, sb.toString());
13495 sb.setLength(0);
13496 sb.append("CPU for ");
13497 app.toShortString(sb);
13498 sb.append(": over ");
13499 TimeUtils.formatDuration(uptimeSince, sb);
13500 sb.append(" used ");
13501 TimeUtils.formatDuration(cputimeUsed, sb);
13502 sb.append(" (");
13503 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013504 sb.append("%)");
13505 Slog.i(TAG, sb.toString());
13506 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013507 // If a process has held a wake lock for more
13508 // than 50% of the time during this period,
13509 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013510 if (doWakeKills && realtimeSince > 0
13511 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13512 synchronized (stats) {
13513 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13514 realtimeSince, wtimeUsed);
13515 }
13516 Slog.w(TAG, "Excessive wake lock in " + app.processName
13517 + " (pid " + app.pid + "): held " + wtimeUsed
13518 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013519 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13520 app.processName, app.setAdj, "excessive wake lock");
13521 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013522 } else if (doCpuKills && uptimeSince > 0
13523 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13524 synchronized (stats) {
13525 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13526 uptimeSince, cputimeUsed);
13527 }
13528 Slog.w(TAG, "Excessive CPU in " + app.processName
13529 + " (pid " + app.pid + "): used " + cputimeUsed
13530 + " during " + uptimeSince);
13531 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13532 app.processName, app.setAdj, "excessive cpu");
13533 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013534 } else {
13535 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013536 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013537 }
13538 }
13539 }
13540 }
13541
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013542 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013543 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013544 app.hiddenAdj = hiddenAdj;
13545
13546 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013547 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013548 }
13549
Dianne Hackborn287952c2010-09-22 22:34:31 -070013550 final boolean wasKeeping = app.keeping;
13551
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013552 boolean success = true;
13553
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013554 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013555
Jeff Brown10e89712011-07-08 18:52:57 -070013556 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013557 if (false) {
13558 // Removing for now. Forcing GCs is not so useful anymore
13559 // with Dalvik, and the new memory level hint facility is
13560 // better for what we need to do these days.
13561 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13562 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13563 // If this app is transitioning from foreground to
13564 // non-foreground, have it do a gc.
13565 scheduleAppGcLocked(app);
13566 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13567 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13568 // Likewise do a gc when an app is moving in to the
13569 // background (such as a service stopping).
13570 scheduleAppGcLocked(app);
13571 }
Jeff Brown10e89712011-07-08 18:52:57 -070013572 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013573
Jeff Brown10e89712011-07-08 18:52:57 -070013574 if (wasKeeping && !app.keeping) {
13575 // This app is no longer something we want to keep. Note
13576 // its current wake lock time to later know to kill it if
13577 // it is not behaving well.
13578 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13579 synchronized (stats) {
13580 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13581 app.pid, SystemClock.elapsedRealtime());
13582 }
13583 app.lastCpuTime = app.curCpuTime;
13584 }
13585
13586 app.setRawAdj = app.curRawAdj;
13587 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013588 if (app.curAdj != app.setAdj) {
13589 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013590 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13591 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013592 " oom adj to " + app.curAdj + " because " + app.adjType);
13593 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013594 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013595 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013596 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013597 }
13598 }
13599 if (app.setSchedGroup != app.curSchedGroup) {
13600 app.setSchedGroup = app.curSchedGroup;
13601 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13602 "Setting process group of " + app.processName
13603 + " to " + app.curSchedGroup);
13604 if (app.waitingToKill != null &&
13605 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13606 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13607 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13608 app.processName, app.setAdj, app.waitingToKill);
13609 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013610 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013611 } else {
13612 if (true) {
13613 long oldId = Binder.clearCallingIdentity();
13614 try {
13615 Process.setProcessGroup(app.pid, app.curSchedGroup);
13616 } catch (Exception e) {
13617 Slog.w(TAG, "Failed setting process group of " + app.pid
13618 + " to " + app.curSchedGroup);
13619 e.printStackTrace();
13620 } finally {
13621 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013622 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013623 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013624 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013625 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013626 app.thread.setSchedulingGroup(app.curSchedGroup);
13627 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013628 }
13629 }
13630 }
13631 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013632 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013633 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013634 }
13635
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013636 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013637 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013638 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013639 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013640 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013641 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013642 }
13643 }
13644 return resumedActivity;
13645 }
13646
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013647 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013648 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013649 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13650 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013651 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13652 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013653
13654 mAdjSeq++;
13655
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013656 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013657 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13658 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013659 if (nowHidden != wasHidden) {
13660 // Changed to/from hidden state, so apps after it in the LRU
13661 // list may also be changed.
13662 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013663 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013664 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013665 }
13666
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013667 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013668 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013669 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13670
13671 if (false) {
13672 RuntimeException e = new RuntimeException();
13673 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013674 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013675 }
13676
13677 mAdjSeq++;
13678
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013679 // Let's determine how many processes we have running vs.
13680 // how many slots we have for background processes; we may want
13681 // to put multiple processes in a slot of there are enough of
13682 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013683 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013684 int factor = (mLruProcesses.size()-4)/numSlots;
13685 if (factor < 1) factor = 1;
13686 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013687 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013688
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013689 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013690 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013691 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013692 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013693 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013694 while (i > 0) {
13695 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013696 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013697 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013698 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013699 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013700 && app.curAdj == curHiddenAdj) {
13701 step++;
13702 if (step >= factor) {
13703 step = 0;
13704 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013705 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013706 }
13707 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013708 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013709 numHidden++;
13710 if (numHidden > mProcessLimit) {
13711 Slog.i(TAG, "No longer want " + app.processName
13712 + " (pid " + app.pid + "): hidden #" + numHidden);
13713 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13714 app.processName, app.setAdj, "too many background");
13715 app.killedBackground = true;
13716 Process.killProcessQuiet(app.pid);
13717 } else {
13718 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013719 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013720 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013721 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013723 }
13724 }
13725
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013726 // Now determine the memory trimming level of background processes.
13727 // Unfortunately we need to start at the back of the list to do this
13728 // properly. We only do this if the number of background apps we
13729 // are managing to keep around is less than half the maximum we desire;
13730 // if we are keeping a good number around, we'll let them use whatever
13731 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013732 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013733 final int N = mLruProcesses.size();
13734 factor = numBg/3;
13735 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013736 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013737 for (i=0; i<N; i++) {
13738 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013739 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013740 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13741 try {
13742 app.thread.scheduleTrimMemory(curLevel);
13743 } catch (RemoteException e) {
13744 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013745 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013746 // For these apps we will also finish their activities
13747 // to help them free memory.
13748 mMainStack.destroyActivitiesLocked(app, false);
13749 }
13750 }
13751 app.trimMemoryLevel = curLevel;
13752 step++;
13753 if (step >= factor) {
13754 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013755 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13756 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013757 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013758 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13759 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013760 break;
13761 }
13762 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013763 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013764 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013765 && app.thread != null) {
13766 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013767 app.thread.scheduleTrimMemory(
13768 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013769 } catch (RemoteException e) {
13770 }
13771 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013772 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013773 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013774 && app.pendingUiClean) {
13775 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13776 && app.thread != null) {
13777 try {
13778 app.thread.scheduleTrimMemory(
13779 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13780 } catch (RemoteException e) {
13781 }
13782 }
13783 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13784 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013785 } else {
13786 app.trimMemoryLevel = 0;
13787 }
13788 }
13789 } else {
13790 final int N = mLruProcesses.size();
13791 for (i=0; i<N; i++) {
13792 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013793 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013794 && app.pendingUiClean) {
13795 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13796 && app.thread != null) {
13797 try {
13798 app.thread.scheduleTrimMemory(
13799 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13800 } catch (RemoteException e) {
13801 }
13802 }
13803 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13804 app.pendingUiClean = false;
13805 } else {
13806 app.trimMemoryLevel = 0;
13807 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013808 }
13809 }
13810
13811 if (mAlwaysFinishActivities) {
13812 mMainStack.destroyActivitiesLocked(null, false);
13813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013814 }
13815
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013816 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013817 synchronized (this) {
13818 int i;
13819
13820 // First remove any unused application processes whose package
13821 // has been removed.
13822 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13823 final ProcessRecord app = mRemovedProcesses.get(i);
13824 if (app.activities.size() == 0
13825 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013826 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013827 TAG, "Exiting empty application process "
13828 + app.processName + " ("
13829 + (app.thread != null ? app.thread.asBinder() : null)
13830 + ")\n");
13831 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013832 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13833 app.processName, app.setAdj, "empty");
13834 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013835 } else {
13836 try {
13837 app.thread.scheduleExit();
13838 } catch (Exception e) {
13839 // Ignore exceptions.
13840 }
13841 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013842 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013843 mRemovedProcesses.remove(i);
13844
13845 if (app.persistent) {
13846 if (app.persistent) {
13847 addAppLocked(app.info);
13848 }
13849 }
13850 }
13851 }
13852
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013853 // Now update the oom adj for all processes.
13854 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013855 }
13856 }
13857
13858 /** This method sends the specified signal to each of the persistent apps */
13859 public void signalPersistentProcesses(int sig) throws RemoteException {
13860 if (sig != Process.SIGNAL_USR1) {
13861 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13862 }
13863
13864 synchronized (this) {
13865 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13866 != PackageManager.PERMISSION_GRANTED) {
13867 throw new SecurityException("Requires permission "
13868 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13869 }
13870
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013871 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13872 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013873 if (r.thread != null && r.persistent) {
13874 Process.sendSignal(r.pid, sig);
13875 }
13876 }
13877 }
13878 }
13879
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013880 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13881 if (proc == null || proc == mProfileProc) {
13882 proc = mProfileProc;
13883 path = mProfileFile;
13884 profileType = mProfileType;
13885 clearProfilerLocked();
13886 }
13887 if (proc == null) {
13888 return;
13889 }
13890 try {
13891 proc.thread.profilerControl(false, path, null, profileType);
13892 } catch (RemoteException e) {
13893 throw new IllegalStateException("Process disappeared");
13894 }
13895 }
13896
13897 private void clearProfilerLocked() {
13898 if (mProfileFd != null) {
13899 try {
13900 mProfileFd.close();
13901 } catch (IOException e) {
13902 }
13903 }
13904 mProfileApp = null;
13905 mProfileProc = null;
13906 mProfileFile = null;
13907 mProfileType = 0;
13908 mAutoStopProfiler = false;
13909 }
13910
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013911 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013912 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013913
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013914 try {
13915 synchronized (this) {
13916 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13917 // its own permission.
13918 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13919 != PackageManager.PERMISSION_GRANTED) {
13920 throw new SecurityException("Requires permission "
13921 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013922 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013923
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013924 if (start && fd == null) {
13925 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013926 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013927
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013928 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013929 if (process != null) {
13930 try {
13931 int pid = Integer.parseInt(process);
13932 synchronized (mPidsSelfLocked) {
13933 proc = mPidsSelfLocked.get(pid);
13934 }
13935 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013936 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013937
13938 if (proc == null) {
13939 HashMap<String, SparseArray<ProcessRecord>> all
13940 = mProcessNames.getMap();
13941 SparseArray<ProcessRecord> procs = all.get(process);
13942 if (procs != null && procs.size() > 0) {
13943 proc = procs.valueAt(0);
13944 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013945 }
13946 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013947
13948 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013949 throw new IllegalArgumentException("Unknown process: " + process);
13950 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013951
13952 if (start) {
13953 stopProfilerLocked(null, null, 0);
13954 setProfileApp(proc.info, proc.processName, path, fd, false);
13955 mProfileProc = proc;
13956 mProfileType = profileType;
13957 try {
13958 fd = fd.dup();
13959 } catch (IOException e) {
13960 fd = null;
13961 }
13962 proc.thread.profilerControl(start, path, fd, profileType);
13963 fd = null;
13964 mProfileFd = null;
13965 } else {
13966 stopProfilerLocked(proc, path, profileType);
13967 if (fd != null) {
13968 try {
13969 fd.close();
13970 } catch (IOException e) {
13971 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013972 }
13973 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013974
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013975 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013976 }
13977 } catch (RemoteException e) {
13978 throw new IllegalStateException("Process disappeared");
13979 } finally {
13980 if (fd != null) {
13981 try {
13982 fd.close();
13983 } catch (IOException e) {
13984 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013985 }
13986 }
13987 }
Andy McFadden824c5102010-07-09 16:26:57 -070013988
13989 public boolean dumpHeap(String process, boolean managed,
13990 String path, ParcelFileDescriptor fd) throws RemoteException {
13991
13992 try {
13993 synchronized (this) {
13994 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13995 // its own permission (same as profileControl).
13996 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13997 != PackageManager.PERMISSION_GRANTED) {
13998 throw new SecurityException("Requires permission "
13999 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14000 }
14001
14002 if (fd == null) {
14003 throw new IllegalArgumentException("null fd");
14004 }
14005
14006 ProcessRecord proc = null;
14007 try {
14008 int pid = Integer.parseInt(process);
14009 synchronized (mPidsSelfLocked) {
14010 proc = mPidsSelfLocked.get(pid);
14011 }
14012 } catch (NumberFormatException e) {
14013 }
14014
14015 if (proc == null) {
14016 HashMap<String, SparseArray<ProcessRecord>> all
14017 = mProcessNames.getMap();
14018 SparseArray<ProcessRecord> procs = all.get(process);
14019 if (procs != null && procs.size() > 0) {
14020 proc = procs.valueAt(0);
14021 }
14022 }
14023
14024 if (proc == null || proc.thread == null) {
14025 throw new IllegalArgumentException("Unknown process: " + process);
14026 }
14027
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014028 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14029 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014030 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14031 throw new SecurityException("Process not debuggable: " + proc);
14032 }
14033 }
14034
14035 proc.thread.dumpHeap(managed, path, fd);
14036 fd = null;
14037 return true;
14038 }
14039 } catch (RemoteException e) {
14040 throw new IllegalStateException("Process disappeared");
14041 } finally {
14042 if (fd != null) {
14043 try {
14044 fd.close();
14045 } catch (IOException e) {
14046 }
14047 }
14048 }
14049 }
14050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014051 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14052 public void monitor() {
14053 synchronized (this) { }
14054 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014055
14056 public void onCoreSettingsChange(Bundle settings) {
14057 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14058 ProcessRecord processRecord = mLruProcesses.get(i);
14059 try {
14060 if (processRecord.thread != null) {
14061 processRecord.thread.setCoreSettings(settings);
14062 }
14063 } catch (RemoteException re) {
14064 /* ignore */
14065 }
14066 }
14067 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014068
14069 // Multi-user methods
14070
14071 public boolean switchUser(int userid) {
14072 // TODO
14073 return true;
14074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014075}