blob: d038d767828d15dc9c398f3766220c83f9d5bf19 [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) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001321 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1322 != PackageManager.PERMISSION_GRANTED) {
1323 pw.println("Permission Denial: can't dump meminfo from from pid="
1324 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1325 + " without permission " + android.Manifest.permission.DUMP);
1326 return;
1327 }
1328
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001329 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 }
1331 }
1332
Chet Haase9c1e23b2011-03-24 10:51:31 -07001333 static class GraphicsBinder extends Binder {
1334 ActivityManagerService mActivityManagerService;
1335 GraphicsBinder(ActivityManagerService activityManagerService) {
1336 mActivityManagerService = activityManagerService;
1337 }
1338
1339 @Override
1340 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001341 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1342 != PackageManager.PERMISSION_GRANTED) {
1343 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1344 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1345 + " without permission " + android.Manifest.permission.DUMP);
1346 return;
1347 }
1348
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001349 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001350 }
1351 }
1352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 static class CpuBinder extends Binder {
1354 ActivityManagerService mActivityManagerService;
1355 CpuBinder(ActivityManagerService activityManagerService) {
1356 mActivityManagerService = activityManagerService;
1357 }
1358
1359 @Override
1360 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001361 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1362 != PackageManager.PERMISSION_GRANTED) {
1363 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1364 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1365 + " without permission " + android.Manifest.permission.DUMP);
1366 return;
1367 }
1368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001370 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1371 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1372 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 }
1374 }
1375 }
1376
1377 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001378 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 File dataDir = Environment.getDataDirectory();
1381 File systemDir = new File(dataDir, "system");
1382 systemDir.mkdirs();
1383 mBatteryStatsService = new BatteryStatsService(new File(
1384 systemDir, "batterystats.bin").toString());
1385 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001386 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001387 mOnBattery = DEBUG_POWER ? true
1388 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001389 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001391 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001392 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393
Jack Palevichb90d28c2009-07-22 15:35:24 -07001394 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1395 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1396
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001397 mConfiguration.setToDefaults();
1398 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 mProcessStats.init();
1400
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001401 mCompatModePackages = new CompatModePackages(this, systemDir);
1402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 // Add ourself to the Watchdog monitors.
1404 Watchdog.getInstance().addMonitor(this);
1405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 mProcessStatsThread = new Thread("ProcessStats") {
1407 public void run() {
1408 while (true) {
1409 try {
1410 try {
1411 synchronized(this) {
1412 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001413 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 // + ", write delay=" + nextWriteDelay);
1417 if (nextWriteDelay < nextCpuDelay) {
1418 nextCpuDelay = nextWriteDelay;
1419 }
1420 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001421 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 this.wait(nextCpuDelay);
1423 }
1424 }
1425 } catch (InterruptedException e) {
1426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 updateCpuStatsNow();
1428 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001429 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 }
1431 }
1432 }
1433 };
1434 mProcessStatsThread.start();
1435 }
1436
1437 @Override
1438 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1439 throws RemoteException {
1440 try {
1441 return super.onTransact(code, data, reply, flags);
1442 } catch (RuntimeException e) {
1443 // The activity manager only throws security exceptions, so let's
1444 // log all others.
1445 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001446 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 }
1448 throw e;
1449 }
1450 }
1451
1452 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001453 final long now = SystemClock.uptimeMillis();
1454 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1455 return;
1456 }
1457 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1458 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 mProcessStatsThread.notify();
1460 }
1461 }
1462 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 void updateCpuStatsNow() {
1465 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001466 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 final long now = SystemClock.uptimeMillis();
1468 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001471 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1472 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 haveNewCpuStats = true;
1474 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 //Slog.i(TAG, mProcessStats.printCurrentState());
1476 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 // + mProcessStats.getTotalCpuPercent() + "%");
1478
Joe Onorato8a9b2202010-02-26 18:56:32 -08001479 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if ("true".equals(SystemProperties.get("events.cpu"))) {
1481 int user = mProcessStats.getLastUserTime();
1482 int system = mProcessStats.getLastSystemTime();
1483 int iowait = mProcessStats.getLastIoWaitTime();
1484 int irq = mProcessStats.getLastIrqTime();
1485 int softIrq = mProcessStats.getLastSoftIrqTime();
1486 int idle = mProcessStats.getLastIdleTime();
1487
1488 int total = user + system + iowait + irq + softIrq + idle;
1489 if (total == 0) total = 1;
1490
Doug Zongker2bec3d42009-12-04 12:52:44 -08001491 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ((user+system+iowait+irq+softIrq) * 100) / total,
1493 (user * 100) / total,
1494 (system * 100) / total,
1495 (iowait * 100) / total,
1496 (irq * 100) / total,
1497 (softIrq * 100) / total);
1498 }
1499 }
1500
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001502 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 synchronized(mPidsSelfLocked) {
1505 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001506 if (mOnBattery) {
1507 int perc = bstats.startAddingCpuLocked();
1508 int totalUTime = 0;
1509 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001510 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001512 ProcessStats.Stats st = mProcessStats.getStats(i);
1513 if (!st.working) {
1514 continue;
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001517 int otherUTime = (st.rel_utime*perc)/100;
1518 int otherSTime = (st.rel_stime*perc)/100;
1519 totalUTime += otherUTime;
1520 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 if (pr != null) {
1522 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001523 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1524 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001525 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001526 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001527 } else {
1528 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001529 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001530 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001531 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1532 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001533 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 }
1536 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001537 bstats.finishAddingCpuLocked(perc, totalUTime,
1538 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 }
1540 }
1541 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1544 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001545 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547 }
1548 }
1549 }
1550
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001551 @Override
1552 public void batteryNeedsCpuUpdate() {
1553 updateCpuStatsNow();
1554 }
1555
1556 @Override
1557 public void batteryPowerChanged(boolean onBattery) {
1558 // When plugging in, update the CPU stats first before changing
1559 // the plug state.
1560 updateCpuStatsNow();
1561 synchronized (this) {
1562 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001563 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001564 }
1565 }
1566 }
1567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 /**
1569 * Initialize the application bind args. These are passed to each
1570 * process when the bindApplication() IPC is sent to the process. They're
1571 * lazily setup to make sure the services are running when they're asked for.
1572 */
1573 private HashMap<String, IBinder> getCommonServicesLocked() {
1574 if (mAppBindArgs == null) {
1575 mAppBindArgs = new HashMap<String, IBinder>();
1576
1577 // Setup the application init args
1578 mAppBindArgs.put("package", ServiceManager.getService("package"));
1579 mAppBindArgs.put("window", ServiceManager.getService("window"));
1580 mAppBindArgs.put(Context.ALARM_SERVICE,
1581 ServiceManager.getService(Context.ALARM_SERVICE));
1582 }
1583 return mAppBindArgs;
1584 }
1585
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001586 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 if (mFocusedActivity != r) {
1588 mFocusedActivity = r;
1589 mWindowManager.setFocusedApp(r, true);
1590 }
1591 }
1592
Dianne Hackborn906497c2010-05-10 15:57:38 -07001593 private final void updateLruProcessInternalLocked(ProcessRecord app,
1594 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001596 int lrui = mLruProcesses.indexOf(app);
1597 if (lrui >= 0) mLruProcesses.remove(lrui);
1598
1599 int i = mLruProcesses.size()-1;
1600 int skipTop = 0;
1601
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602 app.lruSeq = mLruSeq;
1603
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001604 // compute the new weight for this process.
1605 if (updateActivityTime) {
1606 app.lastActivityTime = SystemClock.uptimeMillis();
1607 }
1608 if (app.activities.size() > 0) {
1609 // If this process has activities, we more strongly want to keep
1610 // it around.
1611 app.lruWeight = app.lastActivityTime;
1612 } else if (app.pubProviders.size() > 0) {
1613 // If this process contains content providers, we want to keep
1614 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001615 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001616 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001617 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001618 } else {
1619 // If this process doesn't have activities, we less strongly
1620 // want to keep it around, and generally want to avoid getting
1621 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001622 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001623 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001624 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001625 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001626
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001627 while (i >= 0) {
1628 ProcessRecord p = mLruProcesses.get(i);
1629 // If this app shouldn't be in front of the first N background
1630 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001631 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001632 skipTop--;
1633 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001634 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001635 mLruProcesses.add(i+1, app);
1636 break;
1637 }
1638 i--;
1639 }
1640 if (i < 0) {
1641 mLruProcesses.add(0, app);
1642 }
1643
Dianne Hackborn906497c2010-05-10 15:57:38 -07001644 // If the app is currently using a content provider or service,
1645 // bump those processes as well.
1646 if (app.connections.size() > 0) {
1647 for (ConnectionRecord cr : app.connections) {
1648 if (cr.binding != null && cr.binding.service != null
1649 && cr.binding.service.app != null
1650 && cr.binding.service.app.lruSeq != mLruSeq) {
1651 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1652 updateActivityTime, i+1);
1653 }
1654 }
1655 }
1656 if (app.conProviders.size() > 0) {
1657 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1659 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001660 updateActivityTime, i+1);
1661 }
1662 }
1663 }
1664
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 if (oomAdj) {
1667 updateOomAdjLocked();
1668 }
1669 }
1670
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001671 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001672 boolean oomAdj, boolean updateActivityTime) {
1673 mLruSeq++;
1674 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1675 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 String processName, int uid) {
1679 if (uid == Process.SYSTEM_UID) {
1680 // The system gets to run in any process. If there are multiple
1681 // processes with the same uid, just pick the first (this
1682 // should never happen).
1683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1684 processName);
1685 return procs != null ? procs.valueAt(0) : null;
1686 }
1687 ProcessRecord proc = mProcessNames.get(processName, uid);
1688 return proc;
1689 }
1690
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001691 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001692 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001693 try {
1694 if (pm.performDexOpt(packageName)) {
1695 mDidDexOpt = true;
1696 }
1697 } catch (RemoteException e) {
1698 }
1699 }
1700
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001701 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 int transit = mWindowManager.getPendingAppTransition();
1703 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1704 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1705 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1706 }
1707
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001708 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001710 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1712 // We don't have to do anything more if:
1713 // (1) There is an existing application record; and
1714 // (2) The caller doesn't think it is dead, OR there is no thread
1715 // object attached to it so we know it couldn't have crashed; and
1716 // (3) There is a pid assigned to it, so it is either starting or
1717 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001718 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 + " app=" + app + " knownToBeDead=" + knownToBeDead
1720 + " thread=" + (app != null ? app.thread : null)
1721 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001722 if (app != null && app.pid > 0) {
1723 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001724 // We already have the app running, or are waiting for it to
1725 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001726 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001727 // If this is a new package in the process, add the package to the list
1728 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001729 return app;
1730 } else {
1731 // An application record is attached to a previous process,
1732 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001733 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001734 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001738 String hostingNameStr = hostingName != null
1739 ? hostingName.flattenToShortString() : null;
1740
1741 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1742 // If we are in the background, then check to see if this process
1743 // is bad. If so, we will just silently fail.
1744 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001745 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1746 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 return null;
1748 }
1749 } else {
1750 // When the user is explicitly starting a process, then clear its
1751 // crash count so that we won't make it bad until they see at
1752 // least one crash dialog again, and make the process good again
1753 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001754 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1755 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 mProcessCrashTimes.remove(info.processName, info.uid);
1757 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001758 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 info.processName);
1760 mBadProcesses.remove(info.processName, info.uid);
1761 if (app != null) {
1762 app.bad = false;
1763 }
1764 }
1765 }
1766
1767 if (app == null) {
1768 app = newProcessRecordLocked(null, info, processName);
1769 mProcessNames.put(processName, info.uid, app);
1770 } else {
1771 // If this is a new package in the process, add the package to the list
1772 app.addPackage(info.packageName);
1773 }
1774
1775 // If the system is not ready yet, then hold off on starting this
1776 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001777 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001778 && !isAllowedWhileBooting(info)
1779 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 if (!mProcessesOnHold.contains(app)) {
1781 mProcessesOnHold.add(app);
1782 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001783 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 return app;
1785 }
1786
1787 startProcessLocked(app, hostingType, hostingNameStr);
1788 return (app.pid != 0) ? app : null;
1789 }
1790
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001791 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1792 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1793 }
1794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 private final void startProcessLocked(ProcessRecord app,
1796 String hostingType, String hostingNameStr) {
1797 if (app.pid > 0 && app.pid != MY_PID) {
1798 synchronized (mPidsSelfLocked) {
1799 mPidsSelfLocked.remove(app.pid);
1800 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1801 }
1802 app.pid = 0;
1803 }
1804
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001805 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1806 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 mProcessesOnHold.remove(app);
1808
1809 updateCpuStats();
1810
1811 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1812 mProcDeaths[0] = 0;
1813
1814 try {
1815 int uid = app.info.uid;
1816 int[] gids = null;
1817 try {
1818 gids = mContext.getPackageManager().getPackageGids(
1819 app.info.packageName);
1820 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001821 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 }
1823 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1824 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1825 && mTopComponent != null
1826 && app.processName.equals(mTopComponent.getPackageName())) {
1827 uid = 0;
1828 }
1829 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1830 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1831 uid = 0;
1832 }
1833 }
1834 int debugFlags = 0;
1835 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1836 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001837 // Also turn on CheckJNI for debuggable apps. It's quite
1838 // awkward to turn on otherwise.
1839 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001841 // Run the app in safe mode if its manifest requests so or the
1842 // system is booted in safe mode.
1843 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1844 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001845 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1848 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1849 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001850 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1851 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 if ("1".equals(SystemProperties.get("debug.assert"))) {
1854 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1855 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001856
1857 // Start the process. It will either succeed and return a result containing
1858 // the PID of the new process, or else throw a RuntimeException.
1859 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001860 app.processName, uid, uid, gids, debugFlags,
1861 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1864 synchronized (bs) {
1865 if (bs.isOnBattery()) {
1866 app.batteryStats.incStartsLocked();
1867 }
1868 }
1869
Jeff Brown3f9dd282011-07-08 20:02:19 -07001870 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 app.processName, hostingType,
1872 hostingNameStr != null ? hostingNameStr : "");
1873
1874 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001875 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 }
1877
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001878 StringBuilder buf = mStringBuilder;
1879 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 buf.append("Start proc ");
1881 buf.append(app.processName);
1882 buf.append(" for ");
1883 buf.append(hostingType);
1884 if (hostingNameStr != null) {
1885 buf.append(" ");
1886 buf.append(hostingNameStr);
1887 }
1888 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001889 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 buf.append(" uid=");
1891 buf.append(uid);
1892 buf.append(" gids={");
1893 if (gids != null) {
1894 for (int gi=0; gi<gids.length; gi++) {
1895 if (gi != 0) buf.append(", ");
1896 buf.append(gids[gi]);
1897
1898 }
1899 }
1900 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001901 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001902 app.pid = startResult.pid;
1903 app.usingWrapper = startResult.usingWrapper;
1904 app.removed = false;
1905 synchronized (mPidsSelfLocked) {
1906 this.mPidsSelfLocked.put(startResult.pid, app);
1907 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1908 msg.obj = app;
1909 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1910 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 }
1912 } catch (RuntimeException e) {
1913 // XXX do better error recovery.
1914 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001915 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 }
1917 }
1918
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001919 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 if (resumed) {
1921 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1922 } else {
1923 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1924 }
1925 }
1926
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001927 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001928 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1929 && mTopAction == null) {
1930 // We are running in factory test mode, but unable to find
1931 // the factory test app, so just sit around displaying the
1932 // error message and don't try to start anything.
1933 return false;
1934 }
1935 Intent intent = new Intent(
1936 mTopAction,
1937 mTopData != null ? Uri.parse(mTopData) : null);
1938 intent.setComponent(mTopComponent);
1939 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1940 intent.addCategory(Intent.CATEGORY_HOME);
1941 }
1942 ActivityInfo aInfo =
1943 intent.resolveActivityInfo(mContext.getPackageManager(),
1944 STOCK_PM_FLAGS);
1945 if (aInfo != null) {
1946 intent.setComponent(new ComponentName(
1947 aInfo.applicationInfo.packageName, aInfo.name));
1948 // Don't do this if the home app is currently being
1949 // instrumented.
1950 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1951 aInfo.applicationInfo.uid);
1952 if (app == null || app.instrumentationClass == null) {
1953 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001954 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001955 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001956 }
1957 }
1958
1959
1960 return true;
1961 }
1962
1963 /**
1964 * Starts the "new version setup screen" if appropriate.
1965 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001966 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001967 // Only do this once per boot.
1968 if (mCheckedForSetup) {
1969 return;
1970 }
1971
1972 // We will show this screen if the current one is a different
1973 // version than the last one shown, and we are not running in
1974 // low-level factory test mode.
1975 final ContentResolver resolver = mContext.getContentResolver();
1976 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1977 Settings.Secure.getInt(resolver,
1978 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1979 mCheckedForSetup = true;
1980
1981 // See if we should be showing the platform update setup UI.
1982 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1983 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1984 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1985
1986 // We don't allow third party apps to replace this.
1987 ResolveInfo ri = null;
1988 for (int i=0; ris != null && i<ris.size(); i++) {
1989 if ((ris.get(i).activityInfo.applicationInfo.flags
1990 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1991 ri = ris.get(i);
1992 break;
1993 }
1994 }
1995
1996 if (ri != null) {
1997 String vers = ri.activityInfo.metaData != null
1998 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1999 : null;
2000 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2001 vers = ri.activityInfo.applicationInfo.metaData.getString(
2002 Intent.METADATA_SETUP_VERSION);
2003 }
2004 String lastVers = Settings.Secure.getString(
2005 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2006 if (vers != null && !vers.equals(lastVers)) {
2007 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2008 intent.setComponent(new ComponentName(
2009 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002010 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002011 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002012 }
2013 }
2014 }
2015 }
2016
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002017 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002018 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002019 }
2020
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002021 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002022 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002023 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2024 }
2025 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002026
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002027 public void setFrontActivityScreenCompatMode(int mode) {
2028 synchronized (this) {
2029 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2030 }
2031 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002032
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002033 public int getPackageScreenCompatMode(String packageName) {
2034 synchronized (this) {
2035 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2036 }
2037 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002038
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002039 public void setPackageScreenCompatMode(String packageName, int mode) {
2040 synchronized (this) {
2041 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002042 }
2043 }
2044
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002045 public boolean getPackageAskScreenCompat(String packageName) {
2046 synchronized (this) {
2047 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2048 }
2049 }
2050
2051 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2052 synchronized (this) {
2053 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2054 }
2055 }
2056
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002057 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002058 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002059
2060 final int identHash = System.identityHashCode(r);
2061 updateUsageStats(r, true);
2062
2063 int i = mWatchers.beginBroadcast();
2064 while (i > 0) {
2065 i--;
2066 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2067 if (w != null) {
2068 try {
2069 w.activityResuming(identHash);
2070 } catch (RemoteException e) {
2071 }
2072 }
2073 }
2074 mWatchers.finishBroadcast();
2075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076
Jeff Sharkeya4620792011-05-20 15:29:23 -07002077 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2078 int i = mProcessObservers.beginBroadcast();
2079 while (i > 0) {
2080 i--;
2081 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2082 if (observer != null) {
2083 try {
2084 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2085 } catch (RemoteException e) {
2086 }
2087 }
2088 }
2089 mProcessObservers.finishBroadcast();
2090 }
2091
2092 private void dispatchProcessDied(int pid, int uid) {
2093 int i = mProcessObservers.beginBroadcast();
2094 while (i > 0) {
2095 i--;
2096 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2097 if (observer != null) {
2098 try {
2099 observer.onProcessDied(pid, uid);
2100 } catch (RemoteException e) {
2101 }
2102 }
2103 }
2104 mProcessObservers.finishBroadcast();
2105 }
2106
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002107 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002108 final int N = mPendingActivityLaunches.size();
2109 if (N <= 0) {
2110 return;
2111 }
2112 for (int i=0; i<N; i++) {
2113 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002114 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002115 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2116 doResume && i == (N-1));
2117 }
2118 mPendingActivityLaunches.clear();
2119 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002120
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002121 public final int startActivity(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002124 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2125 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
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, profileFile, profileFd, autoStopProfiler,
2129 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002130 }
2131
2132 public final WaitResult startActivityAndWait(IApplicationThread caller,
2133 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2134 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002135 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2136 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002137 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002138 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002139 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002140 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2141 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002142 return res;
2143 }
2144
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002145 public final int startActivityWithConfig(IApplicationThread caller,
2146 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2147 int grantedMode, IBinder resultTo,
2148 String resultWho, int requestCode, boolean onlyIfNeeded,
2149 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002150 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002151 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002152 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002153 }
2154
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002155 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002156 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002157 IBinder resultTo, String resultWho, int requestCode,
2158 int flagsMask, int flagsValues) {
2159 // Refuse possible leaked file descriptors
2160 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2161 throw new IllegalArgumentException("File descriptors passed in Intent");
2162 }
2163
2164 IIntentSender sender = intent.getTarget();
2165 if (!(sender instanceof PendingIntentRecord)) {
2166 throw new IllegalArgumentException("Bad PendingIntent object");
2167 }
2168
2169 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002170
2171 synchronized (this) {
2172 // If this is coming from the currently resumed activity, it is
2173 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002174 if (mMainStack.mResumedActivity != null
2175 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002176 Binder.getCallingUid()) {
2177 mAppSwitchesAllowedTime = 0;
2178 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002179 }
2180
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002181 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002182 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2183 }
2184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 public boolean startNextMatchingActivity(IBinder callingActivity,
2186 Intent intent) {
2187 // Refuse possible leaked file descriptors
2188 if (intent != null && intent.hasFileDescriptors() == true) {
2189 throw new IllegalArgumentException("File descriptors passed in Intent");
2190 }
2191
2192 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002193 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2194 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195 return false;
2196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 if (r.app == null || r.app.thread == null) {
2198 // The caller is not running... d'oh!
2199 return false;
2200 }
2201 intent = new Intent(intent);
2202 // The caller is not allowed to change the data.
2203 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2204 // And we are resetting to find the next component...
2205 intent.setComponent(null);
2206
2207 ActivityInfo aInfo = null;
2208 try {
2209 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002210 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002212 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213
2214 // Look for the original activity in the list...
2215 final int N = resolves != null ? resolves.size() : 0;
2216 for (int i=0; i<N; i++) {
2217 ResolveInfo rInfo = resolves.get(i);
2218 if (rInfo.activityInfo.packageName.equals(r.packageName)
2219 && rInfo.activityInfo.name.equals(r.info.name)) {
2220 // We found the current one... the next matching is
2221 // after it.
2222 i++;
2223 if (i<N) {
2224 aInfo = resolves.get(i).activityInfo;
2225 }
2226 break;
2227 }
2228 }
2229 } catch (RemoteException e) {
2230 }
2231
2232 if (aInfo == null) {
2233 // Nobody who is next!
2234 return false;
2235 }
2236
2237 intent.setComponent(new ComponentName(
2238 aInfo.applicationInfo.packageName, aInfo.name));
2239 intent.setFlags(intent.getFlags()&~(
2240 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2241 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2242 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2243 Intent.FLAG_ACTIVITY_NEW_TASK));
2244
2245 // Okay now we need to start the new activity, replacing the
2246 // currently running activity. This is a little tricky because
2247 // we want to start the new one as if the current one is finished,
2248 // but not finish the current one first so that there is no flicker.
2249 // And thus...
2250 final boolean wasFinishing = r.finishing;
2251 r.finishing = true;
2252
2253 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002254 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 final String resultWho = r.resultWho;
2256 final int requestCode = r.requestCode;
2257 r.resultTo = null;
2258 if (resultTo != null) {
2259 resultTo.removeResultsLocked(r, resultWho, requestCode);
2260 }
2261
2262 final long origId = Binder.clearCallingIdentity();
2263 // XXX we are not dealing with propagating grantedUriPermissions...
2264 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002265 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002267 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 Binder.restoreCallingIdentity(origId);
2269
2270 r.finishing = wasFinishing;
2271 if (res != START_SUCCESS) {
2272 return false;
2273 }
2274 return true;
2275 }
2276 }
2277
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002278 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 Intent intent, String resolvedType, IBinder resultTo,
2280 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002281
2282 // This is so super not safe, that only the system (or okay root)
2283 // can do it.
2284 final int callingUid = Binder.getCallingUid();
2285 if (callingUid != 0 && callingUid != Process.myUid()) {
2286 throw new SecurityException(
2287 "startActivityInPackage only available to the system");
2288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002290 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002291 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2292 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002293 }
2294
2295 public final int startActivities(IApplicationThread caller,
2296 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2297 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2298 }
2299
2300 public final int startActivitiesInPackage(int uid,
2301 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2302
2303 // This is so super not safe, that only the system (or okay root)
2304 // can do it.
2305 final int callingUid = Binder.getCallingUid();
2306 if (callingUid != 0 && callingUid != Process.myUid()) {
2307 throw new SecurityException(
2308 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 }
2310
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002311 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 }
2313
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002314 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002316 // Quick case: check if the top-most recent task is the same.
2317 if (N > 0 && mRecentTasks.get(0) == task) {
2318 return;
2319 }
2320 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 for (int i=0; i<N; i++) {
2322 TaskRecord tr = mRecentTasks.get(i);
2323 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2324 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2325 mRecentTasks.remove(i);
2326 i--;
2327 N--;
2328 if (task.intent == null) {
2329 // If the new recent task we are adding is not fully
2330 // specified, then replace it with the existing recent task.
2331 task = tr;
2332 }
2333 }
2334 }
2335 if (N >= MAX_RECENT_TASKS) {
2336 mRecentTasks.remove(N-1);
2337 }
2338 mRecentTasks.add(0, task);
2339 }
2340
2341 public void setRequestedOrientation(IBinder token,
2342 int requestedOrientation) {
2343 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002344 ActivityRecord r = mMainStack.isInStackLocked(token);
2345 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 return;
2347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 final long origId = Binder.clearCallingIdentity();
2349 mWindowManager.setAppOrientation(r, requestedOrientation);
2350 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002351 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 r.mayFreezeScreenLocked(r.app) ? r : null);
2353 if (config != null) {
2354 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002355 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002356 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 }
2358 }
2359 Binder.restoreCallingIdentity(origId);
2360 }
2361 }
2362
2363 public int getRequestedOrientation(IBinder token) {
2364 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002365 ActivityRecord r = mMainStack.isInStackLocked(token);
2366 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 return mWindowManager.getAppOrientation(r);
2370 }
2371 }
2372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 /**
2374 * This is the internal entry point for handling Activity.finish().
2375 *
2376 * @param token The Binder token referencing the Activity we want to finish.
2377 * @param resultCode Result code, if any, from this Activity.
2378 * @param resultData Result data (Intent), if any, from this Activity.
2379 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002380 * @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 -08002381 */
2382 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2383 // Refuse possible leaked file descriptors
2384 if (resultData != null && resultData.hasFileDescriptors() == true) {
2385 throw new IllegalArgumentException("File descriptors passed in Intent");
2386 }
2387
2388 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002389 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002391 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 if (next != null) {
2393 // ask watcher if this is allowed
2394 boolean resumeOK = true;
2395 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002396 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002398 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 }
2400
2401 if (!resumeOK) {
2402 return false;
2403 }
2404 }
2405 }
2406 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002407 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 resultData, "app-request");
2409 Binder.restoreCallingIdentity(origId);
2410 return res;
2411 }
2412 }
2413
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 public final void finishHeavyWeightApp() {
2415 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2416 != PackageManager.PERMISSION_GRANTED) {
2417 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2418 + Binder.getCallingPid()
2419 + ", uid=" + Binder.getCallingUid()
2420 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2421 Slog.w(TAG, msg);
2422 throw new SecurityException(msg);
2423 }
2424
2425 synchronized(this) {
2426 if (mHeavyWeightProcess == null) {
2427 return;
2428 }
2429
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002430 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002431 mHeavyWeightProcess.activities);
2432 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002433 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002434 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002435 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002436 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002437 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002438 null, "finish-heavy");
2439 }
2440 }
2441 }
2442
2443 mHeavyWeightProcess = null;
2444 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2445 }
2446 }
2447
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002448 public void crashApplication(int uid, int initialPid, String packageName,
2449 String message) {
2450 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2451 != PackageManager.PERMISSION_GRANTED) {
2452 String msg = "Permission Denial: crashApplication() from pid="
2453 + Binder.getCallingPid()
2454 + ", uid=" + Binder.getCallingUid()
2455 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2456 Slog.w(TAG, msg);
2457 throw new SecurityException(msg);
2458 }
2459
2460 synchronized(this) {
2461 ProcessRecord proc = null;
2462
2463 // Figure out which process to kill. We don't trust that initialPid
2464 // still has any relation to current pids, so must scan through the
2465 // list.
2466 synchronized (mPidsSelfLocked) {
2467 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2468 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2469 if (p.info.uid != uid) {
2470 continue;
2471 }
2472 if (p.pid == initialPid) {
2473 proc = p;
2474 break;
2475 }
2476 for (String str : p.pkgList) {
2477 if (str.equals(packageName)) {
2478 proc = p;
2479 }
2480 }
2481 }
2482 }
2483
2484 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002485 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002486 + " initialPid=" + initialPid
2487 + " packageName=" + packageName);
2488 return;
2489 }
2490
2491 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002492 if (proc.pid == Process.myPid()) {
2493 Log.w(TAG, "crashApplication: trying to crash self!");
2494 return;
2495 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002496 long ident = Binder.clearCallingIdentity();
2497 try {
2498 proc.thread.scheduleCrash(message);
2499 } catch (RemoteException e) {
2500 }
2501 Binder.restoreCallingIdentity(ident);
2502 }
2503 }
2504 }
2505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 public final void finishSubActivity(IBinder token, String resultWho,
2507 int requestCode) {
2508 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002509 ActivityRecord self = mMainStack.isInStackLocked(token);
2510 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 return;
2512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513
2514 final long origId = Binder.clearCallingIdentity();
2515
2516 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002517 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2518 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 if (r.resultTo == self && r.requestCode == requestCode) {
2520 if ((r.resultWho == null && resultWho == null) ||
2521 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 Activity.RESULT_CANCELED, null, "request-sub");
2524 }
2525 }
2526 }
2527
2528 Binder.restoreCallingIdentity(origId);
2529 }
2530 }
2531
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002532 public boolean willActivityBeVisible(IBinder token) {
2533 synchronized(this) {
2534 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002535 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2536 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002537 if (r == token) {
2538 return true;
2539 }
2540 if (r.fullscreen && !r.finishing) {
2541 return false;
2542 }
2543 }
2544 return true;
2545 }
2546 }
2547
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002548 public void overridePendingTransition(IBinder token, String packageName,
2549 int enterAnim, int exitAnim) {
2550 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002551 ActivityRecord self = mMainStack.isInStackLocked(token);
2552 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002553 return;
2554 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002555
2556 final long origId = Binder.clearCallingIdentity();
2557
2558 if (self.state == ActivityState.RESUMED
2559 || self.state == ActivityState.PAUSING) {
2560 mWindowManager.overridePendingAppTransition(packageName,
2561 enterAnim, exitAnim);
2562 }
2563
2564 Binder.restoreCallingIdentity(origId);
2565 }
2566 }
2567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 * Main function for removing an existing process from the activity manager
2570 * as a result of that process going away. Clears out all connections
2571 * to the process.
2572 */
2573 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002574 boolean restarting, boolean allowRestart) {
2575 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002577 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 }
2579
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002580 if (mProfileProc == app) {
2581 clearProfilerLocked();
2582 }
2583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002585 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2586 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2587 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002588 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002589 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2590 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 }
2592
2593 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595
2596 boolean atTop = true;
2597 boolean hasVisibleActivities = false;
2598
2599 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002600 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Removing app " + app + " from history with " + i + " entries");
2603 while (i > 0) {
2604 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002606 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2608 if (r.app == app) {
2609 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002610 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611 TAG, "Removing this entry! frozen=" + r.haveState
2612 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002613 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002614 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002615 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 mWindowManager.removeAppToken(r);
2617 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002618 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002620 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621
2622 } else {
2623 // We have the current state for this activity, so
2624 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002625 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002626 TAG, "Keeping entry, setting app to null");
2627 if (r.visible) {
2628 hasVisibleActivities = true;
2629 }
2630 r.app = null;
2631 r.nowVisible = false;
2632 if (!r.haveState) {
2633 r.icicle = null;
2634 }
2635 }
2636
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002637 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 }
2639 atTop = false;
2640 }
2641
2642 app.activities.clear();
2643
2644 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002645 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002646 + " running instrumentation " + app.instrumentationClass);
2647 Bundle info = new Bundle();
2648 info.putString("shortMsg", "Process crashed.");
2649 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2650 }
2651
2652 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002653 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 // If there was nothing to resume, and we are not already
2655 // restarting this process, but there is a visible activity that
2656 // is hosted by the process... then make sure all visible
2657 // activities are running, taking care of restarting this
2658 // process.
2659 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002660 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 }
2662 }
2663 }
2664 }
2665
2666 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2667 IBinder threadBinder = thread.asBinder();
2668
2669 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002670 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2671 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2673 return i;
2674 }
2675 }
2676 return -1;
2677 }
2678
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002679 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 IApplicationThread thread) {
2681 if (thread == null) {
2682 return null;
2683 }
2684
2685 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002686 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687 }
2688
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002689 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 IApplicationThread thread) {
2691
2692 mProcDeaths[0]++;
2693
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002694 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2695 synchronized (stats) {
2696 stats.noteProcessDiedLocked(app.info.uid, pid);
2697 }
2698
Magnus Edlund7bb25812010-02-24 15:45:06 +01002699 // Clean up already done if the process has been re-started.
2700 if (app.pid == pid && app.thread != null &&
2701 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002702 if (!app.killedBackground) {
2703 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2704 + ") has died.");
2705 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002706 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002707 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 TAG, "Dying app: " + app + ", pid: " + pid
2709 + ", thread: " + thread.asBinder());
2710 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002711 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712
2713 if (doLowMem) {
2714 // If there are no longer any background processes running,
2715 // and the app that died was not running instrumentation,
2716 // then tell everyone we are now low on memory.
2717 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002718 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2719 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002720 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 haveBg = true;
2722 break;
2723 }
2724 }
2725
2726 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002727 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002728 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002729 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2730 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002731 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002732 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2733 // The low memory report is overriding any current
2734 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002735 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002736 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002737 rec.lastRequestedGc = 0;
2738 } else {
2739 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002740 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002741 rec.reportLowMemory = true;
2742 rec.lastLowMemory = now;
2743 mProcessesToGc.remove(rec);
2744 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002747 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 }
2749 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002750 } else if (app.pid != pid) {
2751 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002752 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002753 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002754 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002755 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002756 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002757 + thread.asBinder());
2758 }
2759 }
2760
Dan Egnor42471dd2010-01-07 17:25:22 -08002761 /**
2762 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002763 * @param clearTraces causes the dump file to be erased prior to the new
2764 * traces being written, if true; when false, the new traces will be
2765 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002766 * @param firstPids of dalvik VM processes to dump stack traces for first
2767 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002768 * @return file containing stack traces, or null if no dump file is configured
2769 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002770 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2771 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002772 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2773 if (tracesPath == null || tracesPath.length() == 0) {
2774 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002776
2777 File tracesFile = new File(tracesPath);
2778 try {
2779 File tracesDir = tracesFile.getParentFile();
2780 if (!tracesDir.exists()) tracesFile.mkdirs();
2781 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2782
Christopher Tate6ee412d2010-05-28 12:01:56 -07002783 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002784 tracesFile.createNewFile();
2785 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2786 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002787 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002788 return null;
2789 }
2790
2791 // Use a FileObserver to detect when traces finish writing.
2792 // The order of traces is considered important to maintain for legibility.
2793 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2794 public synchronized void onEvent(int event, String path) { notify(); }
2795 };
2796
2797 try {
2798 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002799
2800 // First collect all of the stacks of the most important pids.
2801 try {
2802 int num = firstPids.size();
2803 for (int i = 0; i < num; i++) {
2804 synchronized (observer) {
2805 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2806 observer.wait(200); // Wait for write-close, give up after 200msec
2807 }
2808 }
2809 } catch (InterruptedException e) {
2810 Log.wtf(TAG, e);
2811 }
2812
2813 // Next measure CPU usage.
2814 if (processStats != null) {
2815 processStats.init();
2816 System.gc();
2817 processStats.update();
2818 try {
2819 synchronized (processStats) {
2820 processStats.wait(500); // measure over 1/2 second.
2821 }
2822 } catch (InterruptedException e) {
2823 }
2824 processStats.update();
2825
2826 // We'll take the stack crawls of just the top apps using CPU.
2827 final int N = processStats.countWorkingStats();
2828 int numProcs = 0;
2829 for (int i=0; i<N && numProcs<5; i++) {
2830 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2831 if (lastPids.indexOfKey(stats.pid) >= 0) {
2832 numProcs++;
2833 try {
2834 synchronized (observer) {
2835 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2836 observer.wait(200); // Wait for write-close, give up after 200msec
2837 }
2838 } catch (InterruptedException e) {
2839 Log.wtf(TAG, e);
2840 }
2841
2842 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002843 }
2844 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002845
2846 return tracesFile;
2847
Dan Egnor42471dd2010-01-07 17:25:22 -08002848 } finally {
2849 observer.stopWatching();
2850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 }
2852
Jeff Brown4d94a762010-09-23 11:33:28 -07002853 private final class AppNotResponding implements Runnable {
2854 private final ProcessRecord mApp;
2855 private final String mAnnotation;
2856
2857 public AppNotResponding(ProcessRecord app, String annotation) {
2858 mApp = app;
2859 mAnnotation = annotation;
2860 }
2861
2862 @Override
2863 public void run() {
2864 appNotResponding(mApp, null, null, mAnnotation);
2865 }
2866 }
2867
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002868 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2869 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002870 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2871 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2872
Dianne Hackborn287952c2010-09-22 22:34:31 -07002873 if (mController != null) {
2874 try {
2875 // 0 == continue, -1 = kill process immediately
2876 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2877 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2878 } catch (RemoteException e) {
2879 mController = null;
2880 }
2881 }
2882
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002883 long anrTime = SystemClock.uptimeMillis();
2884 if (MONITOR_CPU_USAGE) {
2885 updateCpuStatsNow();
2886 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 synchronized (this) {
2889 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2890 if (mShuttingDown) {
2891 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2892 return;
2893 } else if (app.notResponding) {
2894 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2895 return;
2896 } else if (app.crashing) {
2897 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2898 return;
2899 }
2900
2901 // In case we come through here for the same app before completing
2902 // this one, mark as anring now so we will bail out.
2903 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002904
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 // Log the ANR to the event log.
2906 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2907 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002908
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002909 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002910 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002911
2912 int parentPid = app.pid;
2913 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002914 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002915
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002916 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002917
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002918 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2919 ProcessRecord r = mLruProcesses.get(i);
2920 if (r != null && r.thread != null) {
2921 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002922 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2923 if (r.persistent) {
2924 firstPids.add(pid);
2925 } else {
2926 lastPids.put(pid, Boolean.TRUE);
2927 }
2928 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 }
2931 }
2932
Dan Egnor42471dd2010-01-07 17:25:22 -08002933 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002934 StringBuilder info = mStringBuilder;
2935 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002936 info.append("ANR in ").append(app.processName);
2937 if (activity != null && activity.shortComponentName != null) {
2938 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002939 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002940 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002942 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002944 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002945 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947
Dianne Hackborn287952c2010-09-22 22:34:31 -07002948 final ProcessStats processStats = new ProcessStats(true);
2949
2950 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2951
Dan Egnor42471dd2010-01-07 17:25:22 -08002952 String cpuInfo = null;
2953 if (MONITOR_CPU_USAGE) {
2954 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002955 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002956 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002957 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002958 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002959 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 }
2961
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002962 info.append(processStats.printCurrentState(anrTime));
2963
Joe Onorato8a9b2202010-02-26 18:56:32 -08002964 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002965 if (tracesFile == null) {
2966 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2967 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2968 }
2969
2970 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2971
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002972 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002973 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002974 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2975 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002977 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2978 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 }
2980 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002981 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982 }
2983 }
2984
Dan Egnor42471dd2010-01-07 17:25:22 -08002985 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2986 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2987 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002988
2989 synchronized (this) {
2990 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002991 Slog.w(TAG, "Killing " + app + ": background ANR");
2992 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2993 app.processName, app.setAdj, "background ANR");
2994 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002995 return;
2996 }
2997
2998 // Set the app's notResponding state, and look up the errorReportReceiver
2999 makeAppNotRespondingLocked(app,
3000 activity != null ? activity.shortComponentName : null,
3001 annotation != null ? "ANR " + annotation : "ANR",
3002 info.toString());
3003
3004 // Bring up the infamous App Not Responding dialog
3005 Message msg = Message.obtain();
3006 HashMap map = new HashMap();
3007 msg.what = SHOW_NOT_RESPONDING_MSG;
3008 msg.obj = map;
3009 map.put("app", app);
3010 if (activity != null) {
3011 map.put("activity", activity);
3012 }
3013
3014 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 }
3017
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003018 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3019 if (!mLaunchWarningShown) {
3020 mLaunchWarningShown = true;
3021 mHandler.post(new Runnable() {
3022 @Override
3023 public void run() {
3024 synchronized (ActivityManagerService.this) {
3025 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3026 d.show();
3027 mHandler.postDelayed(new Runnable() {
3028 @Override
3029 public void run() {
3030 synchronized (ActivityManagerService.this) {
3031 d.dismiss();
3032 mLaunchWarningShown = false;
3033 }
3034 }
3035 }, 4000);
3036 }
3037 }
3038 });
3039 }
3040 }
3041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 public boolean clearApplicationUserData(final String packageName,
3043 final IPackageDataObserver observer) {
3044 int uid = Binder.getCallingUid();
3045 int pid = Binder.getCallingPid();
3046 long callingId = Binder.clearCallingIdentity();
3047 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003048 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 int pkgUid = -1;
3050 synchronized(this) {
3051 try {
3052 pkgUid = pm.getPackageUid(packageName);
3053 } catch (RemoteException e) {
3054 }
3055 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003056 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 return false;
3058 }
3059 if (uid == pkgUid || checkComponentPermission(
3060 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003061 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 } else {
3065 throw new SecurityException(pid+" does not have permission:"+
3066 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3067 "for process:"+packageName);
3068 }
3069 }
3070
3071 try {
3072 //clear application user data
3073 pm.clearApplicationUserData(packageName, observer);
3074 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3075 Uri.fromParts("package", packageName, null));
3076 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003077 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3078 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 } catch (RemoteException e) {
3080 }
3081 } finally {
3082 Binder.restoreCallingIdentity(callingId);
3083 }
3084 return true;
3085 }
3086
Dianne Hackborn03abb812010-01-04 18:43:19 -08003087 public void killBackgroundProcesses(final String packageName) {
3088 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3089 != PackageManager.PERMISSION_GRANTED &&
3090 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3091 != PackageManager.PERMISSION_GRANTED) {
3092 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 + Binder.getCallingPid()
3094 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003095 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003096 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 throw new SecurityException(msg);
3098 }
3099
3100 long callingId = Binder.clearCallingIdentity();
3101 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003102 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003103 int pkgUid = -1;
3104 synchronized(this) {
3105 try {
3106 pkgUid = pm.getPackageUid(packageName);
3107 } catch (RemoteException e) {
3108 }
3109 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003110 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003111 return;
3112 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003113 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003114 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003115 }
3116 } finally {
3117 Binder.restoreCallingIdentity(callingId);
3118 }
3119 }
3120
3121 public void forceStopPackage(final String packageName) {
3122 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3123 != PackageManager.PERMISSION_GRANTED) {
3124 String msg = "Permission Denial: forceStopPackage() from pid="
3125 + Binder.getCallingPid()
3126 + ", uid=" + Binder.getCallingUid()
3127 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003128 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003129 throw new SecurityException(msg);
3130 }
3131
3132 long callingId = Binder.clearCallingIdentity();
3133 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003134 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003135 int pkgUid = -1;
3136 synchronized(this) {
3137 try {
3138 pkgUid = pm.getPackageUid(packageName);
3139 } catch (RemoteException e) {
3140 }
3141 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003142 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003143 return;
3144 }
3145 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003146 try {
3147 pm.setPackageStoppedState(packageName, true);
3148 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003149 } catch (IllegalArgumentException e) {
3150 Slog.w(TAG, "Failed trying to unstop package "
3151 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 }
3154 } finally {
3155 Binder.restoreCallingIdentity(callingId);
3156 }
3157 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003158
3159 /*
3160 * The pkg name and uid have to be specified.
3161 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3162 */
3163 public void killApplicationWithUid(String pkg, int uid) {
3164 if (pkg == null) {
3165 return;
3166 }
3167 // Make sure the uid is valid.
3168 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003169 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003170 return;
3171 }
3172 int callerUid = Binder.getCallingUid();
3173 // Only the system server can kill an application
3174 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003175 // Post an aysnc message to kill the application
3176 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3177 msg.arg1 = uid;
3178 msg.arg2 = 0;
3179 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003180 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003181 } else {
3182 throw new SecurityException(callerUid + " cannot kill pkg: " +
3183 pkg);
3184 }
3185 }
3186
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003187 public void closeSystemDialogs(String reason) {
3188 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003189 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003190 if (reason != null) {
3191 intent.putExtra("reason", reason);
3192 }
3193
3194 final int uid = Binder.getCallingUid();
3195 final long origId = Binder.clearCallingIdentity();
3196 synchronized (this) {
3197 int i = mWatchers.beginBroadcast();
3198 while (i > 0) {
3199 i--;
3200 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3201 if (w != null) {
3202 try {
3203 w.closingSystemDialogs(reason);
3204 } catch (RemoteException e) {
3205 }
3206 }
3207 }
3208 mWatchers.finishBroadcast();
3209
Dianne Hackbornffa42482009-09-23 22:20:11 -07003210 mWindowManager.closeSystemDialogs(reason);
3211
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003212 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3213 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003214 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003215 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003216 Activity.RESULT_CANCELED, null, "close-sys");
3217 }
3218 }
3219
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003220 broadcastIntentLocked(null, null, intent, null,
3221 null, 0, null, null, null, false, false, -1, uid);
3222 }
3223 Binder.restoreCallingIdentity(origId);
3224 }
3225
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003226 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003227 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003228 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3229 for (int i=pids.length-1; i>=0; i--) {
3230 infos[i] = new Debug.MemoryInfo();
3231 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003232 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003233 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003234 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003235
Dianne Hackbornb437e092011-08-05 17:50:29 -07003236 public long[] getProcessPss(int[] pids) throws RemoteException {
3237 long[] pss = new long[pids.length];
3238 for (int i=pids.length-1; i>=0; i--) {
3239 pss[i] = Debug.getPss(pids[i]);
3240 }
3241 return pss;
3242 }
3243
Christopher Tate5e1ab332009-09-01 20:32:49 -07003244 public void killApplicationProcess(String processName, int uid) {
3245 if (processName == null) {
3246 return;
3247 }
3248
3249 int callerUid = Binder.getCallingUid();
3250 // Only the system server can kill an application
3251 if (callerUid == Process.SYSTEM_UID) {
3252 synchronized (this) {
3253 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003254 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003255 try {
3256 app.thread.scheduleSuicide();
3257 } catch (RemoteException e) {
3258 // If the other end already died, then our work here is done.
3259 }
3260 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003261 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003262 + processName + " / " + uid);
3263 }
3264 }
3265 } else {
3266 throw new SecurityException(callerUid + " cannot kill app process: " +
3267 processName);
3268 }
3269 }
3270
Dianne Hackborn03abb812010-01-04 18:43:19 -08003271 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003272 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3274 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003275 if (!mProcessesReady) {
3276 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003278 intent.putExtra(Intent.EXTRA_UID, uid);
3279 broadcastIntentLocked(null, null, intent,
3280 null, null, 0, null, null, null,
3281 false, false, MY_PID, Process.SYSTEM_UID);
3282 }
3283
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003284 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003285 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3286 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003287 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003288
Dianne Hackborn03abb812010-01-04 18:43:19 -08003289 // Remove all processes this package may have touched: all with the
3290 // same UID (except for the system or root user), and all whose name
3291 // matches the package name.
3292 final String procNamePrefix = packageName + ":";
3293 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3294 final int NA = apps.size();
3295 for (int ia=0; ia<NA; ia++) {
3296 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003297 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003298 // we don't kill persistent processes
3299 continue;
3300 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003301 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003302 if (doit) {
3303 procs.add(app);
3304 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003305 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3306 || app.processName.equals(packageName)
3307 || app.processName.startsWith(procNamePrefix)) {
3308 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003309 if (!doit) {
3310 return true;
3311 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003312 app.removed = true;
3313 procs.add(app);
3314 }
3315 }
3316 }
3317 }
3318
3319 int N = procs.size();
3320 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003321 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003322 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003323 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003324 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003325
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003327 boolean callerWillRestart, boolean purgeCache, boolean doit,
3328 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003329 int i;
3330 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 if (uid < 0) {
3333 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003334 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 } catch (RemoteException e) {
3336 }
3337 }
3338
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003339 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003340 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003341
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003342 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3343 while (badApps.hasNext()) {
3344 SparseArray<Long> ba = badApps.next();
3345 if (ba.get(uid) != null) {
3346 badApps.remove();
3347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 }
3349 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003350
3351 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003352 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003354 TaskRecord lastTask = null;
3355 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003356 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003357 final boolean samePackage = r.packageName.equals(name);
3358 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003359 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003360 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003361 if (r.finishing) {
3362 // If this activity is just finishing, then it is not
3363 // interesting as far as something to stop.
3364 continue;
3365 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003366 return true;
3367 }
3368 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003369 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003370 if (samePackage) {
3371 if (r.app != null) {
3372 r.app.removed = true;
3373 }
3374 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003376 lastTask = r.task;
3377 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3378 null, "force-stop")) {
3379 i--;
3380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 }
3382 }
3383
3384 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3385 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003386 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003387 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003388 if (!doit) {
3389 return true;
3390 }
3391 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003392 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 if (service.app != null) {
3394 service.app.removed = true;
3395 }
3396 service.app = null;
3397 services.add(service);
3398 }
3399 }
3400
3401 N = services.size();
3402 for (i=0; i<N; i++) {
3403 bringDownServiceLocked(services.get(i), true);
3404 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003405
3406 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3407 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3408 if (provider.info.packageName.equals(name)
3409 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3410 if (!doit) {
3411 return true;
3412 }
3413 didSomething = true;
3414 providers.add(provider);
3415 }
3416 }
3417
3418 N = providers.size();
3419 for (i=0; i<N; i++) {
3420 removeDyingProviderLocked(null, providers.get(i));
3421 }
3422
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003423 if (doit) {
3424 if (purgeCache) {
3425 AttributeCache ac = AttributeCache.instance();
3426 if (ac != null) {
3427 ac.removePackage(name);
3428 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003429 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003430 mMainStack.resumeTopActivityLocked(null);
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003431 mMainStack.scheduleIdleLocked();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003432 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003433
3434 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 }
3436
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003437 private final boolean removeProcessLocked(ProcessRecord app,
3438 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 final String name = app.processName;
3440 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003441 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 TAG, "Force removing process " + app + " (" + name
3443 + "/" + uid + ")");
3444
3445 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003446 if (mHeavyWeightProcess == app) {
3447 mHeavyWeightProcess = null;
3448 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 boolean needRestart = false;
3451 if (app.pid > 0 && app.pid != MY_PID) {
3452 int pid = app.pid;
3453 synchronized (mPidsSelfLocked) {
3454 mPidsSelfLocked.remove(pid);
3455 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3456 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003457 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003458 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 Process.killProcess(pid);
3460
3461 if (app.persistent) {
3462 if (!callerWillRestart) {
3463 addAppLocked(app.info);
3464 } else {
3465 needRestart = true;
3466 }
3467 }
3468 } else {
3469 mRemovedProcesses.add(app);
3470 }
3471
3472 return needRestart;
3473 }
3474
3475 private final void processStartTimedOutLocked(ProcessRecord app) {
3476 final int pid = app.pid;
3477 boolean gone = false;
3478 synchronized (mPidsSelfLocked) {
3479 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3480 if (knownApp != null && knownApp.thread == null) {
3481 mPidsSelfLocked.remove(pid);
3482 gone = true;
3483 }
3484 }
3485
3486 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003487 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003488 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003489 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003491 if (mHeavyWeightProcess == app) {
3492 mHeavyWeightProcess = null;
3493 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3494 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003495 // Take care of any launching providers waiting for this process.
3496 checkAppInLaunchingProvidersLocked(app, true);
3497 // Take care of any services that are waiting for the process.
3498 for (int i=0; i<mPendingServices.size(); i++) {
3499 ServiceRecord sr = mPendingServices.get(i);
3500 if (app.info.uid == sr.appInfo.uid
3501 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003502 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003503 mPendingServices.remove(i);
3504 i--;
3505 bringDownServiceLocked(sr, true);
3506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003508 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3509 app.processName, app.setAdj, "start timeout");
3510 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003511 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003512 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003513 try {
3514 IBackupManager bm = IBackupManager.Stub.asInterface(
3515 ServiceManager.getService(Context.BACKUP_SERVICE));
3516 bm.agentDisconnected(app.info.packageName);
3517 } catch (RemoteException e) {
3518 // Can't happen; the backup manager is local
3519 }
3520 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003521 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003522 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003523 mPendingBroadcast.state = BroadcastRecord.IDLE;
3524 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003525 mPendingBroadcast = null;
3526 scheduleBroadcastsLocked();
3527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003529 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 }
3531 }
3532
3533 private final boolean attachApplicationLocked(IApplicationThread thread,
3534 int pid) {
3535
3536 // Find the application record that is being attached... either via
3537 // the pid if we are running in multiple processes, or just pull the
3538 // next app record if we are emulating process with anonymous threads.
3539 ProcessRecord app;
3540 if (pid != MY_PID && pid >= 0) {
3541 synchronized (mPidsSelfLocked) {
3542 app = mPidsSelfLocked.get(pid);
3543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 } else {
3545 app = null;
3546 }
3547
3548 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003549 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003550 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003551 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003553 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 } else {
3555 try {
3556 thread.scheduleExit();
3557 } catch (Exception e) {
3558 // Ignore exceptions.
3559 }
3560 }
3561 return false;
3562 }
3563
3564 // If this application record is still attached to a previous
3565 // process, clean it up now.
3566 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003567 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 }
3569
3570 // Tell the process all about itself.
3571
Joe Onorato8a9b2202010-02-26 18:56:32 -08003572 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 TAG, "Binding process pid " + pid + " to record " + app);
3574
3575 String processName = app.processName;
3576 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003577 AppDeathRecipient adr = new AppDeathRecipient(
3578 app, pid, thread);
3579 thread.asBinder().linkToDeath(adr, 0);
3580 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 } catch (RemoteException e) {
3582 app.resetPackageList();
3583 startProcessLocked(app, "link fail", processName);
3584 return false;
3585 }
3586
Doug Zongker2bec3d42009-12-04 12:52:44 -08003587 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588
3589 app.thread = thread;
3590 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003591 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3592 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 app.forcingToForeground = null;
3594 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003595 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003596 app.debugging = false;
3597
3598 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3599
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003600 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003601 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003603 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003604 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003605 }
3606
Joe Onorato8a9b2202010-02-26 18:56:32 -08003607 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 TAG, "New app record " + app
3609 + " thread=" + thread.asBinder() + " pid=" + pid);
3610 try {
3611 int testMode = IApplicationThread.DEBUG_OFF;
3612 if (mDebugApp != null && mDebugApp.equals(processName)) {
3613 testMode = mWaitForDebugger
3614 ? IApplicationThread.DEBUG_WAIT
3615 : IApplicationThread.DEBUG_ON;
3616 app.debugging = true;
3617 if (mDebugTransient) {
3618 mDebugApp = mOrigDebugApp;
3619 mWaitForDebugger = mOrigWaitForDebugger;
3620 }
3621 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003622 String profileFile = app.instrumentationProfileFile;
3623 ParcelFileDescriptor profileFd = null;
3624 boolean profileAutoStop = false;
3625 if (mProfileApp != null && mProfileApp.equals(processName)) {
3626 mProfileProc = app;
3627 profileFile = mProfileFile;
3628 profileFd = mProfileFd;
3629 profileAutoStop = mAutoStopProfiler;
3630 }
3631
Christopher Tate181fafa2009-05-14 11:12:14 -07003632 // If the app is being launched for restore or full backup, set it up specially
3633 boolean isRestrictedBackupMode = false;
3634 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3635 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003636 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003637 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3638 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003639
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003640 ensurePackageDexOpt(app.instrumentationInfo != null
3641 ? app.instrumentationInfo.packageName
3642 : app.info.packageName);
3643 if (app.instrumentationClass != null) {
3644 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003645 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003646 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003647 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003648 ApplicationInfo appInfo = app.instrumentationInfo != null
3649 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003650 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003651 if (profileFd != null) {
3652 profileFd = profileFd.dup();
3653 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003654 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003655 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003657 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003658 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003659 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003660 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003661 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 } catch (Exception e) {
3663 // todo: Yikes! What should we do? For now we will try to
3664 // start another process, but that could easily get us in
3665 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003666 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667
3668 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003669 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 startProcessLocked(app, "bind fail", processName);
3671 return false;
3672 }
3673
3674 // Remove this record from the list of starting applications.
3675 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003676 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3677 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 mProcessesOnHold.remove(app);
3679
3680 boolean badApp = false;
3681 boolean didSomething = false;
3682
3683 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003684 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003685 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003686 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3687 && processName.equals(hr.processName)) {
3688 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003689 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 didSomething = true;
3691 }
3692 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003693 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 + hr.intent.getComponent().flattenToShortString(), e);
3695 badApp = true;
3696 }
3697 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003698 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 }
3700 }
3701
3702 // Find any services that should be running in this process...
3703 if (!badApp && mPendingServices.size() > 0) {
3704 ServiceRecord sr = null;
3705 try {
3706 for (int i=0; i<mPendingServices.size(); i++) {
3707 sr = mPendingServices.get(i);
3708 if (app.info.uid != sr.appInfo.uid
3709 || !processName.equals(sr.processName)) {
3710 continue;
3711 }
3712
3713 mPendingServices.remove(i);
3714 i--;
3715 realStartServiceLocked(sr, app);
3716 didSomething = true;
3717 }
3718 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003719 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 + sr.shortName, e);
3721 badApp = true;
3722 }
3723 }
3724
3725 // Check if the next broadcast receiver is in this process...
3726 BroadcastRecord br = mPendingBroadcast;
3727 if (!badApp && br != null && br.curApp == app) {
3728 try {
3729 mPendingBroadcast = null;
3730 processCurBroadcastLocked(br, app);
3731 didSomething = true;
3732 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003733 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003734 + br.curComponent.flattenToShortString(), e);
3735 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003736 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3738 br.resultExtras, br.resultAbort, true);
3739 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003740 // We need to reset the state if we fails to start the receiver.
3741 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 }
3743 }
3744
Christopher Tate181fafa2009-05-14 11:12:14 -07003745 // Check whether the next backup agent is in this process...
3746 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003747 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003748 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003749 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003750 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3751 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3752 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003753 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003754 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003755 e.printStackTrace();
3756 }
3757 }
3758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003759 if (badApp) {
3760 // todo: Also need to kill application to deal with all
3761 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003762 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 return false;
3764 }
3765
3766 if (!didSomething) {
3767 updateOomAdjLocked();
3768 }
3769
3770 return true;
3771 }
3772
3773 public final void attachApplication(IApplicationThread thread) {
3774 synchronized (this) {
3775 int callingPid = Binder.getCallingPid();
3776 final long origId = Binder.clearCallingIdentity();
3777 attachApplicationLocked(thread, callingPid);
3778 Binder.restoreCallingIdentity(origId);
3779 }
3780 }
3781
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003782 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003784 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3785 if (stopProfiling) {
3786 synchronized (this) {
3787 if (mProfileProc == r.app) {
3788 if (mProfileFd != null) {
3789 try {
3790 mProfileFd.close();
3791 } catch (IOException e) {
3792 }
3793 clearProfilerLocked();
3794 }
3795 }
3796 }
3797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 Binder.restoreCallingIdentity(origId);
3799 }
3800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003801 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003802 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003803 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 mWindowManager.enableScreenAfterBoot();
3805 }
3806
Dianne Hackborn661cd522011-08-22 00:26:20 -07003807 public void showBootMessage(final CharSequence msg, final boolean always) {
3808 mWindowManager.showBootMessage(msg, always);
3809 }
3810
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003811 public void dismissKeyguardOnNextActivity() {
3812 synchronized (this) {
3813 mMainStack.dismissKeyguardOnNextActivityLocked();
3814 }
3815 }
3816
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003817 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003818 IntentFilter pkgFilter = new IntentFilter();
3819 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3820 pkgFilter.addDataScheme("package");
3821 mContext.registerReceiver(new BroadcastReceiver() {
3822 @Override
3823 public void onReceive(Context context, Intent intent) {
3824 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3825 if (pkgs != null) {
3826 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003827 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003828 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003829 setResultCode(Activity.RESULT_OK);
3830 return;
3831 }
3832 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003833 }
3834 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003835 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003836 }, pkgFilter);
3837
3838 synchronized (this) {
3839 // Ensure that any processes we had put on hold are now started
3840 // up.
3841 final int NP = mProcessesOnHold.size();
3842 if (NP > 0) {
3843 ArrayList<ProcessRecord> procs =
3844 new ArrayList<ProcessRecord>(mProcessesOnHold);
3845 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003846 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3847 + procs.get(ip));
3848 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003849 }
3850 }
3851
3852 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003853 // Start looking for apps that are abusing wake locks.
3854 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003855 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003856 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003857 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003858 broadcastIntentLocked(null, null,
3859 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3860 null, null, 0, null, null,
3861 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3862 false, false, MY_PID, Process.SYSTEM_UID);
3863 }
3864 }
3865 }
3866
3867 final void ensureBootCompleted() {
3868 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003869 boolean enableScreen;
3870 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003871 booting = mBooting;
3872 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003873 enableScreen = !mBooted;
3874 mBooted = true;
3875 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003876
3877 if (booting) {
3878 finishBooting();
3879 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003880
3881 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003882 enableScreenAfterBoot();
3883 }
3884 }
3885
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003886 public final void activityPaused(IBinder token) {
3887 final long origId = Binder.clearCallingIdentity();
3888 mMainStack.activityPaused(token, false);
3889 Binder.restoreCallingIdentity(origId);
3890 }
3891
3892 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3893 CharSequence description) {
3894 if (localLOGV) Slog.v(
3895 TAG, "Activity stopped: token=" + token);
3896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 // Refuse possible leaked file descriptors
3898 if (icicle != null && icicle.hasFileDescriptors()) {
3899 throw new IllegalArgumentException("File descriptors passed in Bundle");
3900 }
3901
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003902 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903
3904 final long origId = Binder.clearCallingIdentity();
3905
3906 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003907 r = mMainStack.isInStackLocked(token);
3908 if (r != null) {
3909 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 }
3911 }
3912
3913 if (r != null) {
3914 sendPendingThumbnail(r, null, null, null, false);
3915 }
3916
3917 trimApplications();
3918
3919 Binder.restoreCallingIdentity(origId);
3920 }
3921
3922 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003923 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003924 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 }
3926
3927 public String getCallingPackage(IBinder token) {
3928 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003929 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003930 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 }
3932 }
3933
3934 public ComponentName getCallingActivity(IBinder token) {
3935 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003936 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 return r != null ? r.intent.getComponent() : null;
3938 }
3939 }
3940
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003941 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003942 ActivityRecord r = mMainStack.isInStackLocked(token);
3943 if (r == null) {
3944 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003946 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 }
3948
3949 public ComponentName getActivityClassForToken(IBinder token) {
3950 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003951 ActivityRecord r = mMainStack.isInStackLocked(token);
3952 if (r == null) {
3953 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003955 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 }
3957 }
3958
3959 public String getPackageForToken(IBinder token) {
3960 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003961 ActivityRecord r = mMainStack.isInStackLocked(token);
3962 if (r == null) {
3963 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003965 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 }
3967 }
3968
3969 public IIntentSender getIntentSender(int type,
3970 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003971 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003973 if (intents != null) {
3974 if (intents.length < 1) {
3975 throw new IllegalArgumentException("Intents array length must be >= 1");
3976 }
3977 for (int i=0; i<intents.length; i++) {
3978 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003979 if (intent != null) {
3980 if (intent.hasFileDescriptors()) {
3981 throw new IllegalArgumentException("File descriptors passed in Intent");
3982 }
3983 if (type == INTENT_SENDER_BROADCAST &&
3984 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3985 throw new IllegalArgumentException(
3986 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3987 }
3988 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003989 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003990 }
3991 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003992 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003993 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003994 }
3995 }
3996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 synchronized(this) {
3998 int callingUid = Binder.getCallingUid();
3999 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004000 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004001 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 .getPackageUid(packageName);
4003 if (uid != Binder.getCallingUid()) {
4004 String msg = "Permission Denial: getIntentSender() from pid="
4005 + Binder.getCallingPid()
4006 + ", uid=" + Binder.getCallingUid()
4007 + ", (need uid=" + uid + ")"
4008 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004009 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 throw new SecurityException(msg);
4011 }
4012 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004013
4014 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004015 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 } catch (RemoteException e) {
4018 throw new SecurityException(e);
4019 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004020 }
4021 }
4022
4023 IIntentSender getIntentSenderLocked(int type,
4024 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004025 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004026 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004027 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004028 activity = mMainStack.isInStackLocked(token);
4029 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004030 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004032 if (activity.finishing) {
4033 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004035 }
4036
4037 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4038 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4039 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4040 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4041 |PendingIntent.FLAG_UPDATE_CURRENT);
4042
4043 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4044 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004045 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004046 WeakReference<PendingIntentRecord> ref;
4047 ref = mIntentSenderRecords.get(key);
4048 PendingIntentRecord rec = ref != null ? ref.get() : null;
4049 if (rec != null) {
4050 if (!cancelCurrent) {
4051 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004052 if (rec.key.requestIntent != null) {
4053 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4054 }
4055 if (intents != null) {
4056 intents[intents.length-1] = rec.key.requestIntent;
4057 rec.key.allIntents = intents;
4058 rec.key.allResolvedTypes = resolvedTypes;
4059 } else {
4060 rec.key.allIntents = null;
4061 rec.key.allResolvedTypes = null;
4062 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 return rec;
4065 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004066 rec.canceled = true;
4067 mIntentSenderRecords.remove(key);
4068 }
4069 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004070 return rec;
4071 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004072 rec = new PendingIntentRecord(this, key, callingUid);
4073 mIntentSenderRecords.put(key, rec.ref);
4074 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4075 if (activity.pendingResults == null) {
4076 activity.pendingResults
4077 = new HashSet<WeakReference<PendingIntentRecord>>();
4078 }
4079 activity.pendingResults.add(rec.ref);
4080 }
4081 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 }
4083
4084 public void cancelIntentSender(IIntentSender sender) {
4085 if (!(sender instanceof PendingIntentRecord)) {
4086 return;
4087 }
4088 synchronized(this) {
4089 PendingIntentRecord rec = (PendingIntentRecord)sender;
4090 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004091 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 .getPackageUid(rec.key.packageName);
4093 if (uid != Binder.getCallingUid()) {
4094 String msg = "Permission Denial: cancelIntentSender() from pid="
4095 + Binder.getCallingPid()
4096 + ", uid=" + Binder.getCallingUid()
4097 + " is not allowed to cancel packges "
4098 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004099 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 throw new SecurityException(msg);
4101 }
4102 } catch (RemoteException e) {
4103 throw new SecurityException(e);
4104 }
4105 cancelIntentSenderLocked(rec, true);
4106 }
4107 }
4108
4109 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4110 rec.canceled = true;
4111 mIntentSenderRecords.remove(rec.key);
4112 if (cleanActivity && rec.key.activity != null) {
4113 rec.key.activity.pendingResults.remove(rec.ref);
4114 }
4115 }
4116
4117 public String getPackageForIntentSender(IIntentSender pendingResult) {
4118 if (!(pendingResult instanceof PendingIntentRecord)) {
4119 return null;
4120 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004121 try {
4122 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4123 return res.key.packageName;
4124 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004125 }
4126 return null;
4127 }
4128
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004129 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4130 if (!(pendingResult instanceof PendingIntentRecord)) {
4131 return false;
4132 }
4133 try {
4134 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4135 if (res.key.allIntents == null) {
4136 return false;
4137 }
4138 for (int i=0; i<res.key.allIntents.length; i++) {
4139 Intent intent = res.key.allIntents[i];
4140 if (intent.getPackage() != null && intent.getComponent() != null) {
4141 return false;
4142 }
4143 }
4144 return true;
4145 } catch (ClassCastException e) {
4146 }
4147 return false;
4148 }
4149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004150 public void setProcessLimit(int max) {
4151 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4152 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004153 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004154 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004155 mProcessLimitOverride = max;
4156 }
4157 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004158 }
4159
4160 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004161 synchronized (this) {
4162 return mProcessLimitOverride;
4163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 }
4165
4166 void foregroundTokenDied(ForegroundToken token) {
4167 synchronized (ActivityManagerService.this) {
4168 synchronized (mPidsSelfLocked) {
4169 ForegroundToken cur
4170 = mForegroundProcesses.get(token.pid);
4171 if (cur != token) {
4172 return;
4173 }
4174 mForegroundProcesses.remove(token.pid);
4175 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4176 if (pr == null) {
4177 return;
4178 }
4179 pr.forcingToForeground = null;
4180 pr.foregroundServices = false;
4181 }
4182 updateOomAdjLocked();
4183 }
4184 }
4185
4186 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4187 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4188 "setProcessForeground()");
4189 synchronized(this) {
4190 boolean changed = false;
4191
4192 synchronized (mPidsSelfLocked) {
4193 ProcessRecord pr = mPidsSelfLocked.get(pid);
4194 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004195 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004196 return;
4197 }
4198 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4199 if (oldToken != null) {
4200 oldToken.token.unlinkToDeath(oldToken, 0);
4201 mForegroundProcesses.remove(pid);
4202 pr.forcingToForeground = null;
4203 changed = true;
4204 }
4205 if (isForeground && token != null) {
4206 ForegroundToken newToken = new ForegroundToken() {
4207 public void binderDied() {
4208 foregroundTokenDied(this);
4209 }
4210 };
4211 newToken.pid = pid;
4212 newToken.token = token;
4213 try {
4214 token.linkToDeath(newToken, 0);
4215 mForegroundProcesses.put(pid, newToken);
4216 pr.forcingToForeground = token;
4217 changed = true;
4218 } catch (RemoteException e) {
4219 // If the process died while doing this, we will later
4220 // do the cleanup with the process death link.
4221 }
4222 }
4223 }
4224
4225 if (changed) {
4226 updateOomAdjLocked();
4227 }
4228 }
4229 }
4230
4231 // =========================================================
4232 // PERMISSIONS
4233 // =========================================================
4234
4235 static class PermissionController extends IPermissionController.Stub {
4236 ActivityManagerService mActivityManagerService;
4237 PermissionController(ActivityManagerService activityManagerService) {
4238 mActivityManagerService = activityManagerService;
4239 }
4240
4241 public boolean checkPermission(String permission, int pid, int uid) {
4242 return mActivityManagerService.checkPermission(permission, pid,
4243 uid) == PackageManager.PERMISSION_GRANTED;
4244 }
4245 }
4246
4247 /**
4248 * This can be called with or without the global lock held.
4249 */
4250 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004251 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 // We might be performing an operation on behalf of an indirect binder
4253 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4254 // client identity accordingly before proceeding.
4255 Identity tlsIdentity = sCallerIdentity.get();
4256 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004257 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4259 uid = tlsIdentity.uid;
4260 pid = tlsIdentity.pid;
4261 }
4262
4263 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004264 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265 return PackageManager.PERMISSION_GRANTED;
4266 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004267 // If there is a uid that owns whatever is being accessed, it has
4268 // blanket access to it regardless of the permissions it requires.
4269 if (owningUid >= 0 && uid == owningUid) {
4270 return PackageManager.PERMISSION_GRANTED;
4271 }
4272 // If the target is not exported, then nobody else can get to it.
4273 if (!exported) {
4274 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 return PackageManager.PERMISSION_DENIED;
4276 }
4277 if (permission == null) {
4278 return PackageManager.PERMISSION_GRANTED;
4279 }
4280 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004281 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004282 .checkUidPermission(permission, uid);
4283 } catch (RemoteException e) {
4284 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004285 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 }
4287 return PackageManager.PERMISSION_DENIED;
4288 }
4289
4290 /**
4291 * As the only public entry point for permissions checking, this method
4292 * can enforce the semantic that requesting a check on a null global
4293 * permission is automatically denied. (Internally a null permission
4294 * string is used when calling {@link #checkComponentPermission} in cases
4295 * when only uid-based security is needed.)
4296 *
4297 * This can be called with or without the global lock held.
4298 */
4299 public int checkPermission(String permission, int pid, int uid) {
4300 if (permission == null) {
4301 return PackageManager.PERMISSION_DENIED;
4302 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004303 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 }
4305
4306 /**
4307 * Binder IPC calls go through the public entry point.
4308 * This can be called with or without the global lock held.
4309 */
4310 int checkCallingPermission(String permission) {
4311 return checkPermission(permission,
4312 Binder.getCallingPid(),
4313 Binder.getCallingUid());
4314 }
4315
4316 /**
4317 * This can be called with or without the global lock held.
4318 */
4319 void enforceCallingPermission(String permission, String func) {
4320 if (checkCallingPermission(permission)
4321 == PackageManager.PERMISSION_GRANTED) {
4322 return;
4323 }
4324
4325 String msg = "Permission Denial: " + func + " from pid="
4326 + Binder.getCallingPid()
4327 + ", uid=" + Binder.getCallingUid()
4328 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004329 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004330 throw new SecurityException(msg);
4331 }
4332
4333 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004334 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4335 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4336 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4337 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4338 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004339 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004340 // Is the component private from the target uid?
4341 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4342
4343 // Acceptable if the there is no read permission needed from the
4344 // target or the target is holding the read permission.
4345 if (!readPerm) {
4346 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004347 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004348 == PackageManager.PERMISSION_GRANTED)) {
4349 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004350 }
4351 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004352
4353 // Acceptable if the there is no write permission needed from the
4354 // target or the target is holding the read permission.
4355 if (!writePerm) {
4356 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004358 == PackageManager.PERMISSION_GRANTED)) {
4359 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 }
4361 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004362
4363 // Acceptable if there is a path permission matching the URI that
4364 // the target holds the permission on.
4365 PathPermission[] pps = pi.pathPermissions;
4366 if (pps != null && (!readPerm || !writePerm)) {
4367 final String path = uri.getPath();
4368 int i = pps.length;
4369 while (i > 0 && (!readPerm || !writePerm)) {
4370 i--;
4371 PathPermission pp = pps[i];
4372 if (!readPerm) {
4373 final String pprperm = pp.getReadPermission();
4374 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4375 + pprperm + " for " + pp.getPath()
4376 + ": match=" + pp.match(path)
4377 + " check=" + pm.checkUidPermission(pprperm, uid));
4378 if (pprperm != null && pp.match(path) &&
4379 (pm.checkUidPermission(pprperm, uid)
4380 == PackageManager.PERMISSION_GRANTED)) {
4381 readPerm = true;
4382 }
4383 }
4384 if (!writePerm) {
4385 final String ppwperm = pp.getWritePermission();
4386 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4387 + ppwperm + " for " + pp.getPath()
4388 + ": match=" + pp.match(path)
4389 + " check=" + pm.checkUidPermission(ppwperm, uid));
4390 if (ppwperm != null && pp.match(path) &&
4391 (pm.checkUidPermission(ppwperm, uid)
4392 == PackageManager.PERMISSION_GRANTED)) {
4393 writePerm = true;
4394 }
4395 }
4396 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398 } catch (RemoteException e) {
4399 return false;
4400 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004401
4402 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
4404
4405 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4406 int modeFlags) {
4407 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004408 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 return true;
4410 }
4411 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4412 if (perms == null) return false;
4413 UriPermission perm = perms.get(uri);
4414 if (perm == null) return false;
4415 return (modeFlags&perm.modeFlags) == modeFlags;
4416 }
4417
4418 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4419 // Another redirected-binder-call permissions check as in
4420 // {@link checkComponentPermission}.
4421 Identity tlsIdentity = sCallerIdentity.get();
4422 if (tlsIdentity != null) {
4423 uid = tlsIdentity.uid;
4424 pid = tlsIdentity.pid;
4425 }
4426
4427 // Our own process gets to do everything.
4428 if (pid == MY_PID) {
4429 return PackageManager.PERMISSION_GRANTED;
4430 }
4431 synchronized(this) {
4432 return checkUriPermissionLocked(uri, uid, modeFlags)
4433 ? PackageManager.PERMISSION_GRANTED
4434 : PackageManager.PERMISSION_DENIED;
4435 }
4436 }
4437
Dianne Hackborn39792d22010-08-19 18:01:52 -07004438 /**
4439 * Check if the targetPkg can be granted permission to access uri by
4440 * the callingUid using the given modeFlags. Throws a security exception
4441 * if callingUid is not allowed to do this. Returns the uid of the target
4442 * if the URI permission grant should be performed; returns -1 if it is not
4443 * needed (for example targetPkg already has permission to access the URI).
4444 */
4445 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4446 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4448 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4449 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004450 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004451 }
4452
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004453 if (targetPkg != null) {
4454 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4455 "Checking grant " + targetPkg + " permission to " + uri);
4456 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004457
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004458 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459
4460 // If this is not a content: uri, we can't do anything with it.
4461 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004462 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004463 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004464 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 }
4466
4467 String name = uri.getAuthority();
4468 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004469 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470 if (cpr != null) {
4471 pi = cpr.info;
4472 } else {
4473 try {
4474 pi = pm.resolveContentProvider(name,
4475 PackageManager.GET_URI_PERMISSION_PATTERNS);
4476 } catch (RemoteException ex) {
4477 }
4478 }
4479 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004480 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004481 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 }
4483
4484 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004485 if (targetPkg != null) {
4486 try {
4487 targetUid = pm.getPackageUid(targetPkg);
4488 if (targetUid < 0) {
4489 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4490 "Can't grant URI permission no uid for: " + targetPkg);
4491 return -1;
4492 }
4493 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004494 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004496 } else {
4497 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 }
4499
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004500 if (targetUid >= 0) {
4501 // First... does the target actually need this permission?
4502 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4503 // No need to grant the target this permission.
4504 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4505 "Target " + targetPkg + " already has full permission to " + uri);
4506 return -1;
4507 }
4508 } else {
4509 // First... there is no target package, so can anyone access it?
4510 boolean allowed = pi.exported;
4511 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4512 if (pi.readPermission != null) {
4513 allowed = false;
4514 }
4515 }
4516 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4517 if (pi.writePermission != null) {
4518 allowed = false;
4519 }
4520 }
4521 if (allowed) {
4522 return -1;
4523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 }
4525
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004526 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004527 if (!pi.grantUriPermissions) {
4528 throw new SecurityException("Provider " + pi.packageName
4529 + "/" + pi.name
4530 + " does not allow granting of Uri permissions (uri "
4531 + uri + ")");
4532 }
4533 if (pi.uriPermissionPatterns != null) {
4534 final int N = pi.uriPermissionPatterns.length;
4535 boolean allowed = false;
4536 for (int i=0; i<N; i++) {
4537 if (pi.uriPermissionPatterns[i] != null
4538 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4539 allowed = true;
4540 break;
4541 }
4542 }
4543 if (!allowed) {
4544 throw new SecurityException("Provider " + pi.packageName
4545 + "/" + pi.name
4546 + " does not allow granting of permission to path of Uri "
4547 + uri);
4548 }
4549 }
4550
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004551 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004553 if (callingUid != Process.myUid()) {
4554 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4555 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4556 throw new SecurityException("Uid " + callingUid
4557 + " does not have permission to uri " + uri);
4558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 }
4560 }
4561
Dianne Hackborn39792d22010-08-19 18:01:52 -07004562 return targetUid;
4563 }
4564
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004565 public int checkGrantUriPermission(int callingUid, String targetPkg,
4566 Uri uri, int modeFlags) {
4567 synchronized(this) {
4568 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4569 }
4570 }
4571
Dianne Hackborn39792d22010-08-19 18:01:52 -07004572 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4573 Uri uri, int modeFlags, UriPermissionOwner owner) {
4574 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4575 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4576 if (modeFlags == 0) {
4577 return;
4578 }
4579
4580 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 // to the uri, and the target doesn't. Let's now give this to
4582 // the target.
4583
Joe Onorato8a9b2202010-02-26 18:56:32 -08004584 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004585 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004587 HashMap<Uri, UriPermission> targetUris
4588 = mGrantedUriPermissions.get(targetUid);
4589 if (targetUris == null) {
4590 targetUris = new HashMap<Uri, UriPermission>();
4591 mGrantedUriPermissions.put(targetUid, targetUris);
4592 }
4593
4594 UriPermission perm = targetUris.get(uri);
4595 if (perm == null) {
4596 perm = new UriPermission(targetUid, uri);
4597 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004601 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004603 } else {
4604 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4605 perm.readOwners.add(owner);
4606 owner.addReadPermission(perm);
4607 }
4608 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4609 perm.writeOwners.add(owner);
4610 owner.addWritePermission(perm);
4611 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 }
4613 }
4614
Dianne Hackborn39792d22010-08-19 18:01:52 -07004615 void grantUriPermissionLocked(int callingUid,
4616 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004617 if (targetPkg == null) {
4618 throw new NullPointerException("targetPkg");
4619 }
4620
Dianne Hackborn39792d22010-08-19 18:01:52 -07004621 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4622 if (targetUid < 0) {
4623 return;
4624 }
4625
4626 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4627 }
4628
4629 /**
4630 * Like checkGrantUriPermissionLocked, but takes an Intent.
4631 */
4632 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4633 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004634 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004635 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004636 + " from " + intent + "; flags=0x"
4637 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4638
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004639 if (targetPkg == null) {
4640 throw new NullPointerException("targetPkg");
4641 }
4642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004644 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004645 }
4646 Uri data = intent.getData();
4647 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004648 return -1;
4649 }
4650 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4651 intent.getFlags());
4652 }
4653
4654 /**
4655 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4656 */
4657 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4658 String targetPkg, Intent intent, UriPermissionOwner owner) {
4659 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4660 intent.getFlags(), owner);
4661 }
4662
4663 void grantUriPermissionFromIntentLocked(int callingUid,
4664 String targetPkg, Intent intent, UriPermissionOwner owner) {
4665 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4666 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 return;
4668 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004669
4670 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004671 }
4672
4673 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4674 Uri uri, int modeFlags) {
4675 synchronized(this) {
4676 final ProcessRecord r = getRecordForAppLocked(caller);
4677 if (r == null) {
4678 throw new SecurityException("Unable to find app for caller "
4679 + caller
4680 + " when granting permission to uri " + uri);
4681 }
4682 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004683 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 }
4685 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004686 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 }
4688
4689 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4690 null);
4691 }
4692 }
4693
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004694 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4696 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4697 HashMap<Uri, UriPermission> perms
4698 = mGrantedUriPermissions.get(perm.uid);
4699 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004700 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004701 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004702 perms.remove(perm.uri);
4703 if (perms.size() == 0) {
4704 mGrantedUriPermissions.remove(perm.uid);
4705 }
4706 }
4707 }
4708 }
4709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4711 int modeFlags) {
4712 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4713 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4714 if (modeFlags == 0) {
4715 return;
4716 }
4717
Joe Onorato8a9b2202010-02-26 18:56:32 -08004718 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004719 "Revoking all granted permissions to " + uri);
4720
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004721 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004722
4723 final String authority = uri.getAuthority();
4724 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004725 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 if (cpr != null) {
4727 pi = cpr.info;
4728 } else {
4729 try {
4730 pi = pm.resolveContentProvider(authority,
4731 PackageManager.GET_URI_PERMISSION_PATTERNS);
4732 } catch (RemoteException ex) {
4733 }
4734 }
4735 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004736 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 return;
4738 }
4739
4740 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004741 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004742 // Right now, if you are not the original owner of the permission,
4743 // you are not allowed to revoke it.
4744 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4745 throw new SecurityException("Uid " + callingUid
4746 + " does not have permission to uri " + uri);
4747 //}
4748 }
4749
4750 // Go through all of the permissions and remove any that match.
4751 final List<String> SEGMENTS = uri.getPathSegments();
4752 if (SEGMENTS != null) {
4753 final int NS = SEGMENTS.size();
4754 int N = mGrantedUriPermissions.size();
4755 for (int i=0; i<N; i++) {
4756 HashMap<Uri, UriPermission> perms
4757 = mGrantedUriPermissions.valueAt(i);
4758 Iterator<UriPermission> it = perms.values().iterator();
4759 toploop:
4760 while (it.hasNext()) {
4761 UriPermission perm = it.next();
4762 Uri targetUri = perm.uri;
4763 if (!authority.equals(targetUri.getAuthority())) {
4764 continue;
4765 }
4766 List<String> targetSegments = targetUri.getPathSegments();
4767 if (targetSegments == null) {
4768 continue;
4769 }
4770 if (targetSegments.size() < NS) {
4771 continue;
4772 }
4773 for (int j=0; j<NS; j++) {
4774 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4775 continue toploop;
4776 }
4777 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004778 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004779 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004780 perm.clearModes(modeFlags);
4781 if (perm.modeFlags == 0) {
4782 it.remove();
4783 }
4784 }
4785 if (perms.size() == 0) {
4786 mGrantedUriPermissions.remove(
4787 mGrantedUriPermissions.keyAt(i));
4788 N--;
4789 i--;
4790 }
4791 }
4792 }
4793 }
4794
4795 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4796 int modeFlags) {
4797 synchronized(this) {
4798 final ProcessRecord r = getRecordForAppLocked(caller);
4799 if (r == null) {
4800 throw new SecurityException("Unable to find app for caller "
4801 + caller
4802 + " when revoking permission to uri " + uri);
4803 }
4804 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004805 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 return;
4807 }
4808
4809 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4810 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4811 if (modeFlags == 0) {
4812 return;
4813 }
4814
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004815 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004816
4817 final String authority = uri.getAuthority();
4818 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004819 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004820 if (cpr != null) {
4821 pi = cpr.info;
4822 } else {
4823 try {
4824 pi = pm.resolveContentProvider(authority,
4825 PackageManager.GET_URI_PERMISSION_PATTERNS);
4826 } catch (RemoteException ex) {
4827 }
4828 }
4829 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004830 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004831 return;
4832 }
4833
4834 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4835 }
4836 }
4837
Dianne Hackborn7e269642010-08-25 19:50:20 -07004838 @Override
4839 public IBinder newUriPermissionOwner(String name) {
4840 synchronized(this) {
4841 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4842 return owner.getExternalTokenLocked();
4843 }
4844 }
4845
4846 @Override
4847 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4848 Uri uri, int modeFlags) {
4849 synchronized(this) {
4850 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4851 if (owner == null) {
4852 throw new IllegalArgumentException("Unknown owner: " + token);
4853 }
4854 if (fromUid != Binder.getCallingUid()) {
4855 if (Binder.getCallingUid() != Process.myUid()) {
4856 // Only system code can grant URI permissions on behalf
4857 // of other users.
4858 throw new SecurityException("nice try");
4859 }
4860 }
4861 if (targetPkg == null) {
4862 throw new IllegalArgumentException("null target");
4863 }
4864 if (uri == null) {
4865 throw new IllegalArgumentException("null uri");
4866 }
4867
4868 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4869 }
4870 }
4871
4872 @Override
4873 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4874 synchronized(this) {
4875 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4876 if (owner == null) {
4877 throw new IllegalArgumentException("Unknown owner: " + token);
4878 }
4879
4880 if (uri == null) {
4881 owner.removeUriPermissionsLocked(mode);
4882 } else {
4883 owner.removeUriPermissionLocked(uri, mode);
4884 }
4885 }
4886 }
4887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4889 synchronized (this) {
4890 ProcessRecord app =
4891 who != null ? getRecordForAppLocked(who) : null;
4892 if (app == null) return;
4893
4894 Message msg = Message.obtain();
4895 msg.what = WAIT_FOR_DEBUGGER_MSG;
4896 msg.obj = app;
4897 msg.arg1 = waiting ? 1 : 0;
4898 mHandler.sendMessage(msg);
4899 }
4900 }
4901
4902 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004903 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4904 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004905 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004906 outInfo.threshold = homeAppMem;
4907 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4908 outInfo.hiddenAppThreshold = hiddenAppMem;
4909 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4910 ProcessList.SECONDARY_SERVER_ADJ);
4911 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4912 ProcessList.VISIBLE_APP_ADJ);
4913 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4914 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004915 }
4916
4917 // =========================================================
4918 // TASK MANAGEMENT
4919 // =========================================================
4920
4921 public List getTasks(int maxNum, int flags,
4922 IThumbnailReceiver receiver) {
4923 ArrayList list = new ArrayList();
4924
4925 PendingThumbnailsRecord pending = null;
4926 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004927 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928
4929 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004930 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004931 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4932 + ", receiver=" + receiver);
4933
4934 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4935 != PackageManager.PERMISSION_GRANTED) {
4936 if (receiver != null) {
4937 // If the caller wants to wait for pending thumbnails,
4938 // it ain't gonna get them.
4939 try {
4940 receiver.finished();
4941 } catch (RemoteException ex) {
4942 }
4943 }
4944 String msg = "Permission Denial: getTasks() from pid="
4945 + Binder.getCallingPid()
4946 + ", uid=" + Binder.getCallingUid()
4947 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004948 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004949 throw new SecurityException(msg);
4950 }
4951
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004952 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004953 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004954 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004955 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 TaskRecord curTask = null;
4957 int numActivities = 0;
4958 int numRunning = 0;
4959 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004960 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004961 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004962 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963
4964 // Initialize state for next task if needed.
4965 if (top == null ||
4966 (top.state == ActivityState.INITIALIZING
4967 && top.task == r.task)) {
4968 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 curTask = r.task;
4970 numActivities = numRunning = 0;
4971 }
4972
4973 // Add 'r' into the current task.
4974 numActivities++;
4975 if (r.app != null && r.app.thread != null) {
4976 numRunning++;
4977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978
Joe Onorato8a9b2202010-02-26 18:56:32 -08004979 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 TAG, r.intent.getComponent().flattenToShortString()
4981 + ": task=" + r.task);
4982
4983 // If the next one is a different task, generate a new
4984 // TaskInfo entry for what we have.
4985 if (next == null || next.task != curTask) {
4986 ActivityManager.RunningTaskInfo ci
4987 = new ActivityManager.RunningTaskInfo();
4988 ci.id = curTask.taskId;
4989 ci.baseActivity = r.intent.getComponent();
4990 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004991 if (top.thumbHolder != null) {
4992 ci.description = top.thumbHolder.lastDescription;
4993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 ci.numActivities = numActivities;
4995 ci.numRunning = numRunning;
4996 //System.out.println(
4997 // "#" + maxNum + ": " + " descr=" + ci.description);
4998 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004999 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 TAG, "State=" + top.state + "Idle=" + top.idle
5001 + " app=" + top.app
5002 + " thr=" + (top.app != null ? top.app.thread : null));
5003 if (top.state == ActivityState.RESUMED
5004 || top.state == ActivityState.PAUSING) {
5005 if (top.idle && top.app != null
5006 && top.app.thread != null) {
5007 topRecord = top;
5008 topThumbnail = top.app.thread;
5009 } else {
5010 top.thumbnailNeeded = true;
5011 }
5012 }
5013 if (pending == null) {
5014 pending = new PendingThumbnailsRecord(receiver);
5015 }
5016 pending.pendingRecords.add(top);
5017 }
5018 list.add(ci);
5019 maxNum--;
5020 top = null;
5021 }
5022 }
5023
5024 if (pending != null) {
5025 mPendingThumbnails.add(pending);
5026 }
5027 }
5028
Joe Onorato8a9b2202010-02-26 18:56:32 -08005029 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005030
5031 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005032 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 try {
5034 topThumbnail.requestThumbnail(topRecord);
5035 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005036 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005037 sendPendingThumbnail(null, topRecord, null, null, true);
5038 }
5039 }
5040
5041 if (pending == null && receiver != null) {
5042 // In this case all thumbnails were available and the client
5043 // is being asked to be told when the remaining ones come in...
5044 // which is unusually, since the top-most currently running
5045 // activity should never have a canned thumbnail! Oh well.
5046 try {
5047 receiver.finished();
5048 } catch (RemoteException ex) {
5049 }
5050 }
5051
5052 return list;
5053 }
5054
5055 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5056 int flags) {
5057 synchronized (this) {
5058 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5059 "getRecentTasks()");
5060
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005061 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005063 final int N = mRecentTasks.size();
5064 ArrayList<ActivityManager.RecentTaskInfo> res
5065 = new ArrayList<ActivityManager.RecentTaskInfo>(
5066 maxNum < N ? maxNum : N);
5067 for (int i=0; i<N && maxNum > 0; i++) {
5068 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005069 // Return the entry if desired by the caller. We always return
5070 // the first entry, because callers always expect this to be the
5071 // forground app. We may filter others if the caller has
5072 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5073 // we should exclude the entry.
5074 if (i == 0
5075 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 || (tr.intent == null)
5077 || ((tr.intent.getFlags()
5078 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5079 ActivityManager.RecentTaskInfo rti
5080 = new ActivityManager.RecentTaskInfo();
5081 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005082 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005083 rti.baseIntent = new Intent(
5084 tr.intent != null ? tr.intent : tr.affinityIntent);
5085 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005086 rti.description = tr.lastDescription;
5087
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005088 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5089 // Check whether this activity is currently available.
5090 try {
5091 if (rti.origActivity != null) {
5092 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5093 continue;
5094 }
5095 } else if (rti.baseIntent != null) {
5096 if (pm.queryIntentActivities(rti.baseIntent,
5097 null, 0) == null) {
5098 continue;
5099 }
5100 }
5101 } catch (RemoteException e) {
5102 // Will never happen.
5103 }
5104 }
5105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106 res.add(rti);
5107 maxNum--;
5108 }
5109 }
5110 return res;
5111 }
5112 }
5113
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005114 private TaskRecord taskForIdLocked(int id) {
5115 final int N = mRecentTasks.size();
5116 for (int i=0; i<N; i++) {
5117 TaskRecord tr = mRecentTasks.get(i);
5118 if (tr.taskId == id) {
5119 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005120 }
5121 }
5122 return null;
5123 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005124
5125 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5126 synchronized (this) {
5127 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5128 "getTaskThumbnails()");
5129 TaskRecord tr = taskForIdLocked(id);
5130 if (tr != null) {
5131 return mMainStack.getTaskThumbnailsLocked(tr);
5132 }
5133 }
5134 return null;
5135 }
5136
5137 public boolean removeSubTask(int taskId, int subTaskIndex) {
5138 synchronized (this) {
5139 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5140 "removeSubTask()");
5141 long ident = Binder.clearCallingIdentity();
5142 try {
5143 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5144 } finally {
5145 Binder.restoreCallingIdentity(ident);
5146 }
5147 }
5148 }
5149
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005150 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005151 TaskRecord tr = root.task;
5152 Intent baseIntent = new Intent(
5153 tr.intent != null ? tr.intent : tr.affinityIntent);
5154 ComponentName component = baseIntent.getComponent();
5155 if (component == null) {
5156 Slog.w(TAG, "Now component for base intent of task: " + tr);
5157 return;
5158 }
5159
5160 // Find any running services associated with this app.
5161 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5162 for (ServiceRecord sr : mServices.values()) {
5163 if (sr.packageName.equals(component.getPackageName())) {
5164 services.add(sr);
5165 }
5166 }
5167
5168 // Take care of any running services associated with the app.
5169 for (int i=0; i<services.size(); i++) {
5170 ServiceRecord sr = services.get(i);
5171 if (sr.startRequested) {
5172 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005173 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005174 stopServiceLocked(sr);
5175 } else {
5176 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5177 sr.makeNextStartId(), baseIntent, -1));
5178 if (sr.app != null && sr.app.thread != null) {
5179 sendServiceArgsLocked(sr, false);
5180 }
5181 }
5182 }
5183 }
5184
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005185 if (killProcesses) {
5186 // Find any running processes associated with this app.
5187 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5188 SparseArray<ProcessRecord> appProcs
5189 = mProcessNames.getMap().get(component.getPackageName());
5190 if (appProcs != null) {
5191 for (int i=0; i<appProcs.size(); i++) {
5192 procs.add(appProcs.valueAt(i));
5193 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005194 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005195
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005196 // Kill the running processes.
5197 for (int i=0; i<procs.size(); i++) {
5198 ProcessRecord pr = procs.get(i);
5199 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5200 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5201 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5202 pr.processName, pr.setAdj, "remove task");
5203 Process.killProcessQuiet(pr.pid);
5204 } else {
5205 pr.waitingToKill = "remove task";
5206 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005207 }
5208 }
5209 }
5210
5211 public boolean removeTask(int taskId, int flags) {
5212 synchronized (this) {
5213 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5214 "removeTask()");
5215 long ident = Binder.clearCallingIdentity();
5216 try {
5217 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5218 if (r != null) {
5219 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005220 cleanUpRemovedTaskLocked(r,
5221 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005222 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005223 } else {
5224 TaskRecord tr = null;
5225 int i=0;
5226 while (i < mRecentTasks.size()) {
5227 TaskRecord t = mRecentTasks.get(i);
5228 if (t.taskId == taskId) {
5229 tr = t;
5230 break;
5231 }
5232 i++;
5233 }
5234 if (tr != null) {
5235 if (tr.numActivities <= 0) {
5236 // Caller is just removing a recent task that is
5237 // not actively running. That is easy!
5238 mRecentTasks.remove(i);
5239 } else {
5240 Slog.w(TAG, "removeTask: task " + taskId
5241 + " does not have activities to remove, "
5242 + " but numActivities=" + tr.numActivities
5243 + ": " + tr);
5244 }
5245 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005246 }
5247 } finally {
5248 Binder.restoreCallingIdentity(ident);
5249 }
5250 }
5251 return false;
5252 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5255 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005256 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005257 TaskRecord jt = startTask;
5258
5259 // First look backwards
5260 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005261 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 if (r.task != jt) {
5263 jt = r.task;
5264 if (affinity.equals(jt.affinity)) {
5265 return j;
5266 }
5267 }
5268 }
5269
5270 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005271 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 jt = startTask;
5273 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005274 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005275 if (r.task != jt) {
5276 if (affinity.equals(jt.affinity)) {
5277 return j;
5278 }
5279 jt = r.task;
5280 }
5281 }
5282
5283 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005284 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 return N-1;
5286 }
5287
5288 return -1;
5289 }
5290
5291 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005292 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005294 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005295 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5296 "moveTaskToFront()");
5297
5298 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005299 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5300 Binder.getCallingUid(), "Task to front")) {
5301 return;
5302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005303 final long origId = Binder.clearCallingIdentity();
5304 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005305 TaskRecord tr = taskForIdLocked(task);
5306 if (tr != null) {
5307 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5308 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005310 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5311 // Caller wants the home activity moved with it. To accomplish this,
5312 // we'll just move the home task to the top first.
5313 mMainStack.moveHomeToFrontLocked();
5314 }
5315 mMainStack.moveTaskToFrontLocked(tr, null);
5316 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005318 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5319 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005320 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005321 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5322 mMainStack.mUserLeaving = true;
5323 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005324 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5325 // Caller wants the home activity moved with it. To accomplish this,
5326 // we'll just move the home task to the top first.
5327 mMainStack.moveHomeToFrontLocked();
5328 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005329 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 return;
5331 }
5332 }
5333 } finally {
5334 Binder.restoreCallingIdentity(origId);
5335 }
5336 }
5337 }
5338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005339 public void moveTaskToBack(int task) {
5340 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5341 "moveTaskToBack()");
5342
5343 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005344 if (mMainStack.mResumedActivity != null
5345 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005346 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5347 Binder.getCallingUid(), "Task to back")) {
5348 return;
5349 }
5350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005352 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005353 Binder.restoreCallingIdentity(origId);
5354 }
5355 }
5356
5357 /**
5358 * Moves an activity, and all of the other activities within the same task, to the bottom
5359 * of the history stack. The activity's order within the task is unchanged.
5360 *
5361 * @param token A reference to the activity we wish to move
5362 * @param nonRoot If false then this only works if the activity is the root
5363 * of a task; if true it will work for any activity in a task.
5364 * @return Returns true if the move completed, false if not.
5365 */
5366 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5367 synchronized(this) {
5368 final long origId = Binder.clearCallingIdentity();
5369 int taskId = getTaskForActivityLocked(token, !nonRoot);
5370 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005371 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 }
5373 Binder.restoreCallingIdentity(origId);
5374 }
5375 return false;
5376 }
5377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005378 public void moveTaskBackwards(int task) {
5379 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5380 "moveTaskBackwards()");
5381
5382 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005383 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5384 Binder.getCallingUid(), "Task backwards")) {
5385 return;
5386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005387 final long origId = Binder.clearCallingIdentity();
5388 moveTaskBackwardsLocked(task);
5389 Binder.restoreCallingIdentity(origId);
5390 }
5391 }
5392
5393 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005394 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 }
5396
5397 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5398 synchronized(this) {
5399 return getTaskForActivityLocked(token, onlyRoot);
5400 }
5401 }
5402
5403 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005404 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 TaskRecord lastTask = null;
5406 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005407 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005408 if (r == token) {
5409 if (!onlyRoot || lastTask != r.task) {
5410 return r.task.taskId;
5411 }
5412 return -1;
5413 }
5414 lastTask = r.task;
5415 }
5416
5417 return -1;
5418 }
5419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 public void finishOtherInstances(IBinder token, ComponentName className) {
5421 synchronized(this) {
5422 final long origId = Binder.clearCallingIdentity();
5423
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005424 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 TaskRecord lastTask = null;
5426 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005427 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 if (r.realActivity.equals(className)
5429 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005430 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 null, "others")) {
5432 i--;
5433 N--;
5434 }
5435 }
5436 lastTask = r.task;
5437 }
5438
5439 Binder.restoreCallingIdentity(origId);
5440 }
5441 }
5442
5443 // =========================================================
5444 // THUMBNAILS
5445 // =========================================================
5446
5447 public void reportThumbnail(IBinder token,
5448 Bitmap thumbnail, CharSequence description) {
5449 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5450 final long origId = Binder.clearCallingIdentity();
5451 sendPendingThumbnail(null, token, thumbnail, description, true);
5452 Binder.restoreCallingIdentity(origId);
5453 }
5454
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005455 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 Bitmap thumbnail, CharSequence description, boolean always) {
5457 TaskRecord task = null;
5458 ArrayList receivers = null;
5459
5460 //System.out.println("Send pending thumbnail: " + r);
5461
5462 synchronized(this) {
5463 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005464 r = mMainStack.isInStackLocked(token);
5465 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 return;
5467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005469 if (thumbnail == null && r.thumbHolder != null) {
5470 thumbnail = r.thumbHolder.lastThumbnail;
5471 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005472 }
5473 if (thumbnail == null && !always) {
5474 // If there is no thumbnail, and this entry is not actually
5475 // going away, then abort for now and pick up the next
5476 // thumbnail we get.
5477 return;
5478 }
5479 task = r.task;
5480
5481 int N = mPendingThumbnails.size();
5482 int i=0;
5483 while (i<N) {
5484 PendingThumbnailsRecord pr =
5485 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5486 //System.out.println("Looking in " + pr.pendingRecords);
5487 if (pr.pendingRecords.remove(r)) {
5488 if (receivers == null) {
5489 receivers = new ArrayList();
5490 }
5491 receivers.add(pr);
5492 if (pr.pendingRecords.size() == 0) {
5493 pr.finished = true;
5494 mPendingThumbnails.remove(i);
5495 N--;
5496 continue;
5497 }
5498 }
5499 i++;
5500 }
5501 }
5502
5503 if (receivers != null) {
5504 final int N = receivers.size();
5505 for (int i=0; i<N; i++) {
5506 try {
5507 PendingThumbnailsRecord pr =
5508 (PendingThumbnailsRecord)receivers.get(i);
5509 pr.receiver.newThumbnail(
5510 task != null ? task.taskId : -1, thumbnail, description);
5511 if (pr.finished) {
5512 pr.receiver.finished();
5513 }
5514 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005515 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005516 }
5517 }
5518 }
5519 }
5520
5521 // =========================================================
5522 // CONTENT PROVIDERS
5523 // =========================================================
5524
Jeff Brown10e89712011-07-08 18:52:57 -07005525 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5526 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005527 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005528 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005530 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 } catch (RemoteException ex) {
5532 }
5533 if (providers != null) {
5534 final int N = providers.size();
5535 for (int i=0; i<N; i++) {
5536 ProviderInfo cpi =
5537 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005538 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5539 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005540 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005541 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005542 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 }
5544 app.pubProviders.put(cpi.name, cpr);
5545 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005546 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005547 }
5548 }
5549 return providers;
5550 }
5551
5552 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005553 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005554 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5555 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5556 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005557 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005558 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005559 return null;
5560 }
5561 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005562 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 == PackageManager.PERMISSION_GRANTED) {
5564 return null;
5565 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005566
5567 PathPermission[] pps = cpi.pathPermissions;
5568 if (pps != null) {
5569 int i = pps.length;
5570 while (i > 0) {
5571 i--;
5572 PathPermission pp = pps[i];
5573 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005574 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005575 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005576 return null;
5577 }
5578 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005579 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005580 == PackageManager.PERMISSION_GRANTED) {
5581 return null;
5582 }
5583 }
5584 }
5585
Dianne Hackbornb424b632010-08-18 15:59:05 -07005586 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5587 if (perms != null) {
5588 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5589 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5590 return null;
5591 }
5592 }
5593 }
5594
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005595 String msg;
5596 if (!cpi.exported) {
5597 msg = "Permission Denial: opening provider " + cpi.name
5598 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5599 + ", uid=" + callingUid + ") that is not exported from uid "
5600 + cpi.applicationInfo.uid;
5601 } else {
5602 msg = "Permission Denial: opening provider " + cpi.name
5603 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5604 + ", uid=" + callingUid + ") requires "
5605 + cpi.readPermission + " or " + cpi.writePermission;
5606 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005607 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005608 return msg;
5609 }
5610
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005611 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5612 if (r != null) {
5613 Integer cnt = r.conProviders.get(cpr);
5614 if (DEBUG_PROVIDER) Slog.v(TAG,
5615 "Adding provider requested by "
5616 + r.processName + " from process "
5617 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5618 + " cnt=" + (cnt == null ? 1 : cnt));
5619 if (cnt == null) {
5620 cpr.clients.add(r);
5621 r.conProviders.put(cpr, new Integer(1));
5622 return true;
5623 } else {
5624 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5625 }
5626 } else {
5627 cpr.externals++;
5628 }
5629 return false;
5630 }
5631
5632 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5633 if (r != null) {
5634 Integer cnt = r.conProviders.get(cpr);
5635 if (DEBUG_PROVIDER) Slog.v(TAG,
5636 "Removing provider requested by "
5637 + r.processName + " from process "
5638 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5639 + " cnt=" + cnt);
5640 if (cnt == null || cnt.intValue() <= 1) {
5641 cpr.clients.remove(r);
5642 r.conProviders.remove(cpr);
5643 return true;
5644 } else {
5645 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5646 }
5647 } else {
5648 cpr.externals++;
5649 }
5650 return false;
5651 }
5652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653 private final ContentProviderHolder getContentProviderImpl(
5654 IApplicationThread caller, String name) {
5655 ContentProviderRecord cpr;
5656 ProviderInfo cpi = null;
5657
5658 synchronized(this) {
5659 ProcessRecord r = null;
5660 if (caller != null) {
5661 r = getRecordForAppLocked(caller);
5662 if (r == null) {
5663 throw new SecurityException(
5664 "Unable to find app for caller " + caller
5665 + " (pid=" + Binder.getCallingPid()
5666 + ") when getting content provider " + name);
5667 }
5668 }
5669
5670 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005671 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005672 boolean providerRunning = cpr != null;
5673 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005675 String msg;
5676 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5677 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005678 }
5679
5680 if (r != null && cpr.canRunHere(r)) {
5681 // This provider has been published or is in the process
5682 // of being published... but it is also allowed to run
5683 // in the caller's process, so don't make a connection
5684 // and just let the caller instantiate its own instance.
5685 if (cpr.provider != null) {
5686 // don't give caller the provider object, it needs
5687 // to make its own.
5688 cpr = new ContentProviderRecord(cpr);
5689 }
5690 return cpr;
5691 }
5692
5693 final long origId = Binder.clearCallingIdentity();
5694
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005695 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005697 final boolean countChanged = incProviderCount(r, cpr);
5698 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005699 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005700 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005701 // make sure to count it as being accessed and thus
5702 // back up on the LRU list. This is good because
5703 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005704 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005705 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005706 }
5707
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005708 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005709 if (false) {
5710 if (cpr.name.flattenToShortString().equals(
5711 "com.android.providers.calendar/.CalendarProvider2")) {
5712 Slog.v(TAG, "****************** KILLING "
5713 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005714 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005715 }
5716 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005717 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005718 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5719 // NOTE: there is still a race here where a signal could be
5720 // pending on the process even though we managed to update its
5721 // adj level. Not sure what to do about this, but at least
5722 // the race is now smaller.
5723 if (!success) {
5724 // Uh oh... it looks like the provider's process
5725 // has been killed on us. We need to wait for a new
5726 // process to be started, and make sure its death
5727 // doesn't kill our process.
5728 Slog.i(TAG,
5729 "Existing provider " + cpr.name.flattenToShortString()
5730 + " is crashing; detaching " + r);
5731 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005732 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005733 if (!lastRef) {
5734 // This wasn't the last ref our process had on
5735 // the provider... we have now been killed, bail.
5736 return null;
5737 }
5738 providerRunning = false;
5739 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 }
5741
5742 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005745 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005746 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005747 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005748 resolveContentProvider(name,
5749 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005750 } catch (RemoteException ex) {
5751 }
5752 if (cpi == null) {
5753 return null;
5754 }
5755
Dianne Hackbornb424b632010-08-18 15:59:05 -07005756 String msg;
5757 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5758 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005759 }
5760
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005761 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005762 && !cpi.processName.equals("system")) {
5763 // If this content provider does not run in the system
5764 // process, and the system is not yet ready to run other
5765 // processes, then fail fast instead of hanging.
5766 throw new IllegalArgumentException(
5767 "Attempt to launch content provider before system ready");
5768 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005769
5770 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5771 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772 final boolean firstClass = cpr == null;
5773 if (firstClass) {
5774 try {
5775 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005776 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005777 getApplicationInfo(
5778 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005779 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005780 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005781 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005782 + cpi.name);
5783 return null;
5784 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005785 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005786 } catch (RemoteException ex) {
5787 // pm is in same process, this will never happen.
5788 }
5789 }
5790
5791 if (r != null && cpr.canRunHere(r)) {
5792 // If this is a multiprocess provider, then just return its
5793 // info and allow the caller to instantiate it. Only do
5794 // this if the provider is the same user as the caller's
5795 // process, or can run as root (so can be in any process).
5796 return cpr;
5797 }
5798
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005799 if (DEBUG_PROVIDER) {
5800 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005801 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005802 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 }
5804
5805 // This is single process, and our app is now connecting to it.
5806 // See if we are already in the process of launching this
5807 // provider.
5808 final int N = mLaunchingProviders.size();
5809 int i;
5810 for (i=0; i<N; i++) {
5811 if (mLaunchingProviders.get(i) == cpr) {
5812 break;
5813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 }
5815
5816 // If the provider is not already being launched, then get it
5817 // started.
5818 if (i >= N) {
5819 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005820
5821 try {
5822 // Content provider is now in use, its package can't be stopped.
5823 try {
5824 AppGlobals.getPackageManager().setPackageStoppedState(
5825 cpr.appInfo.packageName, false);
5826 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005827 } catch (IllegalArgumentException e) {
5828 Slog.w(TAG, "Failed trying to unstop package "
5829 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005830 }
5831
5832 ProcessRecord proc = startProcessLocked(cpi.processName,
5833 cpr.appInfo, false, 0, "content provider",
5834 new ComponentName(cpi.applicationInfo.packageName,
5835 cpi.name), false);
5836 if (proc == null) {
5837 Slog.w(TAG, "Unable to launch app "
5838 + cpi.applicationInfo.packageName + "/"
5839 + cpi.applicationInfo.uid + " for provider "
5840 + name + ": process is bad");
5841 return null;
5842 }
5843 cpr.launchingApp = proc;
5844 mLaunchingProviders.add(cpr);
5845 } finally {
5846 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005847 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 }
5849
5850 // Make sure the provider is published (the same provider class
5851 // may be published under multiple names).
5852 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005853 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005854 }
5855 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005856 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005857 }
5858 }
5859
5860 // Wait for the provider to be published...
5861 synchronized (cpr) {
5862 while (cpr.provider == null) {
5863 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005864 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 + cpi.applicationInfo.packageName + "/"
5866 + cpi.applicationInfo.uid + " for provider "
5867 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005868 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 cpi.applicationInfo.packageName,
5870 cpi.applicationInfo.uid, name);
5871 return null;
5872 }
5873 try {
5874 cpr.wait();
5875 } catch (InterruptedException ex) {
5876 }
5877 }
5878 }
5879 return cpr;
5880 }
5881
5882 public final ContentProviderHolder getContentProvider(
5883 IApplicationThread caller, String name) {
5884 if (caller == null) {
5885 String msg = "null IApplicationThread when getting content provider "
5886 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005887 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888 throw new SecurityException(msg);
5889 }
5890
5891 return getContentProviderImpl(caller, name);
5892 }
5893
5894 private ContentProviderHolder getContentProviderExternal(String name) {
5895 return getContentProviderImpl(null, name);
5896 }
5897
5898 /**
5899 * Drop a content provider from a ProcessRecord's bookkeeping
5900 * @param cpr
5901 */
5902 public void removeContentProvider(IApplicationThread caller, String name) {
5903 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005904 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005906 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005907 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005908 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005909 return;
5910 }
5911 final ProcessRecord r = getRecordForAppLocked(caller);
5912 if (r == null) {
5913 throw new SecurityException(
5914 "Unable to find app for caller " + caller +
5915 " when removing content provider " + name);
5916 }
5917 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005918 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5919 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005920 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005922 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005923 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 return;
5925 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005926 if (decProviderCount(r, localCpr)) {
5927 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005930 }
5931 }
5932
5933 private void removeContentProviderExternal(String name) {
5934 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005935 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936 if(cpr == null) {
5937 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005938 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 return;
5940 }
5941
5942 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005943 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5944 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005945 localCpr.externals--;
5946 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005947 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005948 }
5949 updateOomAdjLocked();
5950 }
5951 }
5952
5953 public final void publishContentProviders(IApplicationThread caller,
5954 List<ContentProviderHolder> providers) {
5955 if (providers == null) {
5956 return;
5957 }
5958
5959 synchronized(this) {
5960 final ProcessRecord r = getRecordForAppLocked(caller);
5961 if (r == null) {
5962 throw new SecurityException(
5963 "Unable to find app for caller " + caller
5964 + " (pid=" + Binder.getCallingPid()
5965 + ") when publishing content providers");
5966 }
5967
5968 final long origId = Binder.clearCallingIdentity();
5969
5970 final int N = providers.size();
5971 for (int i=0; i<N; i++) {
5972 ContentProviderHolder src = providers.get(i);
5973 if (src == null || src.info == null || src.provider == null) {
5974 continue;
5975 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005976 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005977 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005978 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5979 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005980 String names[] = dst.info.authority.split(";");
5981 for (int j = 0; j < names.length; j++) {
5982 mProvidersByName.put(names[j], dst);
5983 }
5984
5985 int NL = mLaunchingProviders.size();
5986 int j;
5987 for (j=0; j<NL; j++) {
5988 if (mLaunchingProviders.get(j) == dst) {
5989 mLaunchingProviders.remove(j);
5990 j--;
5991 NL--;
5992 }
5993 }
5994 synchronized (dst) {
5995 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005996 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005997 dst.notifyAll();
5998 }
5999 updateOomAdjLocked(r);
6000 }
6001 }
6002
6003 Binder.restoreCallingIdentity(origId);
6004 }
6005 }
6006
6007 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006008 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006009 synchronized (mSelf) {
6010 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6011 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006012 if (providers != null) {
6013 for (int i=providers.size()-1; i>=0; i--) {
6014 ProviderInfo pi = (ProviderInfo)providers.get(i);
6015 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6016 Slog.w(TAG, "Not installing system proc provider " + pi.name
6017 + ": not system .apk");
6018 providers.remove(i);
6019 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006020 }
6021 }
6022 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006023 if (providers != null) {
6024 mSystemThread.installSystemProviders(providers);
6025 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006026
6027 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006028
6029 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006030 }
6031
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006032 /**
6033 * Allows app to retrieve the MIME type of a URI without having permission
6034 * to access its content provider.
6035 *
6036 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6037 *
6038 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6039 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6040 */
6041 public String getProviderMimeType(Uri uri) {
6042 final String name = uri.getAuthority();
6043 final long ident = Binder.clearCallingIdentity();
6044 ContentProviderHolder holder = null;
6045
6046 try {
6047 holder = getContentProviderExternal(name);
6048 if (holder != null) {
6049 return holder.provider.getType(uri);
6050 }
6051 } catch (RemoteException e) {
6052 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6053 return null;
6054 } finally {
6055 if (holder != null) {
6056 removeContentProviderExternal(name);
6057 }
6058 Binder.restoreCallingIdentity(ident);
6059 }
6060
6061 return null;
6062 }
6063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 // =========================================================
6065 // GLOBAL MANAGEMENT
6066 // =========================================================
6067
6068 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6069 ApplicationInfo info, String customProcess) {
6070 String proc = customProcess != null ? customProcess : info.processName;
6071 BatteryStatsImpl.Uid.Proc ps = null;
6072 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6073 synchronized (stats) {
6074 ps = stats.getProcessStatsLocked(info.uid, proc);
6075 }
6076 return new ProcessRecord(ps, thread, info, proc);
6077 }
6078
6079 final ProcessRecord addAppLocked(ApplicationInfo info) {
6080 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6081
6082 if (app == null) {
6083 app = newProcessRecordLocked(null, info, null);
6084 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006085 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 }
6087
Dianne Hackborne7f97212011-02-24 14:40:20 -08006088 // This package really, really can not be stopped.
6089 try {
6090 AppGlobals.getPackageManager().setPackageStoppedState(
6091 info.packageName, false);
6092 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006093 } catch (IllegalArgumentException e) {
6094 Slog.w(TAG, "Failed trying to unstop package "
6095 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006096 }
6097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6099 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6100 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006101 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 }
6103 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6104 mPersistentStartingProcesses.add(app);
6105 startProcessLocked(app, "added application", app.processName);
6106 }
6107
6108 return app;
6109 }
6110
6111 public void unhandledBack() {
6112 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6113 "unhandledBack()");
6114
6115 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006116 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006117 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006118 TAG, "Performing unhandledBack(): stack size = " + count);
6119 if (count > 1) {
6120 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006121 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006122 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6123 Binder.restoreCallingIdentity(origId);
6124 }
6125 }
6126 }
6127
6128 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6129 String name = uri.getAuthority();
6130 ContentProviderHolder cph = getContentProviderExternal(name);
6131 ParcelFileDescriptor pfd = null;
6132 if (cph != null) {
6133 // We record the binder invoker's uid in thread-local storage before
6134 // going to the content provider to open the file. Later, in the code
6135 // that handles all permissions checks, we look for this uid and use
6136 // that rather than the Activity Manager's own uid. The effect is that
6137 // we do the check against the caller's permissions even though it looks
6138 // to the content provider like the Activity Manager itself is making
6139 // the request.
6140 sCallerIdentity.set(new Identity(
6141 Binder.getCallingPid(), Binder.getCallingUid()));
6142 try {
6143 pfd = cph.provider.openFile(uri, "r");
6144 } catch (FileNotFoundException e) {
6145 // do nothing; pfd will be returned null
6146 } finally {
6147 // Ensure that whatever happens, we clean up the identity state
6148 sCallerIdentity.remove();
6149 }
6150
6151 // We've got the fd now, so we're done with the provider.
6152 removeContentProviderExternal(name);
6153 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006154 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 }
6156 return pfd;
6157 }
6158
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006159 // Actually is sleeping or shutting down or whatever else in the future
6160 // is an inactive state.
6161 public boolean isSleeping() {
6162 return mSleeping || mShuttingDown;
6163 }
6164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006165 public void goingToSleep() {
6166 synchronized(this) {
6167 mSleeping = true;
6168 mWindowManager.setEventDispatching(false);
6169
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006170 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006171
6172 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006173 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006174 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6175 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006176 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 }
6178 }
6179
Dianne Hackborn55280a92009-05-07 15:53:46 -07006180 public boolean shutdown(int timeout) {
6181 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6182 != PackageManager.PERMISSION_GRANTED) {
6183 throw new SecurityException("Requires permission "
6184 + android.Manifest.permission.SHUTDOWN);
6185 }
6186
6187 boolean timedout = false;
6188
6189 synchronized(this) {
6190 mShuttingDown = true;
6191 mWindowManager.setEventDispatching(false);
6192
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006193 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006194 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006195 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006196 while (mMainStack.mResumedActivity != null
6197 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006198 long delay = endTime - System.currentTimeMillis();
6199 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006200 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006201 timedout = true;
6202 break;
6203 }
6204 try {
6205 this.wait();
6206 } catch (InterruptedException e) {
6207 }
6208 }
6209 }
6210 }
6211
6212 mUsageStatsService.shutdown();
6213 mBatteryStatsService.shutdown();
6214
6215 return timedout;
6216 }
6217
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006218 public final void activitySlept(IBinder token) {
6219 if (localLOGV) Slog.v(
6220 TAG, "Activity slept: token=" + token);
6221
6222 ActivityRecord r = null;
6223
6224 final long origId = Binder.clearCallingIdentity();
6225
6226 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006227 r = mMainStack.isInStackLocked(token);
6228 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006229 mMainStack.activitySleptLocked(r);
6230 }
6231 }
6232
6233 Binder.restoreCallingIdentity(origId);
6234 }
6235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 public void wakingUp() {
6237 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006238 mWindowManager.setEventDispatching(true);
6239 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006240 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006241 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006242 }
6243 }
6244
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006245 public void stopAppSwitches() {
6246 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6247 != PackageManager.PERMISSION_GRANTED) {
6248 throw new SecurityException("Requires permission "
6249 + android.Manifest.permission.STOP_APP_SWITCHES);
6250 }
6251
6252 synchronized(this) {
6253 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6254 + APP_SWITCH_DELAY_TIME;
6255 mDidAppSwitch = false;
6256 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6257 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6258 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6259 }
6260 }
6261
6262 public void resumeAppSwitches() {
6263 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6264 != PackageManager.PERMISSION_GRANTED) {
6265 throw new SecurityException("Requires permission "
6266 + android.Manifest.permission.STOP_APP_SWITCHES);
6267 }
6268
6269 synchronized(this) {
6270 // Note that we don't execute any pending app switches... we will
6271 // let those wait until either the timeout, or the next start
6272 // activity request.
6273 mAppSwitchesAllowedTime = 0;
6274 }
6275 }
6276
6277 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6278 String name) {
6279 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6280 return true;
6281 }
6282
6283 final int perm = checkComponentPermission(
6284 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006285 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006286 if (perm == PackageManager.PERMISSION_GRANTED) {
6287 return true;
6288 }
6289
Joe Onorato8a9b2202010-02-26 18:56:32 -08006290 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006291 return false;
6292 }
6293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 public void setDebugApp(String packageName, boolean waitForDebugger,
6295 boolean persistent) {
6296 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6297 "setDebugApp()");
6298
6299 // Note that this is not really thread safe if there are multiple
6300 // callers into it at the same time, but that's not a situation we
6301 // care about.
6302 if (persistent) {
6303 final ContentResolver resolver = mContext.getContentResolver();
6304 Settings.System.putString(
6305 resolver, Settings.System.DEBUG_APP,
6306 packageName);
6307 Settings.System.putInt(
6308 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6309 waitForDebugger ? 1 : 0);
6310 }
6311
6312 synchronized (this) {
6313 if (!persistent) {
6314 mOrigDebugApp = mDebugApp;
6315 mOrigWaitForDebugger = mWaitForDebugger;
6316 }
6317 mDebugApp = packageName;
6318 mWaitForDebugger = waitForDebugger;
6319 mDebugTransient = !persistent;
6320 if (packageName != null) {
6321 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006322 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006323 Binder.restoreCallingIdentity(origId);
6324 }
6325 }
6326 }
6327
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006328 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6329 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6330 synchronized (this) {
6331 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6332 if (!isDebuggable) {
6333 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6334 throw new SecurityException("Process not debuggable: " + app.packageName);
6335 }
6336 }
6337 mProfileApp = processName;
6338 mProfileFile = profileFile;
6339 if (mProfileFd != null) {
6340 try {
6341 mProfileFd.close();
6342 } catch (IOException e) {
6343 }
6344 mProfileFd = null;
6345 }
6346 mProfileFd = profileFd;
6347 mProfileType = 0;
6348 mAutoStopProfiler = autoStopProfiler;
6349 }
6350 }
6351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006352 public void setAlwaysFinish(boolean enabled) {
6353 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6354 "setAlwaysFinish()");
6355
6356 Settings.System.putInt(
6357 mContext.getContentResolver(),
6358 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6359
6360 synchronized (this) {
6361 mAlwaysFinishActivities = enabled;
6362 }
6363 }
6364
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006365 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006366 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006367 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006368 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006369 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 }
6371 }
6372
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006373 public boolean isUserAMonkey() {
6374 // For now the fact that there is a controller implies
6375 // we have a monkey.
6376 synchronized (this) {
6377 return mController != null;
6378 }
6379 }
6380
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006381 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006382 synchronized (this) {
6383 mWatchers.register(watcher);
6384 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006385 }
6386
6387 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006388 synchronized (this) {
6389 mWatchers.unregister(watcher);
6390 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006391 }
6392
Jeff Sharkeya4620792011-05-20 15:29:23 -07006393 public void registerProcessObserver(IProcessObserver observer) {
6394 mProcessObservers.register(observer);
6395 }
6396
6397 public void unregisterProcessObserver(IProcessObserver observer) {
6398 mProcessObservers.unregister(observer);
6399 }
6400
Daniel Sandler69a48172010-06-23 16:29:36 -04006401 public void setImmersive(IBinder token, boolean immersive) {
6402 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006403 ActivityRecord r = mMainStack.isInStackLocked(token);
6404 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006405 throw new IllegalArgumentException();
6406 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006407 r.immersive = immersive;
6408 }
6409 }
6410
6411 public boolean isImmersive(IBinder token) {
6412 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006413 ActivityRecord r = mMainStack.isInStackLocked(token);
6414 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006415 throw new IllegalArgumentException();
6416 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006417 return r.immersive;
6418 }
6419 }
6420
6421 public boolean isTopActivityImmersive() {
6422 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006423 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006424 return (r != null) ? r.immersive : false;
6425 }
6426 }
6427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006428 public final void enterSafeMode() {
6429 synchronized(this) {
6430 // It only makes sense to do this before the system is ready
6431 // and started launching other packages.
6432 if (!mSystemReady) {
6433 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006434 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006435 } catch (RemoteException e) {
6436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 }
6438 }
6439 }
6440
Jeff Brownb09abc12011-01-13 21:08:27 -08006441 public final void showSafeModeOverlay() {
6442 View v = LayoutInflater.from(mContext).inflate(
6443 com.android.internal.R.layout.safe_mode, null);
6444 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6445 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6446 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6447 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6448 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6449 lp.format = v.getBackground().getOpacity();
6450 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6451 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6452 ((WindowManager)mContext.getSystemService(
6453 Context.WINDOW_SERVICE)).addView(v, lp);
6454 }
6455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006456 public void noteWakeupAlarm(IIntentSender sender) {
6457 if (!(sender instanceof PendingIntentRecord)) {
6458 return;
6459 }
6460 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6461 synchronized (stats) {
6462 if (mBatteryStatsService.isOnBattery()) {
6463 mBatteryStatsService.enforceCallingPermission();
6464 PendingIntentRecord rec = (PendingIntentRecord)sender;
6465 int MY_UID = Binder.getCallingUid();
6466 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6467 BatteryStatsImpl.Uid.Pkg pkg =
6468 stats.getPackageStatsLocked(uid, rec.key.packageName);
6469 pkg.incWakeupsLocked();
6470 }
6471 }
6472 }
6473
Dianne Hackborn64825172011-03-02 21:32:58 -08006474 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006475 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006476 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006477 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006478 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006479 // XXX Note: don't acquire main activity lock here, because the window
6480 // manager calls in with its locks held.
6481
6482 boolean killed = false;
6483 synchronized (mPidsSelfLocked) {
6484 int[] types = new int[pids.length];
6485 int worstType = 0;
6486 for (int i=0; i<pids.length; i++) {
6487 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6488 if (proc != null) {
6489 int type = proc.setAdj;
6490 types[i] = type;
6491 if (type > worstType) {
6492 worstType = type;
6493 }
6494 }
6495 }
6496
Dianne Hackborn64825172011-03-02 21:32:58 -08006497 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006498 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006499 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6500 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006502
6503 // If this is not a secure call, don't let it kill processes that
6504 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006505 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6506 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006507 }
6508
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006509 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 for (int i=0; i<pids.length; i++) {
6511 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6512 if (proc == null) {
6513 continue;
6514 }
6515 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006516 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006517 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006518 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6519 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006520 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006521 proc.killedBackground = true;
6522 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006523 }
6524 }
6525 }
6526 return killed;
6527 }
6528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 public final void startRunning(String pkg, String cls, String action,
6530 String data) {
6531 synchronized(this) {
6532 if (mStartRunning) {
6533 return;
6534 }
6535 mStartRunning = true;
6536 mTopComponent = pkg != null && cls != null
6537 ? new ComponentName(pkg, cls) : null;
6538 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6539 mTopData = data;
6540 if (!mSystemReady) {
6541 return;
6542 }
6543 }
6544
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006545 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006546 }
6547
6548 private void retrieveSettings() {
6549 final ContentResolver resolver = mContext.getContentResolver();
6550 String debugApp = Settings.System.getString(
6551 resolver, Settings.System.DEBUG_APP);
6552 boolean waitForDebugger = Settings.System.getInt(
6553 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6554 boolean alwaysFinishActivities = Settings.System.getInt(
6555 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6556
6557 Configuration configuration = new Configuration();
6558 Settings.System.getConfiguration(resolver, configuration);
6559
6560 synchronized (this) {
6561 mDebugApp = mOrigDebugApp = debugApp;
6562 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6563 mAlwaysFinishActivities = alwaysFinishActivities;
6564 // This happens before any activities are started, so we can
6565 // change mConfiguration in-place.
6566 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006567 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006568 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 }
6570 }
6571
6572 public boolean testIsSystemReady() {
6573 // no need to synchronize(this) just to read & return the value
6574 return mSystemReady;
6575 }
6576
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006577 private static File getCalledPreBootReceiversFile() {
6578 File dataDir = Environment.getDataDirectory();
6579 File systemDir = new File(dataDir, "system");
6580 File fname = new File(systemDir, "called_pre_boots.dat");
6581 return fname;
6582 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006583
6584 static final int LAST_DONE_VERSION = 10000;
6585
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006586 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6587 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6588 File file = getCalledPreBootReceiversFile();
6589 FileInputStream fis = null;
6590 try {
6591 fis = new FileInputStream(file);
6592 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006593 int fvers = dis.readInt();
6594 if (fvers == LAST_DONE_VERSION) {
6595 String vers = dis.readUTF();
6596 String codename = dis.readUTF();
6597 String build = dis.readUTF();
6598 if (android.os.Build.VERSION.RELEASE.equals(vers)
6599 && android.os.Build.VERSION.CODENAME.equals(codename)
6600 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6601 int num = dis.readInt();
6602 while (num > 0) {
6603 num--;
6604 String pkg = dis.readUTF();
6605 String cls = dis.readUTF();
6606 lastDoneReceivers.add(new ComponentName(pkg, cls));
6607 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006608 }
6609 }
6610 } catch (FileNotFoundException e) {
6611 } catch (IOException e) {
6612 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6613 } finally {
6614 if (fis != null) {
6615 try {
6616 fis.close();
6617 } catch (IOException e) {
6618 }
6619 }
6620 }
6621 return lastDoneReceivers;
6622 }
6623
6624 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6625 File file = getCalledPreBootReceiversFile();
6626 FileOutputStream fos = null;
6627 DataOutputStream dos = null;
6628 try {
6629 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6630 fos = new FileOutputStream(file);
6631 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006632 dos.writeInt(LAST_DONE_VERSION);
6633 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006634 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006635 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006636 dos.writeInt(list.size());
6637 for (int i=0; i<list.size(); i++) {
6638 dos.writeUTF(list.get(i).getPackageName());
6639 dos.writeUTF(list.get(i).getClassName());
6640 }
6641 } catch (IOException e) {
6642 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6643 file.delete();
6644 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006645 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006646 if (dos != null) {
6647 try {
6648 dos.close();
6649 } catch (IOException e) {
6650 // TODO Auto-generated catch block
6651 e.printStackTrace();
6652 }
6653 }
6654 }
6655 }
6656
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006657 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 synchronized(this) {
6659 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006660 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006661 return;
6662 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006663
6664 // Check to see if there are any update receivers to run.
6665 if (!mDidUpdate) {
6666 if (mWaitingUpdate) {
6667 return;
6668 }
6669 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6670 List<ResolveInfo> ris = null;
6671 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006672 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006673 intent, null, 0);
6674 } catch (RemoteException e) {
6675 }
6676 if (ris != null) {
6677 for (int i=ris.size()-1; i>=0; i--) {
6678 if ((ris.get(i).activityInfo.applicationInfo.flags
6679 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6680 ris.remove(i);
6681 }
6682 }
6683 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006684
6685 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6686
6687 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006688 for (int i=0; i<ris.size(); i++) {
6689 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006690 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6691 if (lastDoneReceivers.contains(comp)) {
6692 ris.remove(i);
6693 i--;
6694 }
6695 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006696
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006697 for (int i=0; i<ris.size(); i++) {
6698 ActivityInfo ai = ris.get(i).activityInfo;
6699 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6700 doneReceivers.add(comp);
6701 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006702 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006703 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006704 finisher = new IIntentReceiver.Stub() {
6705 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006706 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006707 boolean sticky) {
6708 // The raw IIntentReceiver interface is called
6709 // with the AM lock held, so redispatch to
6710 // execute our code without the lock.
6711 mHandler.post(new Runnable() {
6712 public void run() {
6713 synchronized (ActivityManagerService.this) {
6714 mDidUpdate = true;
6715 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006716 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006717 showBootMessage(mContext.getText(
6718 R.string.android_upgrading_complete),
6719 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006720 systemReady(goingCallback);
6721 }
6722 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006723 }
6724 };
6725 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006726 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006727 broadcastIntentLocked(null, null, intent, null, finisher,
6728 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006729 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006730 mWaitingUpdate = true;
6731 }
6732 }
6733 }
6734 if (mWaitingUpdate) {
6735 return;
6736 }
6737 mDidUpdate = true;
6738 }
6739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 mSystemReady = true;
6741 if (!mStartRunning) {
6742 return;
6743 }
6744 }
6745
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006746 ArrayList<ProcessRecord> procsToKill = null;
6747 synchronized(mPidsSelfLocked) {
6748 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6749 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6750 if (!isAllowedWhileBooting(proc.info)){
6751 if (procsToKill == null) {
6752 procsToKill = new ArrayList<ProcessRecord>();
6753 }
6754 procsToKill.add(proc);
6755 }
6756 }
6757 }
6758
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006759 synchronized(this) {
6760 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006761 for (int i=procsToKill.size()-1; i>=0; i--) {
6762 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006763 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006764 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006765 }
6766 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006767
6768 // Now that we have cleaned up any update processes, we
6769 // are ready to start launching real processes and know that
6770 // we won't trample on them any more.
6771 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006772 }
6773
Joe Onorato8a9b2202010-02-26 18:56:32 -08006774 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006775 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 SystemClock.uptimeMillis());
6777
6778 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006779 // Make sure we have no pre-ready processes sitting around.
6780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006781 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6782 ResolveInfo ri = mContext.getPackageManager()
6783 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006784 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 CharSequence errorMsg = null;
6786 if (ri != null) {
6787 ActivityInfo ai = ri.activityInfo;
6788 ApplicationInfo app = ai.applicationInfo;
6789 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6790 mTopAction = Intent.ACTION_FACTORY_TEST;
6791 mTopData = null;
6792 mTopComponent = new ComponentName(app.packageName,
6793 ai.name);
6794 } else {
6795 errorMsg = mContext.getResources().getText(
6796 com.android.internal.R.string.factorytest_not_system);
6797 }
6798 } else {
6799 errorMsg = mContext.getResources().getText(
6800 com.android.internal.R.string.factorytest_no_action);
6801 }
6802 if (errorMsg != null) {
6803 mTopAction = null;
6804 mTopData = null;
6805 mTopComponent = null;
6806 Message msg = Message.obtain();
6807 msg.what = SHOW_FACTORY_ERROR_MSG;
6808 msg.getData().putCharSequence("msg", errorMsg);
6809 mHandler.sendMessage(msg);
6810 }
6811 }
6812 }
6813
6814 retrieveSettings();
6815
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006816 if (goingCallback != null) goingCallback.run();
6817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 synchronized (this) {
6819 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6820 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006821 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006822 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006823 if (apps != null) {
6824 int N = apps.size();
6825 int i;
6826 for (i=0; i<N; i++) {
6827 ApplicationInfo info
6828 = (ApplicationInfo)apps.get(i);
6829 if (info != null &&
6830 !info.packageName.equals("android")) {
6831 addAppLocked(info);
6832 }
6833 }
6834 }
6835 } catch (RemoteException ex) {
6836 // pm is in same process, this will never happen.
6837 }
6838 }
6839
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006840 // Start up initial activity.
6841 mBooting = true;
6842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006843 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006844 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 Message msg = Message.obtain();
6846 msg.what = SHOW_UID_ERROR_MSG;
6847 mHandler.sendMessage(msg);
6848 }
6849 } catch (RemoteException e) {
6850 }
6851
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006852 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 }
6854 }
6855
Dan Egnorb7f03672009-12-09 16:22:32 -08006856 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006857 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006859 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006860 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006861 startAppProblemLocked(app);
6862 app.stopFreezingAllLocked();
6863 return handleAppCrashLocked(app);
6864 }
6865
Dan Egnorb7f03672009-12-09 16:22:32 -08006866 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006867 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006869 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006870 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6871 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 startAppProblemLocked(app);
6873 app.stopFreezingAllLocked();
6874 }
6875
6876 /**
6877 * Generate a process error record, suitable for attachment to a ProcessRecord.
6878 *
6879 * @param app The ProcessRecord in which the error occurred.
6880 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6881 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006882 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 * @param shortMsg Short message describing the crash.
6884 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006885 * @param stackTrace Full crash stack trace, may be null.
6886 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 * @return Returns a fully-formed AppErrorStateInfo record.
6888 */
6889 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006890 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006891 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006893 report.condition = condition;
6894 report.processName = app.processName;
6895 report.pid = app.pid;
6896 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006897 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006898 report.shortMsg = shortMsg;
6899 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006900 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901
6902 return report;
6903 }
6904
Dan Egnor42471dd2010-01-07 17:25:22 -08006905 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 synchronized (this) {
6907 app.crashing = false;
6908 app.crashingReport = null;
6909 app.notResponding = false;
6910 app.notRespondingReport = null;
6911 if (app.anrDialog == fromDialog) {
6912 app.anrDialog = null;
6913 }
6914 if (app.waitDialog == fromDialog) {
6915 app.waitDialog = null;
6916 }
6917 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006918 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006919 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006920 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6921 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006922 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924 }
6925 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006926
Dan Egnorb7f03672009-12-09 16:22:32 -08006927 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006928 long now = SystemClock.uptimeMillis();
6929
6930 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6931 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006932 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006934 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006935 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006936 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006937 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006938 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6939 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006940 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006941 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006942 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006943 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 }
6945 }
6946 if (!app.persistent) {
6947 // We don't want to start this process again until the user
6948 // explicitly does so... but for persistent process, we really
6949 // need to keep it running. If a persistent process is actually
6950 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006951 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 app.info.processName);
6953 mBadProcesses.put(app.info.processName, app.info.uid, now);
6954 app.bad = true;
6955 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6956 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006957 // Don't let services in this process be restarted and potentially
6958 // annoy the user repeatedly. Unless it is persistent, since those
6959 // processes run critical code.
6960 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006961 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 return false;
6963 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006964 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006965 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006966 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006967 if (r.app == app) {
6968 // If the top running activity is from this crashing
6969 // process, then terminate it to avoid getting in a loop.
6970 Slog.w(TAG, " Force finishing activity "
6971 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006972 int index = mMainStack.indexOfTokenLocked(r);
6973 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006974 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006975 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006976 // stopped, to avoid a situation where one will get
6977 // re-start our crashing activity once it gets resumed again.
6978 index--;
6979 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006980 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006981 if (r.state == ActivityState.RESUMED
6982 || r.state == ActivityState.PAUSING
6983 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006984 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006985 Slog.w(TAG, " Force finishing activity "
6986 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006987 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006988 Activity.RESULT_CANCELED, null, "crashed");
6989 }
6990 }
6991 }
6992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006993 }
6994
6995 // Bump up the crash count of any services currently running in the proc.
6996 if (app.services.size() != 0) {
6997 // Any services running in the application need to be placed
6998 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006999 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007001 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 sr.crashCount++;
7003 }
7004 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007005
7006 // If the crashing process is what we consider to be the "home process" and it has been
7007 // replaced by a third-party app, clear the package preferred activities from packages
7008 // with a home activity running in the process to prevent a repeatedly crashing app
7009 // from blocking the user to manually clear the list.
7010 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7011 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7012 Iterator it = mHomeProcess.activities.iterator();
7013 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007014 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007015 if (r.isHomeActivity) {
7016 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7017 try {
7018 ActivityThread.getPackageManager()
7019 .clearPackagePreferredActivities(r.packageName);
7020 } catch (RemoteException c) {
7021 // pm is in same process, this will never happen.
7022 }
7023 }
7024 }
7025 }
7026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7028 return true;
7029 }
7030
7031 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007032 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7033 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007034 skipCurrentReceiverLocked(app);
7035 }
7036
7037 void skipCurrentReceiverLocked(ProcessRecord app) {
7038 boolean reschedule = false;
7039 BroadcastRecord r = app.curReceiver;
7040 if (r != null) {
7041 // The current broadcast is waiting for this app's receiver
7042 // to be finished. Looks like that's not going to happen, so
7043 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007044 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7046 r.resultExtras, r.resultAbort, true);
7047 reschedule = true;
7048 }
7049 r = mPendingBroadcast;
7050 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007051 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007052 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007053 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007054 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7055 r.resultExtras, r.resultAbort, true);
7056 reschedule = true;
7057 }
7058 if (reschedule) {
7059 scheduleBroadcastsLocked();
7060 }
7061 }
7062
Dan Egnor60d87622009-12-16 16:32:58 -08007063 /**
7064 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7065 * The application process will exit immediately after this call returns.
7066 * @param app object of the crashing app, null for the system server
7067 * @param crashInfo describing the exception
7068 */
7069 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007070 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08007071
7072 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7073 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007074 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007075 crashInfo.exceptionClassName,
7076 crashInfo.exceptionMessage,
7077 crashInfo.throwFileName,
7078 crashInfo.throwLineNumber);
7079
Dan Egnor42471dd2010-01-07 17:25:22 -08007080 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007081
7082 crashApplication(r, crashInfo);
7083 }
7084
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007085 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007086 IBinder app,
7087 int violationMask,
7088 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007089 ProcessRecord r = findAppProcess(app, "StrictMode");
7090 if (r == null) {
7091 return;
7092 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007093
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007094 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007095 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007096 boolean logIt = true;
7097 synchronized (mAlreadyLoggedViolatedStacks) {
7098 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7099 logIt = false;
7100 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007101 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007102 // the relative pain numbers, without logging all
7103 // the stack traces repeatedly. We'd want to do
7104 // likewise in the client code, which also does
7105 // dup suppression, before the Binder call.
7106 } else {
7107 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7108 mAlreadyLoggedViolatedStacks.clear();
7109 }
7110 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7111 }
7112 }
7113 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007114 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007115 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007116 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007117
7118 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7119 AppErrorResult result = new AppErrorResult();
7120 synchronized (this) {
7121 final long origId = Binder.clearCallingIdentity();
7122
7123 Message msg = Message.obtain();
7124 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7125 HashMap<String, Object> data = new HashMap<String, Object>();
7126 data.put("result", result);
7127 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007128 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007129 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007130 msg.obj = data;
7131 mHandler.sendMessage(msg);
7132
7133 Binder.restoreCallingIdentity(origId);
7134 }
7135 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007136 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007137 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007138 }
7139
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007140 // Depending on the policy in effect, there could be a bunch of
7141 // these in quick succession so we try to batch these together to
7142 // minimize disk writes, number of dropbox entries, and maximize
7143 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007144 private void logStrictModeViolationToDropBox(
7145 ProcessRecord process,
7146 StrictMode.ViolationInfo info) {
7147 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007148 return;
7149 }
7150 final boolean isSystemApp = process == null ||
7151 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7152 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7153 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7154 final DropBoxManager dbox = (DropBoxManager)
7155 mContext.getSystemService(Context.DROPBOX_SERVICE);
7156
7157 // Exit early if the dropbox isn't configured to accept this report type.
7158 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7159
7160 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007161 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007162 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7163 synchronized (sb) {
7164 bufferWasEmpty = sb.length() == 0;
7165 appendDropBoxProcessHeaders(process, sb);
7166 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7167 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007168 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7169 if (info.violationNumThisLoop != 0) {
7170 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7171 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007172 if (info.numAnimationsRunning != 0) {
7173 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7174 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007175 if (info.broadcastIntentAction != null) {
7176 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7177 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007178 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007179 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007180 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007181 if (info.numInstances != -1) {
7182 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7183 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007184 if (info.tags != null) {
7185 for (String tag : info.tags) {
7186 sb.append("Span-Tag: ").append(tag).append("\n");
7187 }
7188 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007189 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007190 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7191 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007192 }
7193 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007194
7195 // Only buffer up to ~64k. Various logging bits truncate
7196 // things at 128k.
7197 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007198 }
7199
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007200 // Flush immediately if the buffer's grown too large, or this
7201 // is a non-system app. Non-system apps are isolated with a
7202 // different tag & policy and not batched.
7203 //
7204 // Batching is useful during internal testing with
7205 // StrictMode settings turned up high. Without batching,
7206 // thousands of separate files could be created on boot.
7207 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007208 new Thread("Error dump: " + dropboxTag) {
7209 @Override
7210 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007211 String report;
7212 synchronized (sb) {
7213 report = sb.toString();
7214 sb.delete(0, sb.length());
7215 sb.trimToSize();
7216 }
7217 if (report.length() != 0) {
7218 dbox.addText(dropboxTag, report);
7219 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007220 }
7221 }.start();
7222 return;
7223 }
7224
7225 // System app batching:
7226 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007227 // An existing dropbox-writing thread is outstanding, so
7228 // we don't need to start it up. The existing thread will
7229 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007230 return;
7231 }
7232
7233 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7234 // (After this point, we shouldn't access AMS internal data structures.)
7235 new Thread("Error dump: " + dropboxTag) {
7236 @Override
7237 public void run() {
7238 // 5 second sleep to let stacks arrive and be batched together
7239 try {
7240 Thread.sleep(5000); // 5 seconds
7241 } catch (InterruptedException e) {}
7242
7243 String errorReport;
7244 synchronized (mStrictModeBuffer) {
7245 errorReport = mStrictModeBuffer.toString();
7246 if (errorReport.length() == 0) {
7247 return;
7248 }
7249 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7250 mStrictModeBuffer.trimToSize();
7251 }
7252 dbox.addText(dropboxTag, errorReport);
7253 }
7254 }.start();
7255 }
7256
Dan Egnor60d87622009-12-16 16:32:58 -08007257 /**
7258 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7259 * @param app object of the crashing app, null for the system server
7260 * @param tag reported by the caller
7261 * @param crashInfo describing the context of the error
7262 * @return true if the process should exit immediately (WTF is fatal)
7263 */
7264 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007265 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007266 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007267
7268 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7269 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007270 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007271 tag, crashInfo.exceptionMessage);
7272
Dan Egnor42471dd2010-01-07 17:25:22 -08007273 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007274
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007275 if (r != null && r.pid != Process.myPid() &&
7276 Settings.Secure.getInt(mContext.getContentResolver(),
7277 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007278 crashApplication(r, crashInfo);
7279 return true;
7280 } else {
7281 return false;
7282 }
7283 }
7284
7285 /**
7286 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7287 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7288 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007289 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007290 if (app == null) {
7291 return null;
7292 }
7293
7294 synchronized (this) {
7295 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7296 final int NA = apps.size();
7297 for (int ia=0; ia<NA; ia++) {
7298 ProcessRecord p = apps.valueAt(ia);
7299 if (p.thread != null && p.thread.asBinder() == app) {
7300 return p;
7301 }
7302 }
7303 }
7304
Dianne Hackborncb44d962011-03-10 17:02:27 -08007305 Slog.w(TAG, "Can't find mystery application for " + reason
7306 + " from pid=" + Binder.getCallingPid()
7307 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007308 return null;
7309 }
7310 }
7311
7312 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007313 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7314 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007315 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007316 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007317 // Watchdog thread ends up invoking this function (with
7318 // a null ProcessRecord) to add the stack file to dropbox.
7319 // Do not acquire a lock on this (am) in such cases, as it
7320 // could cause a potential deadlock, if and when watchdog
7321 // is invoked due to unavailability of lock on am and it
7322 // would prevent watchdog from killing system_server.
7323 if (process == null) {
7324 sb.append("Process: system_server\n");
7325 return;
7326 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007327 // Note: ProcessRecord 'process' is guarded by the service
7328 // instance. (notably process.pkgList, which could otherwise change
7329 // concurrently during execution of this method)
7330 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007331 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007332 sb.append("Process: system_server\n");
7333 } else {
7334 sb.append("Process: ").append(process.processName).append("\n");
7335 }
Dan Egnora455d192010-03-12 08:52:28 -08007336 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007337 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007338 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7339 for (String pkg : process.pkgList) {
7340 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007341 try {
Dan Egnora455d192010-03-12 08:52:28 -08007342 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7343 if (pi != null) {
7344 sb.append(" v").append(pi.versionCode);
7345 if (pi.versionName != null) {
7346 sb.append(" (").append(pi.versionName).append(")");
7347 }
7348 }
7349 } catch (RemoteException e) {
7350 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007351 }
Dan Egnora455d192010-03-12 08:52:28 -08007352 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007353 }
Dan Egnora455d192010-03-12 08:52:28 -08007354 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007355 }
7356
7357 private static String processClass(ProcessRecord process) {
7358 if (process == null || process.pid == MY_PID) {
7359 return "system_server";
7360 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7361 return "system_app";
7362 } else {
7363 return "data_app";
7364 }
7365 }
7366
7367 /**
7368 * Write a description of an error (crash, WTF, ANR) to the drop box.
7369 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7370 * @param process which caused the error, null means the system server
7371 * @param activity which triggered the error, null if unknown
7372 * @param parent activity related to the error, null if unknown
7373 * @param subject line related to the error, null if absent
7374 * @param report in long form describing the error, null if absent
7375 * @param logFile to include in the report, null if none
7376 * @param crashInfo giving an application stack trace, null if absent
7377 */
7378 public void addErrorToDropBox(String eventType,
7379 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7380 final String report, final File logFile,
7381 final ApplicationErrorReport.CrashInfo crashInfo) {
7382 // NOTE -- this must never acquire the ActivityManagerService lock,
7383 // otherwise the watchdog may be prevented from resetting the system.
7384
7385 final String dropboxTag = processClass(process) + "_" + eventType;
7386 final DropBoxManager dbox = (DropBoxManager)
7387 mContext.getSystemService(Context.DROPBOX_SERVICE);
7388
7389 // Exit early if the dropbox isn't configured to accept this report type.
7390 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7391
7392 final StringBuilder sb = new StringBuilder(1024);
7393 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007394 if (activity != null) {
7395 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7396 }
7397 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7398 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7399 }
7400 if (parent != null && parent != activity) {
7401 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7402 }
7403 if (subject != null) {
7404 sb.append("Subject: ").append(subject).append("\n");
7405 }
7406 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007407 if (Debug.isDebuggerConnected()) {
7408 sb.append("Debugger: Connected\n");
7409 }
Dan Egnora455d192010-03-12 08:52:28 -08007410 sb.append("\n");
7411
7412 // Do the rest in a worker thread to avoid blocking the caller on I/O
7413 // (After this point, we shouldn't access AMS internal data structures.)
7414 Thread worker = new Thread("Error dump: " + dropboxTag) {
7415 @Override
7416 public void run() {
7417 if (report != null) {
7418 sb.append(report);
7419 }
7420 if (logFile != null) {
7421 try {
7422 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7423 } catch (IOException e) {
7424 Slog.e(TAG, "Error reading " + logFile, e);
7425 }
7426 }
7427 if (crashInfo != null && crashInfo.stackTrace != null) {
7428 sb.append(crashInfo.stackTrace);
7429 }
7430
7431 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7432 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7433 if (lines > 0) {
7434 sb.append("\n");
7435
7436 // Merge several logcat streams, and take the last N lines
7437 InputStreamReader input = null;
7438 try {
7439 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7440 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7441 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7442
7443 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7444 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7445 input = new InputStreamReader(logcat.getInputStream());
7446
7447 int num;
7448 char[] buf = new char[8192];
7449 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7450 } catch (IOException e) {
7451 Slog.e(TAG, "Error running logcat", e);
7452 } finally {
7453 if (input != null) try { input.close(); } catch (IOException e) {}
7454 }
7455 }
7456
7457 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007458 }
Dan Egnora455d192010-03-12 08:52:28 -08007459 };
7460
7461 if (process == null || process.pid == MY_PID) {
7462 worker.run(); // We may be about to die -- need to run this synchronously
7463 } else {
7464 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007465 }
7466 }
7467
7468 /**
7469 * Bring up the "unexpected error" dialog box for a crashing app.
7470 * Deal with edge cases (intercepts from instrumented applications,
7471 * ActivityController, error intent receivers, that sort of thing).
7472 * @param r the application crashing
7473 * @param crashInfo describing the failure
7474 */
7475 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007476 long timeMillis = System.currentTimeMillis();
7477 String shortMsg = crashInfo.exceptionClassName;
7478 String longMsg = crashInfo.exceptionMessage;
7479 String stackTrace = crashInfo.stackTrace;
7480 if (shortMsg != null && longMsg != null) {
7481 longMsg = shortMsg + ": " + longMsg;
7482 } else if (shortMsg != null) {
7483 longMsg = shortMsg;
7484 }
7485
Dan Egnor60d87622009-12-16 16:32:58 -08007486 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007487 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007488 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007489 try {
7490 String name = r != null ? r.processName : null;
7491 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007492 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007493 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007494 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007495 + " at watcher's request");
7496 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007497 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007498 }
7499 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007500 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007501 }
7502 }
7503
7504 final long origId = Binder.clearCallingIdentity();
7505
7506 // If this process is running instrumentation, finish it.
7507 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007508 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007509 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007510 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7511 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 Bundle info = new Bundle();
7513 info.putString("shortMsg", shortMsg);
7514 info.putString("longMsg", longMsg);
7515 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7516 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007517 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 }
7519
Dan Egnor60d87622009-12-16 16:32:58 -08007520 // If we can't identify the process or it's already exceeded its crash quota,
7521 // quit right away without showing a crash dialog.
7522 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007523 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007524 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007525 }
7526
7527 Message msg = Message.obtain();
7528 msg.what = SHOW_ERROR_MSG;
7529 HashMap data = new HashMap();
7530 data.put("result", result);
7531 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007532 msg.obj = data;
7533 mHandler.sendMessage(msg);
7534
7535 Binder.restoreCallingIdentity(origId);
7536 }
7537
7538 int res = result.get();
7539
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007540 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 synchronized (this) {
7542 if (r != null) {
7543 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7544 SystemClock.uptimeMillis());
7545 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007546 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007547 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007548 }
7549 }
7550
7551 if (appErrorIntent != null) {
7552 try {
7553 mContext.startActivity(appErrorIntent);
7554 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007555 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007558 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007559
7560 Intent createAppErrorIntentLocked(ProcessRecord r,
7561 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7562 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007563 if (report == null) {
7564 return null;
7565 }
7566 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7567 result.setComponent(r.errorReportReceiver);
7568 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7569 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7570 return result;
7571 }
7572
Dan Egnorb7f03672009-12-09 16:22:32 -08007573 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7574 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007575 if (r.errorReportReceiver == null) {
7576 return null;
7577 }
7578
7579 if (!r.crashing && !r.notResponding) {
7580 return null;
7581 }
7582
Dan Egnorb7f03672009-12-09 16:22:32 -08007583 ApplicationErrorReport report = new ApplicationErrorReport();
7584 report.packageName = r.info.packageName;
7585 report.installerPackageName = r.errorReportReceiver.getPackageName();
7586 report.processName = r.processName;
7587 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007588 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007589
Dan Egnorb7f03672009-12-09 16:22:32 -08007590 if (r.crashing) {
7591 report.type = ApplicationErrorReport.TYPE_CRASH;
7592 report.crashInfo = crashInfo;
7593 } else if (r.notResponding) {
7594 report.type = ApplicationErrorReport.TYPE_ANR;
7595 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007596
Dan Egnorb7f03672009-12-09 16:22:32 -08007597 report.anrInfo.activity = r.notRespondingReport.tag;
7598 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7599 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007600 }
7601
Dan Egnorb7f03672009-12-09 16:22:32 -08007602 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007603 }
7604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007605 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7606 // assume our apps are happy - lazy create the list
7607 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7608
7609 synchronized (this) {
7610
7611 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007612 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7613 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007614 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7615 // This one's in trouble, so we'll generate a report for it
7616 // crashes are higher priority (in case there's a crash *and* an anr)
7617 ActivityManager.ProcessErrorStateInfo report = null;
7618 if (app.crashing) {
7619 report = app.crashingReport;
7620 } else if (app.notResponding) {
7621 report = app.notRespondingReport;
7622 }
7623
7624 if (report != null) {
7625 if (errList == null) {
7626 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7627 }
7628 errList.add(report);
7629 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007630 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 " crashing = " + app.crashing +
7632 " notResponding = " + app.notResponding);
7633 }
7634 }
7635 }
7636 }
7637
7638 return errList;
7639 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007640
7641 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7642 if (adj >= ProcessList.EMPTY_APP_ADJ) {
7643 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7644 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7645 if (currApp != null) {
7646 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7647 }
7648 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7649 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7650 if (currApp != null) {
7651 currApp.lru = 0;
7652 }
7653 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7654 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
7655 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7656 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7657 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7658 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7659 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7660 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7661 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7662 } else {
7663 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7664 }
7665 }
7666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007667 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7668 // Lazy instantiation of list
7669 List<ActivityManager.RunningAppProcessInfo> runList = null;
7670 synchronized (this) {
7671 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007672 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7673 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007674 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7675 // Generate process state info for running application
7676 ActivityManager.RunningAppProcessInfo currApp =
7677 new ActivityManager.RunningAppProcessInfo(app.processName,
7678 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007679 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007680 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007681 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007682 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007683 if (app.persistent) {
7684 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7685 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007686 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007687 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007688 currApp.importanceReasonCode = app.adjTypeCode;
7689 if (app.adjSource instanceof ProcessRecord) {
7690 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007691 currApp.importanceReasonImportance = oomAdjToImportance(
7692 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007693 } else if (app.adjSource instanceof ActivityRecord) {
7694 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007695 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7696 }
7697 if (app.adjTarget instanceof ComponentName) {
7698 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7699 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007700 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007701 // + " lru=" + currApp.lru);
7702 if (runList == null) {
7703 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7704 }
7705 runList.add(currApp);
7706 }
7707 }
7708 }
7709 return runList;
7710 }
7711
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007712 public List<ApplicationInfo> getRunningExternalApplications() {
7713 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7714 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7715 if (runningApps != null && runningApps.size() > 0) {
7716 Set<String> extList = new HashSet<String>();
7717 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7718 if (app.pkgList != null) {
7719 for (String pkg : app.pkgList) {
7720 extList.add(pkg);
7721 }
7722 }
7723 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007724 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007725 for (String pkg : extList) {
7726 try {
7727 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7728 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7729 retList.add(info);
7730 }
7731 } catch (RemoteException e) {
7732 }
7733 }
7734 }
7735 return retList;
7736 }
7737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007738 @Override
7739 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007740 if (checkCallingPermission(android.Manifest.permission.DUMP)
7741 != PackageManager.PERMISSION_GRANTED) {
7742 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7743 + Binder.getCallingPid()
7744 + ", uid=" + Binder.getCallingUid()
7745 + " without permission "
7746 + android.Manifest.permission.DUMP);
7747 return;
7748 }
7749
7750 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007751 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007752
7753 int opti = 0;
7754 while (opti < args.length) {
7755 String opt = args[opti];
7756 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7757 break;
7758 }
7759 opti++;
7760 if ("-a".equals(opt)) {
7761 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007762 } else if ("-c".equals(opt)) {
7763 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007764 } else if ("-h".equals(opt)) {
7765 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007766 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007767 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007768 pw.println(" a[ctivities]: activity stack state");
7769 pw.println(" b[roadcasts]: broadcast state");
7770 pw.println(" i[ntents]: pending intent state");
7771 pw.println(" p[rocesses]: process state");
7772 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007773 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7774 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007775 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007776 pw.println(" all: dump all activities");
7777 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007778 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007779 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7780 pw.println(" a partial substring in a component name, a");
7781 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007782 pw.println(" -a: include all available server state.");
7783 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007784 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007785 } else {
7786 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007787 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007788 }
7789
7790 // Is the caller requesting to dump a particular piece of data?
7791 if (opti < args.length) {
7792 String cmd = args[opti];
7793 opti++;
7794 if ("activities".equals(cmd) || "a".equals(cmd)) {
7795 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007796 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007797 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007798 return;
7799 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7800 synchronized (this) {
7801 dumpBroadcastsLocked(fd, pw, args, opti, true);
7802 }
7803 return;
7804 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7805 synchronized (this) {
7806 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7807 }
7808 return;
7809 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7810 synchronized (this) {
7811 dumpProcessesLocked(fd, pw, args, opti, true);
7812 }
7813 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007814 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7815 synchronized (this) {
7816 dumpOomLocked(fd, pw, args, opti, true);
7817 }
7818 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007819 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7820 synchronized (this) {
7821 dumpProvidersLocked(fd, pw, args, opti, true);
7822 }
7823 return;
7824 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007825 String[] newArgs;
7826 String name;
7827 if (opti >= args.length) {
7828 name = null;
7829 newArgs = EMPTY_STRING_ARRAY;
7830 } else {
7831 name = args[opti];
7832 opti++;
7833 newArgs = new String[args.length - opti];
7834 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7835 }
7836 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7837 pw.println("No services match: " + name);
7838 pw.println("Use -h for help.");
7839 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007840 return;
7841 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7842 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007843 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007844 }
7845 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007846 } else {
7847 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007848 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7849 pw.println("Bad activity command, or no activities match: " + cmd);
7850 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007851 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007852 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007854 }
7855
7856 // No piece of data specified, dump everything.
7857 synchronized (this) {
7858 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007859 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007860 if (needSep) {
7861 pw.println(" ");
7862 }
7863 if (dumpAll) {
7864 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007865 }
7866 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7867 if (needSep) {
7868 pw.println(" ");
7869 }
7870 if (dumpAll) {
7871 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007872 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007873 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007874 if (needSep) {
7875 pw.println(" ");
7876 }
7877 if (dumpAll) {
7878 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007879 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007880 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007881 if (needSep) {
7882 pw.println(" ");
7883 }
7884 if (dumpAll) {
7885 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007886 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007887 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007888 if (needSep) {
7889 pw.println(" ");
7890 }
7891 if (dumpAll) {
7892 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007893 }
7894 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7895 }
7896 }
7897
7898 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007899 int opti, boolean dumpAll, boolean dumpClient) {
7900 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7901 pw.println(" Main stack:");
7902 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007903 pw.println(" ");
7904 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007905 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007906 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007907 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007908 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007909 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7910 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007912 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007913 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007914 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007915 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7916 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007917 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007918 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7919 pw.println(" ");
7920 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007921 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7922 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007923 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007924 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007925 pw.println(" ");
7926 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007927 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7928 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007930
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007931 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007932 if (mMainStack.mPausingActivity != null) {
7933 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7934 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007935 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007936 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007937 if (dumpAll) {
7938 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7939 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007940 pw.println(" mDismissKeyguardOnNextActivity: "
7941 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007944 if (mRecentTasks.size() > 0) {
7945 pw.println();
7946 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007947
7948 final int N = mRecentTasks.size();
7949 for (int i=0; i<N; i++) {
7950 TaskRecord tr = mRecentTasks.get(i);
7951 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7952 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007953 if (dumpAll) {
7954 mRecentTasks.get(i).dump(pw, " ");
7955 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007956 }
7957 }
7958
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007959 if (dumpAll) {
7960 pw.println(" ");
7961 pw.println(" mCurTask: " + mCurTask);
7962 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007963
7964 return true;
7965 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007966
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007967 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7968 int opti, boolean dumpAll) {
7969 boolean needSep = false;
7970 int numPers = 0;
7971
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007972 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7973
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007974 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7976 final int NA = procs.size();
7977 for (int ia=0; ia<NA; ia++) {
7978 if (!needSep) {
7979 pw.println(" All known processes:");
7980 needSep = true;
7981 }
7982 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007983 pw.print(r.persistent ? " *PERS*" : " *APP*");
7984 pw.print(" UID "); pw.print(procs.keyAt(ia));
7985 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 r.dump(pw, " ");
7987 if (r.persistent) {
7988 numPers++;
7989 }
7990 }
7991 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007992 }
7993
7994 if (mLruProcesses.size() > 0) {
7995 if (needSep) pw.println(" ");
7996 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007997 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007998 dumpProcessOomList(pw, this, mLruProcesses, " ",
7999 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008000 needSep = true;
8001 }
8002
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008003 if (dumpAll) {
8004 synchronized (mPidsSelfLocked) {
8005 if (mPidsSelfLocked.size() > 0) {
8006 if (needSep) pw.println(" ");
8007 needSep = true;
8008 pw.println(" PID mappings:");
8009 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8010 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8011 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008013 }
8014 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008015 }
8016
8017 if (mForegroundProcesses.size() > 0) {
8018 if (needSep) pw.println(" ");
8019 needSep = true;
8020 pw.println(" Foreground Processes:");
8021 for (int i=0; i<mForegroundProcesses.size(); i++) {
8022 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8023 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008025 }
8026
8027 if (mPersistentStartingProcesses.size() > 0) {
8028 if (needSep) pw.println(" ");
8029 needSep = true;
8030 pw.println(" Persisent processes that are starting:");
8031 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008032 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008033 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008035 if (mRemovedProcesses.size() > 0) {
8036 if (needSep) pw.println(" ");
8037 needSep = true;
8038 pw.println(" Processes that are being removed:");
8039 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008040 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008041 }
8042
8043 if (mProcessesOnHold.size() > 0) {
8044 if (needSep) pw.println(" ");
8045 needSep = true;
8046 pw.println(" Processes that are on old until the system is ready:");
8047 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008048 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008050
Dianne Hackborn287952c2010-09-22 22:34:31 -07008051 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008052
8053 if (mProcessCrashTimes.getMap().size() > 0) {
8054 if (needSep) pw.println(" ");
8055 needSep = true;
8056 pw.println(" Time since processes crashed:");
8057 long now = SystemClock.uptimeMillis();
8058 for (Map.Entry<String, SparseArray<Long>> procs
8059 : mProcessCrashTimes.getMap().entrySet()) {
8060 SparseArray<Long> uids = procs.getValue();
8061 final int N = uids.size();
8062 for (int i=0; i<N; i++) {
8063 pw.print(" Process "); pw.print(procs.getKey());
8064 pw.print(" uid "); pw.print(uids.keyAt(i));
8065 pw.print(": last crashed ");
8066 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008067 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008068 }
8069 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008072 if (mBadProcesses.getMap().size() > 0) {
8073 if (needSep) pw.println(" ");
8074 needSep = true;
8075 pw.println(" Bad processes:");
8076 for (Map.Entry<String, SparseArray<Long>> procs
8077 : mBadProcesses.getMap().entrySet()) {
8078 SparseArray<Long> uids = procs.getValue();
8079 final int N = uids.size();
8080 for (int i=0; i<N; i++) {
8081 pw.print(" Bad process "); pw.print(procs.getKey());
8082 pw.print(" uid "); pw.print(uids.keyAt(i));
8083 pw.print(": crashed at time ");
8084 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008085 }
8086 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008089 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008090 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008091 if (mHeavyWeightProcess != null) {
8092 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8093 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008094 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008095 if (dumpAll) {
8096 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008097 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008098 pw.println(" mScreenCompatPackages:");
8099 for (Map.Entry<String, Integer> entry
8100 : mCompatModePackages.getPackages().entrySet()) {
8101 String pkg = entry.getKey();
8102 int mode = entry.getValue();
8103 pw.print(" "); pw.print(pkg); pw.print(": ");
8104 pw.print(mode); pw.println();
8105 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008106 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008107 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008108 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8109 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8110 || mOrigWaitForDebugger) {
8111 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8112 + " mDebugTransient=" + mDebugTransient
8113 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8114 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008115 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8116 || mProfileFd != null) {
8117 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8118 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8119 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8120 + mAutoStopProfiler);
8121 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008122 if (mAlwaysFinishActivities || mController != null) {
8123 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8124 + " mController=" + mController);
8125 }
8126 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008127 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008128 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008129 + " mProcessesReady=" + mProcessesReady
8130 + " mSystemReady=" + mSystemReady);
8131 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 + " mBooted=" + mBooted
8133 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008134 pw.print(" mLastPowerCheckRealtime=");
8135 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8136 pw.println("");
8137 pw.print(" mLastPowerCheckUptime=");
8138 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8139 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008140 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8141 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008142 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008144
8145 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 }
8147
Dianne Hackborn287952c2010-09-22 22:34:31 -07008148 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8149 int opti, boolean needSep, boolean dumpAll) {
8150 if (mProcessesToGc.size() > 0) {
8151 if (needSep) pw.println(" ");
8152 needSep = true;
8153 pw.println(" Processes that are waiting to GC:");
8154 long now = SystemClock.uptimeMillis();
8155 for (int i=0; i<mProcessesToGc.size(); i++) {
8156 ProcessRecord proc = mProcessesToGc.get(i);
8157 pw.print(" Process "); pw.println(proc);
8158 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8159 pw.print(", last gced=");
8160 pw.print(now-proc.lastRequestedGc);
8161 pw.print(" ms ago, last lowMem=");
8162 pw.print(now-proc.lastLowMemory);
8163 pw.println(" ms ago");
8164
8165 }
8166 }
8167 return needSep;
8168 }
8169
8170 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8171 int opti, boolean dumpAll) {
8172 boolean needSep = false;
8173
8174 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008175 if (needSep) pw.println(" ");
8176 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008177 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008178 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8179 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8180 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8181 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8182 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8183 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8184 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8185 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8186 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8187 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8188 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008189
8190 if (needSep) pw.println(" ");
8191 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008192 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008193 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008194 "Proc", "PERS", true);
8195 needSep = true;
8196 }
8197
8198 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8199
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008200 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008201 pw.println(" mHomeProcess: " + mHomeProcess);
8202 if (mHeavyWeightProcess != null) {
8203 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8204 }
8205
8206 return true;
8207 }
8208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008209 /**
8210 * There are three ways to call this:
8211 * - no service specified: dump all the services
8212 * - a flattened component name that matched an existing service was specified as the
8213 * first arg: dump that one service
8214 * - the first arg isn't the flattened component name of an existing service:
8215 * dump all services whose component contains the first arg as a substring
8216 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008217 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8218 int opti, boolean dumpAll) {
8219 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008220
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008221 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008222 synchronized (this) {
8223 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008224 services.add(r1);
8225 }
8226 }
8227 } else {
8228 ComponentName componentName = name != null
8229 ? ComponentName.unflattenFromString(name) : null;
8230 int objectId = 0;
8231 if (componentName == null) {
8232 // Not a '/' separated full component name; maybe an object ID?
8233 try {
8234 objectId = Integer.parseInt(name, 16);
8235 name = null;
8236 componentName = null;
8237 } catch (RuntimeException e) {
8238 }
8239 }
8240
8241 synchronized (this) {
8242 for (ServiceRecord r1 : mServices.values()) {
8243 if (componentName != null) {
8244 if (r1.name.equals(componentName)) {
8245 services.add(r1);
8246 }
8247 } else if (name != null) {
8248 if (r1.name.flattenToString().contains(name)) {
8249 services.add(r1);
8250 }
8251 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008252 services.add(r1);
8253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008254 }
8255 }
8256 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008257
8258 if (services.size() <= 0) {
8259 return false;
8260 }
8261
8262 boolean needSep = false;
8263 for (int i=0; i<services.size(); i++) {
8264 if (needSep) {
8265 pw.println();
8266 }
8267 needSep = true;
8268 dumpService("", fd, pw, services.get(i), args, dumpAll);
8269 }
8270 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008271 }
8272
8273 /**
8274 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8275 * there is a thread associated with the service.
8276 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008277 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8278 final ServiceRecord r, String[] args, boolean dumpAll) {
8279 String innerPrefix = prefix + " ";
8280 synchronized (this) {
8281 pw.print(prefix); pw.print("SERVICE ");
8282 pw.print(r.shortName); pw.print(" ");
8283 pw.print(Integer.toHexString(System.identityHashCode(r)));
8284 pw.print(" pid=");
8285 if (r.app != null) pw.println(r.app.pid);
8286 else pw.println("(not running)");
8287 if (dumpAll) {
8288 r.dump(pw, innerPrefix);
8289 }
8290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008291 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008292 pw.print(prefix); pw.println(" Client:");
8293 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008294 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008295 TransferPipe tp = new TransferPipe();
8296 try {
8297 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8298 tp.setBufferPrefix(prefix + " ");
8299 tp.go(fd);
8300 } finally {
8301 tp.kill();
8302 }
8303 } catch (IOException e) {
8304 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008305 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008306 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 }
8308 }
8309 }
8310
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008311 static class ItemMatcher {
8312 ArrayList<ComponentName> components;
8313 ArrayList<String> strings;
8314 ArrayList<Integer> objects;
8315 boolean all;
8316
8317 ItemMatcher() {
8318 all = true;
8319 }
8320
8321 void build(String name) {
8322 ComponentName componentName = ComponentName.unflattenFromString(name);
8323 if (componentName != null) {
8324 if (components == null) {
8325 components = new ArrayList<ComponentName>();
8326 }
8327 components.add(componentName);
8328 all = false;
8329 } else {
8330 int objectId = 0;
8331 // Not a '/' separated full component name; maybe an object ID?
8332 try {
8333 objectId = Integer.parseInt(name, 16);
8334 if (objects == null) {
8335 objects = new ArrayList<Integer>();
8336 }
8337 objects.add(objectId);
8338 all = false;
8339 } catch (RuntimeException e) {
8340 // Not an integer; just do string match.
8341 if (strings == null) {
8342 strings = new ArrayList<String>();
8343 }
8344 strings.add(name);
8345 all = false;
8346 }
8347 }
8348 }
8349
8350 int build(String[] args, int opti) {
8351 for (; opti<args.length; opti++) {
8352 String name = args[opti];
8353 if ("--".equals(name)) {
8354 return opti+1;
8355 }
8356 build(name);
8357 }
8358 return opti;
8359 }
8360
8361 boolean match(Object object, ComponentName comp) {
8362 if (all) {
8363 return true;
8364 }
8365 if (components != null) {
8366 for (int i=0; i<components.size(); i++) {
8367 if (components.get(i).equals(comp)) {
8368 return true;
8369 }
8370 }
8371 }
8372 if (objects != null) {
8373 for (int i=0; i<objects.size(); i++) {
8374 if (System.identityHashCode(object) == objects.get(i)) {
8375 return true;
8376 }
8377 }
8378 }
8379 if (strings != null) {
8380 String flat = comp.flattenToString();
8381 for (int i=0; i<strings.size(); i++) {
8382 if (flat.contains(strings.get(i))) {
8383 return true;
8384 }
8385 }
8386 }
8387 return false;
8388 }
8389 }
8390
Dianne Hackborn625ac272010-09-17 18:29:22 -07008391 /**
8392 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008393 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008394 * - the cmd arg isn't the flattened component name of an existing activity:
8395 * dump all activity whose component contains the cmd as a substring
8396 * - A hex number of the ActivityRecord object instance.
8397 */
8398 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8399 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008400 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008401
8402 if ("all".equals(name)) {
8403 synchronized (this) {
8404 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008405 activities.add(r1);
8406 }
8407 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008408 } else if ("top".equals(name)) {
8409 synchronized (this) {
8410 final int N = mMainStack.mHistory.size();
8411 if (N > 0) {
8412 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8413 }
8414 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008415 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008416 ItemMatcher matcher = new ItemMatcher();
8417 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008418
8419 synchronized (this) {
8420 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008421 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008422 activities.add(r1);
8423 }
8424 }
8425 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008426 }
8427
8428 if (activities.size() <= 0) {
8429 return false;
8430 }
8431
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008432 String[] newArgs = new String[args.length - opti];
8433 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8434
Dianne Hackborn30d71892010-12-11 10:37:55 -08008435 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008436 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008437 for (int i=activities.size()-1; i>=0; i--) {
8438 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008439 if (needSep) {
8440 pw.println();
8441 }
8442 needSep = true;
8443 synchronized (this) {
8444 if (lastTask != r.task) {
8445 lastTask = r.task;
8446 pw.print("TASK "); pw.print(lastTask.affinity);
8447 pw.print(" id="); pw.println(lastTask.taskId);
8448 if (dumpAll) {
8449 lastTask.dump(pw, " ");
8450 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008451 }
8452 }
8453 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008454 }
8455 return true;
8456 }
8457
8458 /**
8459 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8460 * there is a thread associated with the activity.
8461 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008462 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008463 final ActivityRecord r, String[] args, boolean dumpAll) {
8464 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008465 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008466 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8467 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8468 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008469 if (r.app != null) pw.println(r.app.pid);
8470 else pw.println("(not running)");
8471 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008472 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008473 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008474 }
8475 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008476 // flush anything that is already in the PrintWriter since the thread is going
8477 // to write to the file descriptor directly
8478 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008479 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008480 TransferPipe tp = new TransferPipe();
8481 try {
8482 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8483 innerPrefix, args);
8484 tp.go(fd);
8485 } finally {
8486 tp.kill();
8487 }
8488 } catch (IOException e) {
8489 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008490 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008491 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008492 }
8493 }
8494 }
8495
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008496 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8497 int opti, boolean dumpAll) {
8498 boolean needSep = false;
8499
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008500 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008501 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008502 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008503 pw.println(" Registered Receivers:");
8504 Iterator it = mRegisteredReceivers.values().iterator();
8505 while (it.hasNext()) {
8506 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008507 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508 r.dump(pw, " ");
8509 }
8510 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008511
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008512 pw.println();
8513 pw.println(" Receiver Resolver Table:");
8514 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008515 needSep = true;
8516 }
8517
8518 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8519 || mPendingBroadcast != null) {
8520 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008521 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008522 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008524 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8525 pw.println(" Broadcast #" + i + ":");
8526 mParallelBroadcasts.get(i).dump(pw, " ");
8527 }
8528 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008529 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008530 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008531 }
8532 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8533 pw.println(" Serialized Broadcast #" + i + ":");
8534 mOrderedBroadcasts.get(i).dump(pw, " ");
8535 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008536 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008537 pw.println(" Pending broadcast:");
8538 if (mPendingBroadcast != null) {
8539 mPendingBroadcast.dump(pw, " ");
8540 } else {
8541 pw.println(" (null)");
8542 }
8543 needSep = true;
8544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008545
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008546 if (needSep) {
8547 pw.println();
8548 }
8549 pw.println(" Historical broadcasts:");
8550 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8551 BroadcastRecord r = mBroadcastHistory[i];
8552 if (r == null) {
8553 break;
8554 }
8555 if (dumpAll) {
8556 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8557 r.dump(pw, " ");
8558 } else {
8559 if (i >= 50) {
8560 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008561 break;
8562 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008563 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008564 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008565 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008566 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008567
8568 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008569 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008570 pw.println(" Sticky broadcasts:");
8571 StringBuilder sb = new StringBuilder(128);
8572 for (Map.Entry<String, ArrayList<Intent>> ent
8573 : mStickyBroadcasts.entrySet()) {
8574 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008575 if (dumpAll) {
8576 pw.println(":");
8577 ArrayList<Intent> intents = ent.getValue();
8578 final int N = intents.size();
8579 for (int i=0; i<N; i++) {
8580 sb.setLength(0);
8581 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008582 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008583 pw.println(sb.toString());
8584 Bundle bundle = intents.get(i).getExtras();
8585 if (bundle != null) {
8586 pw.print(" ");
8587 pw.println(bundle.toString());
8588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008590 } else {
8591 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008592 }
8593 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008594 needSep = true;
8595 }
8596
8597 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008598 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008599 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008600 pw.println(" mHandler:");
8601 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008602 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008603 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008604
8605 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 }
8607
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008608 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008609 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008610 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008611
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008612 ItemMatcher matcher = new ItemMatcher();
8613 matcher.build(args, opti);
8614
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008615 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8616 if (mServices.size() > 0) {
8617 pw.println(" Active services:");
8618 long nowReal = SystemClock.elapsedRealtime();
8619 Iterator<ServiceRecord> it = mServices.values().iterator();
8620 needSep = false;
8621 while (it.hasNext()) {
8622 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008623 if (!matcher.match(r, r.name)) {
8624 continue;
8625 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008626 if (needSep) {
8627 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008629 pw.print(" * "); pw.println(r);
8630 if (dumpAll) {
8631 r.dump(pw, " ");
8632 needSep = true;
8633 } else {
8634 pw.print(" app="); pw.println(r.app);
8635 pw.print(" created=");
8636 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8637 pw.print(" started="); pw.print(r.startRequested);
8638 pw.print(" connections="); pw.println(r.connections.size());
8639 }
8640 if (dumpClient && r.app != null && r.app.thread != null) {
8641 pw.println(" Client:");
8642 pw.flush();
8643 try {
8644 TransferPipe tp = new TransferPipe();
8645 try {
8646 r.app.thread.dumpService(
8647 tp.getWriteFd().getFileDescriptor(), r, args);
8648 tp.setBufferPrefix(" ");
8649 // Short timeout, since blocking here can
8650 // deadlock with the application.
8651 tp.go(fd, 2000);
8652 } finally {
8653 tp.kill();
8654 }
8655 } catch (IOException e) {
8656 pw.println(" Failure while dumping the service: " + e);
8657 } catch (RemoteException e) {
8658 pw.println(" Got a RemoteException while dumping the service");
8659 }
8660 needSep = true;
8661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008662 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008663 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008664 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008665
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008666 if (mPendingServices.size() > 0) {
8667 if (needSep) pw.println(" ");
8668 pw.println(" Pending services:");
8669 for (int i=0; i<mPendingServices.size(); i++) {
8670 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008671 if (!matcher.match(r, r.name)) {
8672 continue;
8673 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008674 pw.print(" * Pending "); pw.println(r);
8675 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008676 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008677 needSep = true;
8678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008679
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008680 if (mRestartingServices.size() > 0) {
8681 if (needSep) pw.println(" ");
8682 pw.println(" Restarting services:");
8683 for (int i=0; i<mRestartingServices.size(); i++) {
8684 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008685 if (!matcher.match(r, r.name)) {
8686 continue;
8687 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008688 pw.print(" * Restarting "); pw.println(r);
8689 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008691 needSep = true;
8692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008693
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008694 if (mStoppingServices.size() > 0) {
8695 if (needSep) pw.println(" ");
8696 pw.println(" Stopping services:");
8697 for (int i=0; i<mStoppingServices.size(); i++) {
8698 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008699 if (!matcher.match(r, r.name)) {
8700 continue;
8701 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008702 pw.print(" * Stopping "); pw.println(r);
8703 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008704 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008705 needSep = true;
8706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008707
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008708 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709 if (mServiceConnections.size() > 0) {
8710 if (needSep) pw.println(" ");
8711 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008712 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008713 = mServiceConnections.values().iterator();
8714 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008715 ArrayList<ConnectionRecord> r = it.next();
8716 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008717 ConnectionRecord cr = r.get(i);
8718 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8719 continue;
8720 }
8721 pw.print(" * "); pw.println(cr);
8722 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008724 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008725 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008726 }
8727 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008728
8729 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008730 }
8731
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008732 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8733 int opti, boolean dumpAll) {
8734 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008735
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008736 ItemMatcher matcher = new ItemMatcher();
8737 matcher.build(args, opti);
8738
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008739 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8740 if (mProvidersByClass.size() > 0) {
8741 if (needSep) pw.println(" ");
8742 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008743 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008744 = mProvidersByClass.entrySet().iterator();
8745 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008746 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008747 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008748 ComponentName comp = e.getKey();
8749 String cls = comp.getClassName();
8750 int end = cls.lastIndexOf('.');
8751 if (end > 0 && end < (cls.length()-2)) {
8752 cls = cls.substring(end+1);
8753 }
8754 if (!matcher.match(r, comp)) {
8755 continue;
8756 }
8757 pw.print(" * "); pw.print(cls); pw.print(" (");
8758 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008759 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008760 pw.println();
8761 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008762 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008763 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008764 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008765 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008766 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008767 } else {
8768 pw.println();
8769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008771 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008772 needSep = true;
8773 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008774
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008775 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008776 if (mProvidersByName.size() > 0) {
8777 pw.println(" ");
8778 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008779 Iterator<Map.Entry<String, ContentProviderRecord>> it
8780 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008781 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008782 Map.Entry<String, ContentProviderRecord> e = it.next();
8783 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008784 if (!matcher.match(r, r.name)) {
8785 continue;
8786 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008787 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8788 pw.println(r);
8789 }
8790 needSep = true;
8791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008792 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008793
8794 if (mLaunchingProviders.size() > 0) {
8795 if (needSep) pw.println(" ");
8796 pw.println(" Launching content providers:");
8797 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8798 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8799 pw.println(mLaunchingProviders.get(i));
8800 }
8801 needSep = true;
8802 }
8803
8804 if (mGrantedUriPermissions.size() > 0) {
8805 pw.println();
8806 pw.println("Granted Uri Permissions:");
8807 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8808 int uid = mGrantedUriPermissions.keyAt(i);
8809 HashMap<Uri, UriPermission> perms
8810 = mGrantedUriPermissions.valueAt(i);
8811 pw.print(" * UID "); pw.print(uid);
8812 pw.println(" holds:");
8813 for (UriPermission perm : perms.values()) {
8814 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008815 if (dumpAll) {
8816 perm.dump(pw, " ");
8817 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008818 }
8819 }
8820 needSep = true;
8821 }
8822
8823 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008824 }
8825
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008826 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8827 int opti, boolean dumpAll) {
8828 boolean needSep = false;
8829
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008830 if (this.mIntentSenderRecords.size() > 0) {
8831 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8832 Iterator<WeakReference<PendingIntentRecord>> it
8833 = mIntentSenderRecords.values().iterator();
8834 while (it.hasNext()) {
8835 WeakReference<PendingIntentRecord> ref = it.next();
8836 PendingIntentRecord rec = ref != null ? ref.get(): null;
8837 needSep = true;
8838 if (rec != null) {
8839 pw.print(" * "); pw.println(rec);
8840 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008842 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008843 } else {
8844 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 }
8846 }
8847 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008848
8849 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008850 }
8851
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008852 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8853 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008854 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008855 boolean needNL = false;
8856 final String innerPrefix = prefix + " ";
8857 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008858 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008859 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008860 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 if (needNL) {
8862 pw.println(" ");
8863 needNL = false;
8864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008865 if (lastTask != r.task) {
8866 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008867 pw.print(prefix);
8868 pw.print(full ? "* " : " ");
8869 pw.println(lastTask);
8870 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008871 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008872 } else if (complete) {
8873 // Complete + brief == give a summary. Isn't that obvious?!?
8874 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008875 pw.print(prefix); pw.print(" ");
8876 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008877 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008880 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8881 pw.print(" #"); pw.print(i); pw.print(": ");
8882 pw.println(r);
8883 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008884 r.dump(pw, innerPrefix);
8885 } else if (complete) {
8886 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008887 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 if (r.app != null) {
8889 pw.print(innerPrefix); pw.println(r.app);
8890 }
8891 }
8892 if (client && r.app != null && r.app.thread != null) {
8893 // flush anything that is already in the PrintWriter since the thread is going
8894 // to write to the file descriptor directly
8895 pw.flush();
8896 try {
8897 TransferPipe tp = new TransferPipe();
8898 try {
8899 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8900 innerPrefix, args);
8901 // Short timeout, since blocking here can
8902 // deadlock with the application.
8903 tp.go(fd, 2000);
8904 } finally {
8905 tp.kill();
8906 }
8907 } catch (IOException e) {
8908 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8909 } catch (RemoteException e) {
8910 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8911 }
8912 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008913 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008914 }
8915 }
8916
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008917 private static String buildOomTag(String prefix, String space, int val, int base) {
8918 if (val == base) {
8919 if (space == null) return prefix;
8920 return prefix + " ";
8921 }
8922 return prefix + "+" + Integer.toString(val-base);
8923 }
8924
8925 private static final int dumpProcessList(PrintWriter pw,
8926 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008927 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008929 final int N = list.size()-1;
8930 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008931 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008932 pw.println(String.format("%s%s #%2d: %s",
8933 prefix, (r.persistent ? persistentLabel : normalLabel),
8934 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008935 if (r.persistent) {
8936 numPers++;
8937 }
8938 }
8939 return numPers;
8940 }
8941
Dianne Hackborn287952c2010-09-22 22:34:31 -07008942 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008943 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008944 String prefix, String normalLabel, String persistentLabel,
8945 boolean inclDetails) {
8946
Dianne Hackborn905577f2011-09-07 18:31:28 -07008947 ArrayList<Pair<ProcessRecord, Integer>> list
8948 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8949 for (int i=0; i<origList.size(); i++) {
8950 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8951 }
8952
8953 Comparator<Pair<ProcessRecord, Integer>> comparator
8954 = new Comparator<Pair<ProcessRecord, Integer>>() {
8955 @Override
8956 public int compare(Pair<ProcessRecord, Integer> object1,
8957 Pair<ProcessRecord, Integer> object2) {
8958 if (object1.first.setAdj != object2.first.setAdj) {
8959 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8960 }
8961 if (object1.second.intValue() != object2.second.intValue()) {
8962 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8963 }
8964 return 0;
8965 }
8966 };
8967
8968 Collections.sort(list, comparator);
8969
Dianne Hackborn287952c2010-09-22 22:34:31 -07008970 final long curRealtime = SystemClock.elapsedRealtime();
8971 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8972 final long curUptime = SystemClock.uptimeMillis();
8973 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8974
8975 final int N = list.size()-1;
8976 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008977 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008978 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008979 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8980 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8981 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8982 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8983 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8984 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8985 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8986 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8987 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8988 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8989 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8990 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8991 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8992 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8993 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8994 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8995 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8996 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8997 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8998 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8999 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9000 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009001 } else {
9002 oomAdj = Integer.toString(r.setAdj);
9003 }
9004 String schedGroup;
9005 switch (r.setSchedGroup) {
9006 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9007 schedGroup = "B";
9008 break;
9009 case Process.THREAD_GROUP_DEFAULT:
9010 schedGroup = "F";
9011 break;
9012 default:
9013 schedGroup = Integer.toString(r.setSchedGroup);
9014 break;
9015 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009016 String foreground;
9017 if (r.foregroundActivities) {
9018 foreground = "A";
9019 } else if (r.foregroundServices) {
9020 foreground = "S";
9021 } else {
9022 foreground = " ";
9023 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009024 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009025 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009026 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009027 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009028 if (r.adjSource != null || r.adjTarget != null) {
9029 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009030 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009031 if (r.adjTarget instanceof ComponentName) {
9032 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9033 } else if (r.adjTarget != null) {
9034 pw.print(r.adjTarget.toString());
9035 } else {
9036 pw.print("{null}");
9037 }
9038 pw.print("<=");
9039 if (r.adjSource instanceof ProcessRecord) {
9040 pw.print("Proc{");
9041 pw.print(((ProcessRecord)r.adjSource).toShortString());
9042 pw.println("}");
9043 } else if (r.adjSource != null) {
9044 pw.println(r.adjSource.toString());
9045 } else {
9046 pw.println("{null}");
9047 }
9048 }
9049 if (inclDetails) {
9050 pw.print(prefix);
9051 pw.print(" ");
9052 pw.print("oom: max="); pw.print(r.maxAdj);
9053 pw.print(" hidden="); pw.print(r.hiddenAdj);
9054 pw.print(" curRaw="); pw.print(r.curRawAdj);
9055 pw.print(" setRaw="); pw.print(r.setRawAdj);
9056 pw.print(" cur="); pw.print(r.curAdj);
9057 pw.print(" set="); pw.println(r.setAdj);
9058 pw.print(prefix);
9059 pw.print(" ");
9060 pw.print("keeping="); pw.print(r.keeping);
9061 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009062 pw.print(" empty="); pw.print(r.empty);
9063 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009064
9065 if (!r.keeping) {
9066 if (r.lastWakeTime != 0) {
9067 long wtime;
9068 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9069 synchronized (stats) {
9070 wtime = stats.getProcessWakeTime(r.info.uid,
9071 r.pid, curRealtime);
9072 }
9073 long timeUsed = wtime - r.lastWakeTime;
9074 pw.print(prefix);
9075 pw.print(" ");
9076 pw.print("keep awake over ");
9077 TimeUtils.formatDuration(realtimeSince, pw);
9078 pw.print(" used ");
9079 TimeUtils.formatDuration(timeUsed, pw);
9080 pw.print(" (");
9081 pw.print((timeUsed*100)/realtimeSince);
9082 pw.println("%)");
9083 }
9084 if (r.lastCpuTime != 0) {
9085 long timeUsed = r.curCpuTime - r.lastCpuTime;
9086 pw.print(prefix);
9087 pw.print(" ");
9088 pw.print("run cpu over ");
9089 TimeUtils.formatDuration(uptimeSince, pw);
9090 pw.print(" used ");
9091 TimeUtils.formatDuration(timeUsed, pw);
9092 pw.print(" (");
9093 pw.print((timeUsed*100)/uptimeSince);
9094 pw.println("%)");
9095 }
9096 }
9097 }
9098 }
9099 }
9100
Dianne Hackbornb437e092011-08-05 17:50:29 -07009101 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009102 ArrayList<ProcessRecord> procs;
9103 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009104 if (args != null && args.length > start
9105 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009106 procs = new ArrayList<ProcessRecord>();
9107 int pid = -1;
9108 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009109 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009110 } catch (NumberFormatException e) {
9111
9112 }
9113 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9114 ProcessRecord proc = mLruProcesses.get(i);
9115 if (proc.pid == pid) {
9116 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009117 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009118 procs.add(proc);
9119 }
9120 }
9121 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009122 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009123 return null;
9124 }
9125 } else {
9126 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9127 }
9128 }
9129 return procs;
9130 }
9131
9132 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9133 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009134 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009135 if (procs == null) {
9136 return;
9137 }
9138
9139 long uptime = SystemClock.uptimeMillis();
9140 long realtime = SystemClock.elapsedRealtime();
9141 pw.println("Applications Graphics Acceleration Info:");
9142 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9143
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009144 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9145 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009146 if (r.thread != null) {
9147 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9148 pw.flush();
9149 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009150 TransferPipe tp = new TransferPipe();
9151 try {
9152 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9153 tp.go(fd);
9154 } finally {
9155 tp.kill();
9156 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009157 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009158 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009159 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009160 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009161 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009162 pw.flush();
9163 }
9164 }
9165 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009166 }
9167
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009168 final static class MemItem {
9169 final String label;
9170 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009171 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009172
9173 public MemItem(String _label, long _pss) {
9174 label = _label;
9175 pss = _pss;
9176 }
9177 }
9178
Dianne Hackbornb437e092011-08-05 17:50:29 -07009179 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9180 boolean sort) {
9181 if (sort) {
9182 Collections.sort(items, new Comparator<MemItem>() {
9183 @Override
9184 public int compare(MemItem lhs, MemItem rhs) {
9185 if (lhs.pss < rhs.pss) {
9186 return 1;
9187 } else if (lhs.pss > rhs.pss) {
9188 return -1;
9189 }
9190 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009191 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009192 });
9193 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009194
9195 for (int i=0; i<items.size(); i++) {
9196 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009197 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9198 if (mi.subitems != null) {
9199 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9200 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009201 }
9202 }
9203
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009204 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9205 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009206 boolean dumpAll = false;
9207
9208 int opti = 0;
9209 while (opti < args.length) {
9210 String opt = args[opti];
9211 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9212 break;
9213 }
9214 opti++;
9215 if ("-a".equals(opt)) {
9216 dumpAll = true;
9217 } else if ("-h".equals(opt)) {
9218 pw.println("meminfo dump options: [-a] [process]");
9219 pw.println(" -a: include all available information for each process.");
9220 pw.println("If [process] is specified it can be the name or ");
9221 pw.println("pid of a specific process to dump.");
9222 return;
9223 } else {
9224 pw.println("Unknown argument: " + opt + "; use -h for help");
9225 }
9226 }
9227
9228 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009229 if (procs == null) {
9230 return;
9231 }
9232
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009233 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009234 long uptime = SystemClock.uptimeMillis();
9235 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009236
9237 if (procs.size() == 1 || isCheckinRequest) {
9238 dumpAll = true;
9239 }
9240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009241 if (isCheckinRequest) {
9242 // short checkin version
9243 pw.println(uptime + "," + realtime);
9244 pw.flush();
9245 } else {
9246 pw.println("Applications Memory Usage (kB):");
9247 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9248 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009249
Dianne Hackbornb437e092011-08-05 17:50:29 -07009250 String[] innerArgs = new String[args.length-opti];
9251 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9252
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009253 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9254 long nativePss=0, dalvikPss=0, otherPss=0;
9255 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9256
Dianne Hackbornb437e092011-08-05 17:50:29 -07009257 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009258 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9259 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9260 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009261 };
9262 final String[] oomLabel = new String[] {
9263 "System", "Persistent", "Foreground",
9264 "Visible", "Perceptible", "Heavy Weight",
9265 "Backup", "Services", "Home", "Background"
9266 };
9267 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009268 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009269
9270 long totalPss = 0;
9271
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009272 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9273 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009274 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009275 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009276 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9277 pw.flush();
9278 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009279 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009280 if (dumpAll) {
9281 try {
9282 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9283 } catch (RemoteException e) {
9284 if (!isCheckinRequest) {
9285 pw.println("Got RemoteException!");
9286 pw.flush();
9287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009288 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009289 } else {
9290 mi = new Debug.MemoryInfo();
9291 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009292 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009293
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009294 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009295 long myTotalPss = mi.getTotalPss();
9296 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009297 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9298 myTotalPss);
9299 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009300
9301 nativePss += mi.nativePss;
9302 dalvikPss += mi.dalvikPss;
9303 otherPss += mi.otherPss;
9304 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9305 long mem = mi.getOtherPss(j);
9306 miscPss[j] += mem;
9307 otherPss -= mem;
9308 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009309
9310 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9311 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9312 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009313 if (oomProcs[oomIndex] == null) {
9314 oomProcs[oomIndex] = new ArrayList<MemItem>();
9315 }
9316 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009317 break;
9318 }
9319 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009321 }
9322 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009323
9324 if (!isCheckinRequest && procs.size() > 1) {
9325 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9326
9327 catMems.add(new MemItem("Native", nativePss));
9328 catMems.add(new MemItem("Dalvik", dalvikPss));
9329 catMems.add(new MemItem("Unknown", otherPss));
9330 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9331 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9332 }
9333
Dianne Hackbornb437e092011-08-05 17:50:29 -07009334 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9335 for (int j=0; j<oomPss.length; j++) {
9336 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009337 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9338 item.subitems = oomProcs[j];
9339 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009340 }
9341 }
9342
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009343 pw.println();
9344 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009345 dumpMemItems(pw, " ", procMems, true);
9346 pw.println();
9347 pw.println("Total PSS by OOM adjustment:");
9348 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009349 pw.println();
9350 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009351 dumpMemItems(pw, " ", catMems, true);
9352 pw.println();
9353 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 }
9356
9357 /**
9358 * Searches array of arguments for the specified string
9359 * @param args array of argument strings
9360 * @param value value to search for
9361 * @return true if the value is contained in the array
9362 */
9363 private static boolean scanArgs(String[] args, String value) {
9364 if (args != null) {
9365 for (String arg : args) {
9366 if (value.equals(arg)) {
9367 return true;
9368 }
9369 }
9370 }
9371 return false;
9372 }
9373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009374 private final void killServicesLocked(ProcessRecord app,
9375 boolean allowRestart) {
9376 // Report disconnected services.
9377 if (false) {
9378 // XXX we are letting the client link to the service for
9379 // death notifications.
9380 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009381 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009382 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009383 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009384 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009385 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009386 = r.connections.values().iterator();
9387 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009388 ArrayList<ConnectionRecord> cl = jt.next();
9389 for (int i=0; i<cl.size(); i++) {
9390 ConnectionRecord c = cl.get(i);
9391 if (c.binding.client != app) {
9392 try {
9393 //c.conn.connected(r.className, null);
9394 } catch (Exception e) {
9395 // todo: this should be asynchronous!
9396 Slog.w(TAG, "Exception thrown disconnected servce "
9397 + r.shortName
9398 + " from app " + app.processName, e);
9399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 }
9401 }
9402 }
9403 }
9404 }
9405 }
9406 }
9407
9408 // Clean up any connections this application has to other services.
9409 if (app.connections.size() > 0) {
9410 Iterator<ConnectionRecord> it = app.connections.iterator();
9411 while (it.hasNext()) {
9412 ConnectionRecord r = it.next();
9413 removeConnectionLocked(r, app, null);
9414 }
9415 }
9416 app.connections.clear();
9417
9418 if (app.services.size() != 0) {
9419 // Any services running in the application need to be placed
9420 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009421 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009422 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009423 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 synchronized (sr.stats.getBatteryStats()) {
9425 sr.stats.stopLaunchedLocked();
9426 }
9427 sr.app = null;
9428 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009429 if (mStoppingServices.remove(sr)) {
9430 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9431 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009432
9433 boolean hasClients = sr.bindings.size() > 0;
9434 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009435 Iterator<IntentBindRecord> bindings
9436 = sr.bindings.values().iterator();
9437 while (bindings.hasNext()) {
9438 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009439 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009440 + ": shouldUnbind=" + b.hasBound);
9441 b.binder = null;
9442 b.requested = b.received = b.hasBound = false;
9443 }
9444 }
9445
Dianne Hackborn070783f2010-12-29 16:46:28 -08009446 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9447 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009448 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009449 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009450 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009451 sr.crashCount, sr.shortName, app.pid);
9452 bringDownServiceLocked(sr, true);
9453 } else if (!allowRestart) {
9454 bringDownServiceLocked(sr, true);
9455 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009456 boolean canceled = scheduleServiceRestartLocked(sr, true);
9457
9458 // Should the service remain running? Note that in the
9459 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009460 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009461 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9462 if (sr.pendingStarts.size() == 0) {
9463 sr.startRequested = false;
9464 if (!hasClients) {
9465 // Whoops, no reason to restart!
9466 bringDownServiceLocked(sr, true);
9467 }
9468 }
9469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009470 }
9471 }
9472
9473 if (!allowRestart) {
9474 app.services.clear();
9475 }
9476 }
9477
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009478 // Make sure we have no more records on the stopping list.
9479 int i = mStoppingServices.size();
9480 while (i > 0) {
9481 i--;
9482 ServiceRecord sr = mStoppingServices.get(i);
9483 if (sr.app == app) {
9484 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009485 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009486 }
9487 }
9488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009489 app.executingServices.clear();
9490 }
9491
9492 private final void removeDyingProviderLocked(ProcessRecord proc,
9493 ContentProviderRecord cpr) {
9494 synchronized (cpr) {
9495 cpr.launchingApp = null;
9496 cpr.notifyAll();
9497 }
9498
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009499 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 String names[] = cpr.info.authority.split(";");
9501 for (int j = 0; j < names.length; j++) {
9502 mProvidersByName.remove(names[j]);
9503 }
9504
9505 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9506 while (cit.hasNext()) {
9507 ProcessRecord capp = cit.next();
9508 if (!capp.persistent && capp.thread != null
9509 && capp.pid != 0
9510 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009511 Slog.i(TAG, "Kill " + capp.processName
9512 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009513 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009514 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009515 capp.processName, capp.setAdj, "dying provider "
9516 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009517 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 }
9519 }
9520
9521 mLaunchingProviders.remove(cpr);
9522 }
9523
9524 /**
9525 * Main code for cleaning up a process when it has gone away. This is
9526 * called both as a result of the process dying, or directly when stopping
9527 * a process when running in single process mode.
9528 */
9529 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009530 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009532 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 }
9534
Dianne Hackborn36124872009-10-08 16:22:03 -07009535 mProcessesToGc.remove(app);
9536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009537 // Dismiss any open dialogs.
9538 if (app.crashDialog != null) {
9539 app.crashDialog.dismiss();
9540 app.crashDialog = null;
9541 }
9542 if (app.anrDialog != null) {
9543 app.anrDialog.dismiss();
9544 app.anrDialog = null;
9545 }
9546 if (app.waitDialog != null) {
9547 app.waitDialog.dismiss();
9548 app.waitDialog = null;
9549 }
9550
9551 app.crashing = false;
9552 app.notResponding = false;
9553
9554 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009555 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009556 app.thread = null;
9557 app.forcingToForeground = null;
9558 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009559 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009560 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009561 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009562
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009563 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564
9565 boolean restart = false;
9566
9567 int NL = mLaunchingProviders.size();
9568
9569 // Remove published content providers.
9570 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009571 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009572 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009573 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009574 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009575 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009576
9577 // See if someone is waiting for this provider... in which
9578 // case we don't remove it, but just let it restart.
9579 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009580 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009581 for (; i<NL; i++) {
9582 if (mLaunchingProviders.get(i) == cpr) {
9583 restart = true;
9584 break;
9585 }
9586 }
9587 } else {
9588 i = NL;
9589 }
9590
9591 if (i >= NL) {
9592 removeDyingProviderLocked(app, cpr);
9593 NL = mLaunchingProviders.size();
9594 }
9595 }
9596 app.pubProviders.clear();
9597 }
9598
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009599 // Take care of any launching providers waiting for this process.
9600 if (checkAppInLaunchingProvidersLocked(app, false)) {
9601 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009602 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 // Unregister from connected content providers.
9605 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009606 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009607 while (it.hasNext()) {
9608 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9609 cpr.clients.remove(app);
9610 }
9611 app.conProviders.clear();
9612 }
9613
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009614 // At this point there may be remaining entries in mLaunchingProviders
9615 // where we were the only one waiting, so they are no longer of use.
9616 // Look for these and clean up if found.
9617 // XXX Commented out for now. Trying to figure out a way to reproduce
9618 // the actual situation to identify what is actually going on.
9619 if (false) {
9620 for (int i=0; i<NL; i++) {
9621 ContentProviderRecord cpr = (ContentProviderRecord)
9622 mLaunchingProviders.get(i);
9623 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9624 synchronized (cpr) {
9625 cpr.launchingApp = null;
9626 cpr.notifyAll();
9627 }
9628 }
9629 }
9630 }
9631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 skipCurrentReceiverLocked(app);
9633
9634 // Unregister any receivers.
9635 if (app.receivers.size() > 0) {
9636 Iterator<ReceiverList> it = app.receivers.iterator();
9637 while (it.hasNext()) {
9638 removeReceiverLocked(it.next());
9639 }
9640 app.receivers.clear();
9641 }
9642
Christopher Tate181fafa2009-05-14 11:12:14 -07009643 // If the app is undergoing backup, tell the backup manager about it
9644 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009645 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009646 try {
9647 IBackupManager bm = IBackupManager.Stub.asInterface(
9648 ServiceManager.getService(Context.BACKUP_SERVICE));
9649 bm.agentDisconnected(app.info.packageName);
9650 } catch (RemoteException e) {
9651 // can't happen; backup manager is local
9652 }
9653 }
9654
Jeff Sharkey287bd832011-05-28 19:36:26 -07009655 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657 // If the caller is restarting this app, then leave it in its
9658 // current lists and let the caller take care of it.
9659 if (restarting) {
9660 return;
9661 }
9662
9663 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009664 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009665 "Removing non-persistent process during cleanup: " + app);
9666 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009667 if (mHeavyWeightProcess == app) {
9668 mHeavyWeightProcess = null;
9669 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009671 } else if (!app.removed) {
9672 // This app is persistent, so we need to keep its record around.
9673 // If it is not already on the pending app list, add it there
9674 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009675 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9676 mPersistentStartingProcesses.add(app);
9677 restart = true;
9678 }
9679 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009680 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9681 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009682 mProcessesOnHold.remove(app);
9683
The Android Open Source Project4df24232009-03-05 14:34:35 -08009684 if (app == mHomeProcess) {
9685 mHomeProcess = null;
9686 }
9687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009688 if (restart) {
9689 // We have components that still need to be running in the
9690 // process, so re-launch it.
9691 mProcessNames.put(app.processName, app.info.uid, app);
9692 startProcessLocked(app, "restart", app.processName);
9693 } else if (app.pid > 0 && app.pid != MY_PID) {
9694 // Goodbye!
9695 synchronized (mPidsSelfLocked) {
9696 mPidsSelfLocked.remove(app.pid);
9697 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9698 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009699 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 }
9701 }
9702
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009703 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9704 // Look through the content providers we are waiting to have launched,
9705 // and if any run in this process then either schedule a restart of
9706 // the process or kill the client waiting for it if this process has
9707 // gone bad.
9708 int NL = mLaunchingProviders.size();
9709 boolean restart = false;
9710 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009711 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009712 if (cpr.launchingApp == app) {
9713 if (!alwaysBad && !app.bad) {
9714 restart = true;
9715 } else {
9716 removeDyingProviderLocked(app, cpr);
9717 NL = mLaunchingProviders.size();
9718 }
9719 }
9720 }
9721 return restart;
9722 }
9723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009724 // =========================================================
9725 // SERVICES
9726 // =========================================================
9727
9728 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9729 ActivityManager.RunningServiceInfo info =
9730 new ActivityManager.RunningServiceInfo();
9731 info.service = r.name;
9732 if (r.app != null) {
9733 info.pid = r.app.pid;
9734 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009735 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009736 info.process = r.processName;
9737 info.foreground = r.isForeground;
9738 info.activeSince = r.createTime;
9739 info.started = r.startRequested;
9740 info.clientCount = r.connections.size();
9741 info.crashCount = r.crashCount;
9742 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009743 if (r.isForeground) {
9744 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9745 }
9746 if (r.startRequested) {
9747 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9748 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009749 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009750 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9751 }
9752 if (r.app != null && r.app.persistent) {
9753 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9754 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009755
9756 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9757 for (int i=0; i<connl.size(); i++) {
9758 ConnectionRecord conn = connl.get(i);
9759 if (conn.clientLabel != 0) {
9760 info.clientPackage = conn.binding.client.info.packageName;
9761 info.clientLabel = conn.clientLabel;
9762 return info;
9763 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009764 }
9765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 return info;
9767 }
9768
9769 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9770 int flags) {
9771 synchronized (this) {
9772 ArrayList<ActivityManager.RunningServiceInfo> res
9773 = new ArrayList<ActivityManager.RunningServiceInfo>();
9774
9775 if (mServices.size() > 0) {
9776 Iterator<ServiceRecord> it = mServices.values().iterator();
9777 while (it.hasNext() && res.size() < maxNum) {
9778 res.add(makeRunningServiceInfoLocked(it.next()));
9779 }
9780 }
9781
9782 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9783 ServiceRecord r = mRestartingServices.get(i);
9784 ActivityManager.RunningServiceInfo info =
9785 makeRunningServiceInfoLocked(r);
9786 info.restarting = r.nextRestartTime;
9787 res.add(info);
9788 }
9789
9790 return res;
9791 }
9792 }
9793
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009794 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9795 synchronized (this) {
9796 ServiceRecord r = mServices.get(name);
9797 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009798 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9799 for (int i=0; i<conn.size(); i++) {
9800 if (conn.get(i).clientIntent != null) {
9801 return conn.get(i).clientIntent;
9802 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009803 }
9804 }
9805 }
9806 }
9807 return null;
9808 }
9809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009810 private final ServiceRecord findServiceLocked(ComponentName name,
9811 IBinder token) {
9812 ServiceRecord r = mServices.get(name);
9813 return r == token ? r : null;
9814 }
9815
9816 private final class ServiceLookupResult {
9817 final ServiceRecord record;
9818 final String permission;
9819
9820 ServiceLookupResult(ServiceRecord _record, String _permission) {
9821 record = _record;
9822 permission = _permission;
9823 }
9824 };
9825
9826 private ServiceLookupResult findServiceLocked(Intent service,
9827 String resolvedType) {
9828 ServiceRecord r = null;
9829 if (service.getComponent() != null) {
9830 r = mServices.get(service.getComponent());
9831 }
9832 if (r == null) {
9833 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9834 r = mServicesByIntent.get(filter);
9835 }
9836
9837 if (r == null) {
9838 try {
9839 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009840 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009841 service, resolvedType, 0);
9842 ServiceInfo sInfo =
9843 rInfo != null ? rInfo.serviceInfo : null;
9844 if (sInfo == null) {
9845 return null;
9846 }
9847
9848 ComponentName name = new ComponentName(
9849 sInfo.applicationInfo.packageName, sInfo.name);
9850 r = mServices.get(name);
9851 } catch (RemoteException ex) {
9852 // pm is in same process, this will never happen.
9853 }
9854 }
9855 if (r != null) {
9856 int callingPid = Binder.getCallingPid();
9857 int callingUid = Binder.getCallingUid();
9858 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009859 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009861 if (!r.exported) {
9862 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9863 + " from pid=" + callingPid
9864 + ", uid=" + callingUid
9865 + " that is not exported from uid " + r.appInfo.uid);
9866 return new ServiceLookupResult(null, "not exported from uid "
9867 + r.appInfo.uid);
9868 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009869 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009870 + " from pid=" + callingPid
9871 + ", uid=" + callingUid
9872 + " requires " + r.permission);
9873 return new ServiceLookupResult(null, r.permission);
9874 }
9875 return new ServiceLookupResult(r, null);
9876 }
9877 return null;
9878 }
9879
9880 private class ServiceRestarter implements Runnable {
9881 private ServiceRecord mService;
9882
9883 void setService(ServiceRecord service) {
9884 mService = service;
9885 }
9886
9887 public void run() {
9888 synchronized(ActivityManagerService.this) {
9889 performServiceRestartLocked(mService);
9890 }
9891 }
9892 }
9893
9894 private ServiceLookupResult retrieveServiceLocked(Intent service,
9895 String resolvedType, int callingPid, int callingUid) {
9896 ServiceRecord r = null;
9897 if (service.getComponent() != null) {
9898 r = mServices.get(service.getComponent());
9899 }
9900 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9901 r = mServicesByIntent.get(filter);
9902 if (r == null) {
9903 try {
9904 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009905 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009906 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 ServiceInfo sInfo =
9908 rInfo != null ? rInfo.serviceInfo : null;
9909 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009910 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911 ": not found");
9912 return null;
9913 }
9914
9915 ComponentName name = new ComponentName(
9916 sInfo.applicationInfo.packageName, sInfo.name);
9917 r = mServices.get(name);
9918 if (r == null) {
9919 filter = new Intent.FilterComparison(service.cloneFilter());
9920 ServiceRestarter res = new ServiceRestarter();
9921 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9922 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9923 synchronized (stats) {
9924 ss = stats.getServiceStatsLocked(
9925 sInfo.applicationInfo.uid, sInfo.packageName,
9926 sInfo.name);
9927 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009928 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009929 res.setService(r);
9930 mServices.put(name, r);
9931 mServicesByIntent.put(filter, r);
9932
9933 // Make sure this component isn't in the pending list.
9934 int N = mPendingServices.size();
9935 for (int i=0; i<N; i++) {
9936 ServiceRecord pr = mPendingServices.get(i);
9937 if (pr.name.equals(name)) {
9938 mPendingServices.remove(i);
9939 i--;
9940 N--;
9941 }
9942 }
9943 }
9944 } catch (RemoteException ex) {
9945 // pm is in same process, this will never happen.
9946 }
9947 }
9948 if (r != null) {
9949 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009950 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009951 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009952 if (!r.exported) {
9953 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9954 + " from pid=" + callingPid
9955 + ", uid=" + callingUid
9956 + " that is not exported from uid " + r.appInfo.uid);
9957 return new ServiceLookupResult(null, "not exported from uid "
9958 + r.appInfo.uid);
9959 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009960 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009961 + " from pid=" + callingPid
9962 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009963 + " requires " + r.permission);
9964 return new ServiceLookupResult(null, r.permission);
9965 }
9966 return new ServiceLookupResult(r, null);
9967 }
9968 return null;
9969 }
9970
Dianne Hackborn287952c2010-09-22 22:34:31 -07009971 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9972 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9973 + why + " of " + r + " in app " + r.app);
9974 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9975 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976 long now = SystemClock.uptimeMillis();
9977 if (r.executeNesting == 0 && r.app != null) {
9978 if (r.app.executingServices.size() == 0) {
9979 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9980 msg.obj = r.app;
9981 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9982 }
9983 r.app.executingServices.add(r);
9984 }
9985 r.executeNesting++;
9986 r.executingStart = now;
9987 }
9988
9989 private final void sendServiceArgsLocked(ServiceRecord r,
9990 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009991 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 if (N == 0) {
9993 return;
9994 }
9995
Dianne Hackborn39792d22010-08-19 18:01:52 -07009996 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009997 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009998 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009999 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10000 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010001 if (si.intent == null && N > 1) {
10002 // If somehow we got a dummy null intent in the middle,
10003 // then skip it. DO NOT skip a null intent when it is
10004 // the only one in the list -- this is to support the
10005 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010006 continue;
10007 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010008 si.deliveredTime = SystemClock.uptimeMillis();
10009 r.deliveredStarts.add(si);
10010 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010011 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010012 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010013 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010014 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010015 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016 if (!oomAdjusted) {
10017 oomAdjusted = true;
10018 updateOomAdjLocked(r.app);
10019 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010020 int flags = 0;
10021 if (si.deliveryCount > 0) {
10022 flags |= Service.START_FLAG_RETRY;
10023 }
10024 if (si.doneExecutingCount > 0) {
10025 flags |= Service.START_FLAG_REDELIVERY;
10026 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010027 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010028 } catch (RemoteException e) {
10029 // Remote process gone... we'll let the normal cleanup take
10030 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010031 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010032 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010033 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010034 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010035 break;
10036 }
10037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010038 }
10039
10040 private final boolean requestServiceBindingLocked(ServiceRecord r,
10041 IntentBindRecord i, boolean rebind) {
10042 if (r.app == null || r.app.thread == null) {
10043 // If service is not currently running, can't yet bind.
10044 return false;
10045 }
10046 if ((!i.requested || rebind) && i.apps.size() > 0) {
10047 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010048 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10050 if (!rebind) {
10051 i.requested = true;
10052 }
10053 i.hasBound = true;
10054 i.doRebind = false;
10055 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010056 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010057 return false;
10058 }
10059 }
10060 return true;
10061 }
10062
10063 private final void requestServiceBindingsLocked(ServiceRecord r) {
10064 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10065 while (bindings.hasNext()) {
10066 IntentBindRecord i = bindings.next();
10067 if (!requestServiceBindingLocked(r, i, false)) {
10068 break;
10069 }
10070 }
10071 }
10072
10073 private final void realStartServiceLocked(ServiceRecord r,
10074 ProcessRecord app) throws RemoteException {
10075 if (app.thread == null) {
10076 throw new RemoteException();
10077 }
10078
10079 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010080 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081
10082 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010083 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010084 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010085
10086 boolean created = false;
10087 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010088 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010089 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010090 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010092 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010093 synchronized (r.stats.getBatteryStats()) {
10094 r.stats.startLaunchedLocked();
10095 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010096 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010097 app.thread.scheduleCreateService(r, r.serviceInfo,
10098 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010099 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010100 created = true;
10101 } finally {
10102 if (!created) {
10103 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010104 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 }
10106 }
10107
10108 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010109
10110 // If the service is in the started state, and there are no
10111 // pending arguments, then fake up one so its onStartCommand() will
10112 // be called.
10113 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010114 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10115 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010116 }
10117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010118 sendServiceArgsLocked(r, true);
10119 }
10120
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010121 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10122 boolean allowCancel) {
10123 boolean canceled = false;
10124
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010125 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010126 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010127 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010128
Dianne Hackborn070783f2010-12-29 16:46:28 -080010129 if ((r.serviceInfo.applicationInfo.flags
10130 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10131 minDuration /= 4;
10132 }
10133
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010134 // Any delivered but not yet finished starts should be put back
10135 // on the pending list.
10136 final int N = r.deliveredStarts.size();
10137 if (N > 0) {
10138 for (int i=N-1; i>=0; i--) {
10139 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010140 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010141 if (si.intent == null) {
10142 // We'll generate this again if needed.
10143 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10144 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10145 r.pendingStarts.add(0, si);
10146 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10147 dur *= 2;
10148 if (minDuration < dur) minDuration = dur;
10149 if (resetTime < dur) resetTime = dur;
10150 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010151 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010152 + r.name);
10153 canceled = true;
10154 }
10155 }
10156 r.deliveredStarts.clear();
10157 }
10158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010159 r.totalRestartCount++;
10160 if (r.restartDelay == 0) {
10161 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010162 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010163 } else {
10164 // If it has been a "reasonably long time" since the service
10165 // was started, then reset our restart duration back to
10166 // the beginning, so we don't infinitely increase the duration
10167 // on a service that just occasionally gets killed (which is
10168 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010169 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010171 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010172 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010173 if ((r.serviceInfo.applicationInfo.flags
10174 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10175 // Services in peristent processes will restart much more
10176 // quickly, since they are pretty important. (Think SystemUI).
10177 r.restartDelay += minDuration/2;
10178 } else {
10179 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10180 if (r.restartDelay < minDuration) {
10181 r.restartDelay = minDuration;
10182 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 }
10185 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010186
10187 r.nextRestartTime = now + r.restartDelay;
10188
10189 // Make sure that we don't end up restarting a bunch of services
10190 // all at the same time.
10191 boolean repeat;
10192 do {
10193 repeat = false;
10194 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10195 ServiceRecord r2 = mRestartingServices.get(i);
10196 if (r2 != r && r.nextRestartTime
10197 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10198 && r.nextRestartTime
10199 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10200 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10201 r.restartDelay = r.nextRestartTime - now;
10202 repeat = true;
10203 break;
10204 }
10205 }
10206 } while (repeat);
10207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 if (!mRestartingServices.contains(r)) {
10209 mRestartingServices.add(r);
10210 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010211
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010212 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010214 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010215 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010216 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010217 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010218 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010219 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010220 r.shortName, r.restartDelay);
10221
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010222 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 }
10224
10225 final void performServiceRestartLocked(ServiceRecord r) {
10226 if (!mRestartingServices.contains(r)) {
10227 return;
10228 }
10229 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10230 }
10231
10232 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10233 if (r.restartDelay == 0) {
10234 return false;
10235 }
10236 r.resetRestartCounter();
10237 mRestartingServices.remove(r);
10238 mHandler.removeCallbacks(r.restarter);
10239 return true;
10240 }
10241
10242 private final boolean bringUpServiceLocked(ServiceRecord r,
10243 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010244 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010245 //r.dump(" ");
10246
Dianne Hackborn36124872009-10-08 16:22:03 -070010247 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010248 sendServiceArgsLocked(r, false);
10249 return true;
10250 }
10251
10252 if (!whileRestarting && r.restartDelay > 0) {
10253 // If waiting for a restart, then do nothing.
10254 return true;
10255 }
10256
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010257 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010258
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010259 // We are now bringing the service up, so no longer in the
10260 // restarting state.
10261 mRestartingServices.remove(r);
10262
Dianne Hackborne7f97212011-02-24 14:40:20 -080010263 // Service is now being launched, its package can't be stopped.
10264 try {
10265 AppGlobals.getPackageManager().setPackageStoppedState(
10266 r.packageName, false);
10267 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010268 } catch (IllegalArgumentException e) {
10269 Slog.w(TAG, "Failed trying to unstop package "
10270 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010271 }
10272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010273 final String appName = r.processName;
10274 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10275 if (app != null && app.thread != null) {
10276 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010277 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010278 realStartServiceLocked(r, app);
10279 return true;
10280 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010281 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010282 }
10283
10284 // If a dead object exception was thrown -- fall through to
10285 // restart the application.
10286 }
10287
Dianne Hackborn36124872009-10-08 16:22:03 -070010288 // Not running -- get it started, and enqueue this service record
10289 // to be executed when the app comes up.
10290 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10291 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010292 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010293 + r.appInfo.packageName + "/"
10294 + r.appInfo.uid + " for service "
10295 + r.intent.getIntent() + ": process is bad");
10296 bringDownServiceLocked(r, true);
10297 return false;
10298 }
10299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301 mPendingServices.add(r);
10302 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 return true;
10305 }
10306
10307 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010308 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010309 //r.dump(" ");
10310
10311 // Does it still need to run?
10312 if (!force && r.startRequested) {
10313 return;
10314 }
10315 if (r.connections.size() > 0) {
10316 if (!force) {
10317 // XXX should probably keep a count of the number of auto-create
10318 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010319 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010320 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010321 ArrayList<ConnectionRecord> cr = it.next();
10322 for (int i=0; i<cr.size(); i++) {
10323 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10324 return;
10325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010326 }
10327 }
10328 }
10329
10330 // Report to all of the connections that the service is no longer
10331 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010332 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010333 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010334 ArrayList<ConnectionRecord> c = it.next();
10335 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010336 ConnectionRecord cr = c.get(i);
10337 // There is still a connection to the service that is
10338 // being brought down. Mark it as dead.
10339 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010340 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010341 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010342 } catch (Exception e) {
10343 Slog.w(TAG, "Failure disconnecting service " + r.name +
10344 " to connection " + c.get(i).conn.asBinder() +
10345 " (in " + c.get(i).binding.client.processName + ")", e);
10346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010347 }
10348 }
10349 }
10350
10351 // Tell the service that it has been unbound.
10352 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10353 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10354 while (it.hasNext()) {
10355 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010356 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010357 + ": hasBound=" + ibr.hasBound);
10358 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10359 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010360 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010361 updateOomAdjLocked(r.app);
10362 ibr.hasBound = false;
10363 r.app.thread.scheduleUnbindService(r,
10364 ibr.intent.getIntent());
10365 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010366 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010367 + r.shortName, e);
10368 serviceDoneExecutingLocked(r, true);
10369 }
10370 }
10371 }
10372 }
10373
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010374 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010375 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010376 System.identityHashCode(r), r.shortName,
10377 (r.app != null) ? r.app.pid : -1);
10378
10379 mServices.remove(r.name);
10380 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010381 r.totalRestartCount = 0;
10382 unscheduleServiceRestartLocked(r);
10383
10384 // Also make sure it is not on the pending list.
10385 int N = mPendingServices.size();
10386 for (int i=0; i<N; i++) {
10387 if (mPendingServices.get(i) == r) {
10388 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010389 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010390 i--;
10391 N--;
10392 }
10393 }
10394
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010395 r.cancelNotification();
10396 r.isForeground = false;
10397 r.foregroundId = 0;
10398 r.foregroundNoti = null;
10399
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010400 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010401 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010402 r.pendingStarts.clear();
10403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 if (r.app != null) {
10405 synchronized (r.stats.getBatteryStats()) {
10406 r.stats.stopLaunchedLocked();
10407 }
10408 r.app.services.remove(r);
10409 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010410 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010411 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010412 mStoppingServices.add(r);
10413 updateOomAdjLocked(r.app);
10414 r.app.thread.scheduleStopService(r);
10415 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010416 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010417 + r.shortName, e);
10418 serviceDoneExecutingLocked(r, true);
10419 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010420 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010422 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010423 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010424 }
10425 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010426 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010427 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010428 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010429
10430 if (r.bindings.size() > 0) {
10431 r.bindings.clear();
10432 }
10433
10434 if (r.restarter instanceof ServiceRestarter) {
10435 ((ServiceRestarter)r.restarter).setService(null);
10436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010437 }
10438
10439 ComponentName startServiceLocked(IApplicationThread caller,
10440 Intent service, String resolvedType,
10441 int callingPid, int callingUid) {
10442 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010443 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010444 + " type=" + resolvedType + " args=" + service.getExtras());
10445
10446 if (caller != null) {
10447 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10448 if (callerApp == null) {
10449 throw new SecurityException(
10450 "Unable to find app for caller " + caller
10451 + " (pid=" + Binder.getCallingPid()
10452 + ") when starting service " + service);
10453 }
10454 }
10455
10456 ServiceLookupResult res =
10457 retrieveServiceLocked(service, resolvedType,
10458 callingPid, callingUid);
10459 if (res == null) {
10460 return null;
10461 }
10462 if (res.record == null) {
10463 return new ComponentName("!", res.permission != null
10464 ? res.permission : "private to package");
10465 }
10466 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010467 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10468 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010470 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 }
10472 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010473 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010474 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010475 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010476 r.lastActivity = SystemClock.uptimeMillis();
10477 synchronized (r.stats.getBatteryStats()) {
10478 r.stats.startRunningLocked();
10479 }
10480 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10481 return new ComponentName("!", "Service process is bad");
10482 }
10483 return r.name;
10484 }
10485 }
10486
10487 public ComponentName startService(IApplicationThread caller, Intent service,
10488 String resolvedType) {
10489 // Refuse possible leaked file descriptors
10490 if (service != null && service.hasFileDescriptors() == true) {
10491 throw new IllegalArgumentException("File descriptors passed in Intent");
10492 }
10493
10494 synchronized(this) {
10495 final int callingPid = Binder.getCallingPid();
10496 final int callingUid = Binder.getCallingUid();
10497 final long origId = Binder.clearCallingIdentity();
10498 ComponentName res = startServiceLocked(caller, service,
10499 resolvedType, callingPid, callingUid);
10500 Binder.restoreCallingIdentity(origId);
10501 return res;
10502 }
10503 }
10504
10505 ComponentName startServiceInPackage(int uid,
10506 Intent service, String resolvedType) {
10507 synchronized(this) {
10508 final long origId = Binder.clearCallingIdentity();
10509 ComponentName res = startServiceLocked(null, service,
10510 resolvedType, -1, uid);
10511 Binder.restoreCallingIdentity(origId);
10512 return res;
10513 }
10514 }
10515
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010516 private void stopServiceLocked(ServiceRecord service) {
10517 synchronized (service.stats.getBatteryStats()) {
10518 service.stats.stopRunningLocked();
10519 }
10520 service.startRequested = false;
10521 service.callStart = false;
10522 bringDownServiceLocked(service, false);
10523 }
10524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010525 public int stopService(IApplicationThread caller, Intent service,
10526 String resolvedType) {
10527 // Refuse possible leaked file descriptors
10528 if (service != null && service.hasFileDescriptors() == true) {
10529 throw new IllegalArgumentException("File descriptors passed in Intent");
10530 }
10531
10532 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010533 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010534 + " type=" + resolvedType);
10535
10536 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10537 if (caller != null && callerApp == null) {
10538 throw new SecurityException(
10539 "Unable to find app for caller " + caller
10540 + " (pid=" + Binder.getCallingPid()
10541 + ") when stopping service " + service);
10542 }
10543
10544 // If this service is active, make sure it is stopped.
10545 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10546 if (r != null) {
10547 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010549 try {
10550 stopServiceLocked(r.record);
10551 } finally {
10552 Binder.restoreCallingIdentity(origId);
10553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010554 return 1;
10555 }
10556 return -1;
10557 }
10558 }
10559
10560 return 0;
10561 }
10562
10563 public IBinder peekService(Intent service, String resolvedType) {
10564 // Refuse possible leaked file descriptors
10565 if (service != null && service.hasFileDescriptors() == true) {
10566 throw new IllegalArgumentException("File descriptors passed in Intent");
10567 }
10568
10569 IBinder ret = null;
10570
10571 synchronized(this) {
10572 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10573
10574 if (r != null) {
10575 // r.record is null if findServiceLocked() failed the caller permission check
10576 if (r.record == null) {
10577 throw new SecurityException(
10578 "Permission Denial: Accessing service " + r.record.name
10579 + " from pid=" + Binder.getCallingPid()
10580 + ", uid=" + Binder.getCallingUid()
10581 + " requires " + r.permission);
10582 }
10583 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10584 if (ib != null) {
10585 ret = ib.binder;
10586 }
10587 }
10588 }
10589
10590 return ret;
10591 }
10592
10593 public boolean stopServiceToken(ComponentName className, IBinder token,
10594 int startId) {
10595 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010596 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010597 + " " + token + " startId=" + startId);
10598 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010599 if (r != null) {
10600 if (startId >= 0) {
10601 // Asked to only stop if done with all work. Note that
10602 // to avoid leaks, we will take this as dropping all
10603 // start items up to and including this one.
10604 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10605 if (si != null) {
10606 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010607 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10608 cur.removeUriPermissionsLocked();
10609 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010610 break;
10611 }
10612 }
10613 }
10614
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010615 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010616 return false;
10617 }
10618
10619 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010620 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010621 + " is last, but have " + r.deliveredStarts.size()
10622 + " remaining args");
10623 }
10624 }
10625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010626 synchronized (r.stats.getBatteryStats()) {
10627 r.stats.stopRunningLocked();
10628 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010629 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010630 }
10631 final long origId = Binder.clearCallingIdentity();
10632 bringDownServiceLocked(r, false);
10633 Binder.restoreCallingIdentity(origId);
10634 return true;
10635 }
10636 }
10637 return false;
10638 }
10639
10640 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010641 int id, Notification notification, boolean removeNotification) {
10642 final long origId = Binder.clearCallingIdentity();
10643 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 synchronized(this) {
10645 ServiceRecord r = findServiceLocked(className, token);
10646 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010647 if (id != 0) {
10648 if (notification == null) {
10649 throw new IllegalArgumentException("null notification");
10650 }
10651 if (r.foregroundId != id) {
10652 r.cancelNotification();
10653 r.foregroundId = id;
10654 }
10655 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10656 r.foregroundNoti = notification;
10657 r.isForeground = true;
10658 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 if (r.app != null) {
10660 updateServiceForegroundLocked(r.app, true);
10661 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010662 } else {
10663 if (r.isForeground) {
10664 r.isForeground = false;
10665 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010666 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010667 updateServiceForegroundLocked(r.app, true);
10668 }
10669 }
10670 if (removeNotification) {
10671 r.cancelNotification();
10672 r.foregroundId = 0;
10673 r.foregroundNoti = null;
10674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 }
10676 }
10677 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010678 } finally {
10679 Binder.restoreCallingIdentity(origId);
10680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 }
10682
10683 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10684 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010685 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010686 if (sr.isForeground) {
10687 anyForeground = true;
10688 break;
10689 }
10690 }
10691 if (anyForeground != proc.foregroundServices) {
10692 proc.foregroundServices = anyForeground;
10693 if (oomAdj) {
10694 updateOomAdjLocked();
10695 }
10696 }
10697 }
10698
10699 public int bindService(IApplicationThread caller, IBinder token,
10700 Intent service, String resolvedType,
10701 IServiceConnection connection, int flags) {
10702 // Refuse possible leaked file descriptors
10703 if (service != null && service.hasFileDescriptors() == true) {
10704 throw new IllegalArgumentException("File descriptors passed in Intent");
10705 }
10706
10707 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010708 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010709 + " type=" + resolvedType + " conn=" + connection.asBinder()
10710 + " flags=0x" + Integer.toHexString(flags));
10711 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10712 if (callerApp == null) {
10713 throw new SecurityException(
10714 "Unable to find app for caller " + caller
10715 + " (pid=" + Binder.getCallingPid()
10716 + ") when binding service " + service);
10717 }
10718
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010719 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010720 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010721 activity = mMainStack.isInStackLocked(token);
10722 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010723 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 return 0;
10725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 }
10727
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010728 int clientLabel = 0;
10729 PendingIntent clientIntent = null;
10730
10731 if (callerApp.info.uid == Process.SYSTEM_UID) {
10732 // Hacky kind of thing -- allow system stuff to tell us
10733 // what they are, so we can report this elsewhere for
10734 // others to know why certain services are running.
10735 try {
10736 clientIntent = (PendingIntent)service.getParcelableExtra(
10737 Intent.EXTRA_CLIENT_INTENT);
10738 } catch (RuntimeException e) {
10739 }
10740 if (clientIntent != null) {
10741 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10742 if (clientLabel != 0) {
10743 // There are no useful extras in the intent, trash them.
10744 // System code calling with this stuff just needs to know
10745 // this will happen.
10746 service = service.cloneFilter();
10747 }
10748 }
10749 }
10750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010751 ServiceLookupResult res =
10752 retrieveServiceLocked(service, resolvedType,
10753 Binder.getCallingPid(), Binder.getCallingUid());
10754 if (res == null) {
10755 return 0;
10756 }
10757 if (res.record == null) {
10758 return -1;
10759 }
10760 ServiceRecord s = res.record;
10761
10762 final long origId = Binder.clearCallingIdentity();
10763
10764 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010765 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010766 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 }
10768
10769 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10770 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010771 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772
10773 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010774 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10775 if (clist == null) {
10776 clist = new ArrayList<ConnectionRecord>();
10777 s.connections.put(binder, clist);
10778 }
10779 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010780 b.connections.add(c);
10781 if (activity != null) {
10782 if (activity.connections == null) {
10783 activity.connections = new HashSet<ConnectionRecord>();
10784 }
10785 activity.connections.add(c);
10786 }
10787 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010788 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10789 b.client.hasAboveClient = true;
10790 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010791 clist = mServiceConnections.get(binder);
10792 if (clist == null) {
10793 clist = new ArrayList<ConnectionRecord>();
10794 mServiceConnections.put(binder, clist);
10795 }
10796 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010797
10798 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10799 s.lastActivity = SystemClock.uptimeMillis();
10800 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10801 return 0;
10802 }
10803 }
10804
10805 if (s.app != null) {
10806 // This could have made the service more important.
10807 updateOomAdjLocked(s.app);
10808 }
10809
Joe Onorato8a9b2202010-02-26 18:56:32 -080010810 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010811 + ": received=" + b.intent.received
10812 + " apps=" + b.intent.apps.size()
10813 + " doRebind=" + b.intent.doRebind);
10814
10815 if (s.app != null && b.intent.received) {
10816 // Service is already running, so we can immediately
10817 // publish the connection.
10818 try {
10819 c.conn.connected(s.name, b.intent.binder);
10820 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010821 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010822 + " to connection " + c.conn.asBinder()
10823 + " (in " + c.binding.client.processName + ")", e);
10824 }
10825
10826 // If this is the first app connected back to this binding,
10827 // and the service had previously asked to be told when
10828 // rebound, then do so.
10829 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10830 requestServiceBindingLocked(s, b.intent, true);
10831 }
10832 } else if (!b.intent.requested) {
10833 requestServiceBindingLocked(s, b.intent, false);
10834 }
10835
10836 Binder.restoreCallingIdentity(origId);
10837 }
10838
10839 return 1;
10840 }
10841
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010842 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010843 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010844 IBinder binder = c.conn.asBinder();
10845 AppBindRecord b = c.binding;
10846 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010847 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10848 if (clist != null) {
10849 clist.remove(c);
10850 if (clist.size() == 0) {
10851 s.connections.remove(binder);
10852 }
10853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010854 b.connections.remove(c);
10855 if (c.activity != null && c.activity != skipAct) {
10856 if (c.activity.connections != null) {
10857 c.activity.connections.remove(c);
10858 }
10859 }
10860 if (b.client != skipApp) {
10861 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010862 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10863 b.client.updateHasAboveClientLocked();
10864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010865 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010866 clist = mServiceConnections.get(binder);
10867 if (clist != null) {
10868 clist.remove(c);
10869 if (clist.size() == 0) {
10870 mServiceConnections.remove(binder);
10871 }
10872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010873
10874 if (b.connections.size() == 0) {
10875 b.intent.apps.remove(b.client);
10876 }
10877
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010878 if (!c.serviceDead) {
10879 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10880 + ": shouldUnbind=" + b.intent.hasBound);
10881 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10882 && b.intent.hasBound) {
10883 try {
10884 bumpServiceExecutingLocked(s, "unbind");
10885 updateOomAdjLocked(s.app);
10886 b.intent.hasBound = false;
10887 // Assume the client doesn't want to know about a rebind;
10888 // we will deal with that later if it asks for one.
10889 b.intent.doRebind = false;
10890 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10891 } catch (Exception e) {
10892 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10893 serviceDoneExecutingLocked(s, true);
10894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010895 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010896
10897 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10898 bringDownServiceLocked(s, false);
10899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 }
10901 }
10902
10903 public boolean unbindService(IServiceConnection connection) {
10904 synchronized (this) {
10905 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010906 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010907 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10908 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010909 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 + connection.asBinder());
10911 return false;
10912 }
10913
10914 final long origId = Binder.clearCallingIdentity();
10915
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010916 while (clist.size() > 0) {
10917 ConnectionRecord r = clist.get(0);
10918 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010919
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010920 if (r.binding.service.app != null) {
10921 // This could have made the service less important.
10922 updateOomAdjLocked(r.binding.service.app);
10923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010924 }
10925
10926 Binder.restoreCallingIdentity(origId);
10927 }
10928
10929 return true;
10930 }
10931
10932 public void publishService(IBinder token, Intent intent, IBinder service) {
10933 // Refuse possible leaked file descriptors
10934 if (intent != null && intent.hasFileDescriptors() == true) {
10935 throw new IllegalArgumentException("File descriptors passed in Intent");
10936 }
10937
10938 synchronized(this) {
10939 if (!(token instanceof ServiceRecord)) {
10940 throw new IllegalArgumentException("Invalid service token");
10941 }
10942 ServiceRecord r = (ServiceRecord)token;
10943
10944 final long origId = Binder.clearCallingIdentity();
10945
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010946 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010947 + " " + intent + ": " + service);
10948 if (r != null) {
10949 Intent.FilterComparison filter
10950 = new Intent.FilterComparison(intent);
10951 IntentBindRecord b = r.bindings.get(filter);
10952 if (b != null && !b.received) {
10953 b.binder = service;
10954 b.requested = true;
10955 b.received = true;
10956 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010957 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010958 = r.connections.values().iterator();
10959 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010960 ArrayList<ConnectionRecord> clist = it.next();
10961 for (int i=0; i<clist.size(); i++) {
10962 ConnectionRecord c = clist.get(i);
10963 if (!filter.equals(c.binding.intent.intent)) {
10964 if (DEBUG_SERVICE) Slog.v(
10965 TAG, "Not publishing to: " + c);
10966 if (DEBUG_SERVICE) Slog.v(
10967 TAG, "Bound intent: " + c.binding.intent.intent);
10968 if (DEBUG_SERVICE) Slog.v(
10969 TAG, "Published intent: " + intent);
10970 continue;
10971 }
10972 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10973 try {
10974 c.conn.connected(r.name, service);
10975 } catch (Exception e) {
10976 Slog.w(TAG, "Failure sending service " + r.name +
10977 " to connection " + c.conn.asBinder() +
10978 " (in " + c.binding.client.processName + ")", e);
10979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010980 }
10981 }
10982 }
10983 }
10984
10985 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10986
10987 Binder.restoreCallingIdentity(origId);
10988 }
10989 }
10990 }
10991
10992 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10993 // Refuse possible leaked file descriptors
10994 if (intent != null && intent.hasFileDescriptors() == true) {
10995 throw new IllegalArgumentException("File descriptors passed in Intent");
10996 }
10997
10998 synchronized(this) {
10999 if (!(token instanceof ServiceRecord)) {
11000 throw new IllegalArgumentException("Invalid service token");
11001 }
11002 ServiceRecord r = (ServiceRecord)token;
11003
11004 final long origId = Binder.clearCallingIdentity();
11005
11006 if (r != null) {
11007 Intent.FilterComparison filter
11008 = new Intent.FilterComparison(intent);
11009 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011010 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011011 + " at " + b + ": apps="
11012 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011013
11014 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011015 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011016 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 // Applications have already bound since the last
11018 // unbind, so just rebind right here.
11019 requestServiceBindingLocked(r, b, true);
11020 } else {
11021 // Note to tell the service the next time there is
11022 // a new client.
11023 b.doRebind = true;
11024 }
11025 }
11026
Per Edelberg78f9fff2010-08-30 20:01:35 +020011027 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011028
11029 Binder.restoreCallingIdentity(origId);
11030 }
11031 }
11032 }
11033
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011034 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011035 synchronized(this) {
11036 if (!(token instanceof ServiceRecord)) {
11037 throw new IllegalArgumentException("Invalid service token");
11038 }
11039 ServiceRecord r = (ServiceRecord)token;
11040 boolean inStopping = mStoppingServices.contains(token);
11041 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011042 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011043 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 + " with incorrect token: given " + token
11045 + ", expected " + r);
11046 return;
11047 }
11048
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011049 if (type == 1) {
11050 // This is a call from a service start... take care of
11051 // book-keeping.
11052 r.callStart = true;
11053 switch (res) {
11054 case Service.START_STICKY_COMPATIBILITY:
11055 case Service.START_STICKY: {
11056 // We are done with the associated start arguments.
11057 r.findDeliveredStart(startId, true);
11058 // Don't stop if killed.
11059 r.stopIfKilled = false;
11060 break;
11061 }
11062 case Service.START_NOT_STICKY: {
11063 // We are done with the associated start arguments.
11064 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011065 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011066 // There is no more work, and this service
11067 // doesn't want to hang around if killed.
11068 r.stopIfKilled = true;
11069 }
11070 break;
11071 }
11072 case Service.START_REDELIVER_INTENT: {
11073 // We'll keep this item until they explicitly
11074 // call stop for it, but keep track of the fact
11075 // that it was delivered.
11076 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11077 if (si != null) {
11078 si.deliveryCount = 0;
11079 si.doneExecutingCount++;
11080 // Don't stop if killed.
11081 r.stopIfKilled = true;
11082 }
11083 break;
11084 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011085 case Service.START_TASK_REMOVED_COMPLETE: {
11086 // Special processing for onTaskRemoved(). Don't
11087 // impact normal onStartCommand() processing.
11088 r.findDeliveredStart(startId, true);
11089 break;
11090 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011091 default:
11092 throw new IllegalArgumentException(
11093 "Unknown service start result: " + res);
11094 }
11095 if (res == Service.START_STICKY_COMPATIBILITY) {
11096 r.callStart = false;
11097 }
11098 }
11099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011100 final long origId = Binder.clearCallingIdentity();
11101 serviceDoneExecutingLocked(r, inStopping);
11102 Binder.restoreCallingIdentity(origId);
11103 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011104 Slog.w(TAG, "Done executing unknown service from pid "
11105 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011106 }
11107 }
11108 }
11109
11110 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011111 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11112 + ": nesting=" + r.executeNesting
11113 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011114 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 r.executeNesting--;
11116 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011117 if (DEBUG_SERVICE) Slog.v(TAG,
11118 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 r.app.executingServices.remove(r);
11120 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011121 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11122 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011123 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11124 }
11125 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011126 if (DEBUG_SERVICE) Slog.v(TAG,
11127 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011129 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011130 }
11131 updateOomAdjLocked(r.app);
11132 }
11133 }
11134
11135 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011136 String anrMessage = null;
11137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011138 synchronized(this) {
11139 if (proc.executingServices.size() == 0 || proc.thread == null) {
11140 return;
11141 }
11142 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11143 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11144 ServiceRecord timeout = null;
11145 long nextTime = 0;
11146 while (it.hasNext()) {
11147 ServiceRecord sr = it.next();
11148 if (sr.executingStart < maxTime) {
11149 timeout = sr;
11150 break;
11151 }
11152 if (sr.executingStart > nextTime) {
11153 nextTime = sr.executingStart;
11154 }
11155 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011156 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011157 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011158 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011159 } else {
11160 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11161 msg.obj = proc;
11162 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11163 }
11164 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011165
11166 if (anrMessage != null) {
11167 appNotResponding(proc, null, null, anrMessage);
11168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 }
11170
11171 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011172 // BACKUP AND RESTORE
11173 // =========================================================
11174
11175 // Cause the target app to be launched if necessary and its backup agent
11176 // instantiated. The backup agent will invoke backupAgentCreated() on the
11177 // activity manager to announce its creation.
11178 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011179 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011180 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11181
11182 synchronized(this) {
11183 // !!! TODO: currently no check here that we're already bound
11184 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11185 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11186 synchronized (stats) {
11187 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11188 }
11189
Dianne Hackborne7f97212011-02-24 14:40:20 -080011190 // Backup agent is now in use, its package can't be stopped.
11191 try {
11192 AppGlobals.getPackageManager().setPackageStoppedState(
11193 app.packageName, false);
11194 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011195 } catch (IllegalArgumentException e) {
11196 Slog.w(TAG, "Failed trying to unstop package "
11197 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011198 }
11199
Christopher Tate181fafa2009-05-14 11:12:14 -070011200 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011201 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11202 ? new ComponentName(app.packageName, app.backupAgentName)
11203 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011204 // startProcessLocked() returns existing proc's record if it's already running
11205 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011206 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011207 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011208 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011209 return false;
11210 }
11211
11212 r.app = proc;
11213 mBackupTarget = r;
11214 mBackupAppName = app.packageName;
11215
Christopher Tate6fa95972009-06-05 18:43:55 -070011216 // Try not to kill the process during backup
11217 updateOomAdjLocked(proc);
11218
Christopher Tate181fafa2009-05-14 11:12:14 -070011219 // If the process is already attached, schedule the creation of the backup agent now.
11220 // If it is not yet live, this will be done when it attaches to the framework.
11221 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011222 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011223 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011224 proc.thread.scheduleCreateBackupAgent(app,
11225 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011226 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011227 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011228 }
11229 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011230 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011231 }
11232 // Invariants: at this point, the target app process exists and the application
11233 // is either already running or in the process of coming up. mBackupTarget and
11234 // mBackupAppName describe the app, so that when it binds back to the AM we
11235 // know that it's scheduled for a backup-agent operation.
11236 }
11237
11238 return true;
11239 }
11240
11241 // A backup agent has just come up
11242 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011243 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011244 + " = " + agent);
11245
11246 synchronized(this) {
11247 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011248 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011249 return;
11250 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011251 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011252
Dianne Hackborn06740692010-09-22 22:46:21 -070011253 long oldIdent = Binder.clearCallingIdentity();
11254 try {
11255 IBackupManager bm = IBackupManager.Stub.asInterface(
11256 ServiceManager.getService(Context.BACKUP_SERVICE));
11257 bm.agentConnected(agentPackageName, agent);
11258 } catch (RemoteException e) {
11259 // can't happen; the backup manager service is local
11260 } catch (Exception e) {
11261 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11262 e.printStackTrace();
11263 } finally {
11264 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011265 }
11266 }
11267
11268 // done with this agent
11269 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011270 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011271 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011272 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011273 return;
11274 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011275
11276 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011277 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011278 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011279 return;
11280 }
11281
Christopher Tate181fafa2009-05-14 11:12:14 -070011282 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011283 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011284 return;
11285 }
11286
Christopher Tate6fa95972009-06-05 18:43:55 -070011287 ProcessRecord proc = mBackupTarget.app;
11288 mBackupTarget = null;
11289 mBackupAppName = null;
11290
11291 // Not backing this app up any more; reset its OOM adjustment
11292 updateOomAdjLocked(proc);
11293
Christopher Tatec7b31e32009-06-10 15:49:30 -070011294 // If the app crashed during backup, 'thread' will be null here
11295 if (proc.thread != null) {
11296 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011297 proc.thread.scheduleDestroyBackupAgent(appInfo,
11298 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011299 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011300 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011301 e.printStackTrace();
11302 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011303 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011304 }
11305 }
11306 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011307 // BROADCASTS
11308 // =========================================================
11309
Josh Bartel7f208742010-02-25 11:01:44 -060011310 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011311 List cur) {
11312 final ContentResolver resolver = mContext.getContentResolver();
11313 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11314 if (list == null) {
11315 return cur;
11316 }
11317 int N = list.size();
11318 for (int i=0; i<N; i++) {
11319 Intent intent = list.get(i);
11320 if (filter.match(resolver, intent, true, TAG) >= 0) {
11321 if (cur == null) {
11322 cur = new ArrayList<Intent>();
11323 }
11324 cur.add(intent);
11325 }
11326 }
11327 return cur;
11328 }
11329
11330 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011331 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011332 + mBroadcastsScheduled);
11333
11334 if (mBroadcastsScheduled) {
11335 return;
11336 }
11337 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11338 mBroadcastsScheduled = true;
11339 }
11340
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011341 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011342 IIntentReceiver receiver, IntentFilter filter, String permission) {
11343 synchronized(this) {
11344 ProcessRecord callerApp = null;
11345 if (caller != null) {
11346 callerApp = getRecordForAppLocked(caller);
11347 if (callerApp == null) {
11348 throw new SecurityException(
11349 "Unable to find app for caller " + caller
11350 + " (pid=" + Binder.getCallingPid()
11351 + ") when registering receiver " + receiver);
11352 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011353 if (callerApp.info.uid != Process.SYSTEM_UID &&
11354 !callerApp.pkgList.contains(callerPackage)) {
11355 throw new SecurityException("Given caller package " + callerPackage
11356 + " is not running in process " + callerApp);
11357 }
11358 } else {
11359 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 }
11361
11362 List allSticky = null;
11363
11364 // Look for any matching sticky broadcasts...
11365 Iterator actions = filter.actionsIterator();
11366 if (actions != null) {
11367 while (actions.hasNext()) {
11368 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011369 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011370 }
11371 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011372 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011373 }
11374
11375 // The first sticky in the list is returned directly back to
11376 // the client.
11377 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11378
Joe Onorato8a9b2202010-02-26 18:56:32 -080011379 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011380 + ": " + sticky);
11381
11382 if (receiver == null) {
11383 return sticky;
11384 }
11385
11386 ReceiverList rl
11387 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11388 if (rl == null) {
11389 rl = new ReceiverList(this, callerApp,
11390 Binder.getCallingPid(),
11391 Binder.getCallingUid(), receiver);
11392 if (rl.app != null) {
11393 rl.app.receivers.add(rl);
11394 } else {
11395 try {
11396 receiver.asBinder().linkToDeath(rl, 0);
11397 } catch (RemoteException e) {
11398 return sticky;
11399 }
11400 rl.linkedToDeath = true;
11401 }
11402 mRegisteredReceivers.put(receiver.asBinder(), rl);
11403 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011404 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011405 rl.add(bf);
11406 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011407 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011408 }
11409 mReceiverResolver.addFilter(bf);
11410
11411 // Enqueue broadcasts for all existing stickies that match
11412 // this filter.
11413 if (allSticky != null) {
11414 ArrayList receivers = new ArrayList();
11415 receivers.add(bf);
11416
11417 int N = allSticky.size();
11418 for (int i=0; i<N; i++) {
11419 Intent intent = (Intent)allSticky.get(i);
11420 BroadcastRecord r = new BroadcastRecord(intent, null,
11421 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011422 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011423 if (mParallelBroadcasts.size() == 0) {
11424 scheduleBroadcastsLocked();
11425 }
11426 mParallelBroadcasts.add(r);
11427 }
11428 }
11429
11430 return sticky;
11431 }
11432 }
11433
11434 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011435 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011436
11437 boolean doNext = false;
11438
11439 synchronized(this) {
11440 ReceiverList rl
11441 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11442 if (rl != null) {
11443 if (rl.curBroadcast != null) {
11444 BroadcastRecord r = rl.curBroadcast;
11445 doNext = finishReceiverLocked(
11446 receiver.asBinder(), r.resultCode, r.resultData,
11447 r.resultExtras, r.resultAbort, true);
11448 }
11449
11450 if (rl.app != null) {
11451 rl.app.receivers.remove(rl);
11452 }
11453 removeReceiverLocked(rl);
11454 if (rl.linkedToDeath) {
11455 rl.linkedToDeath = false;
11456 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11457 }
11458 }
11459 }
11460
11461 if (!doNext) {
11462 return;
11463 }
11464
11465 final long origId = Binder.clearCallingIdentity();
11466 processNextBroadcast(false);
11467 trimApplications();
11468 Binder.restoreCallingIdentity(origId);
11469 }
11470
11471 void removeReceiverLocked(ReceiverList rl) {
11472 mRegisteredReceivers.remove(rl.receiver.asBinder());
11473 int N = rl.size();
11474 for (int i=0; i<N; i++) {
11475 mReceiverResolver.removeFilter(rl.get(i));
11476 }
11477 }
11478
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011479 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11480 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11481 ProcessRecord r = mLruProcesses.get(i);
11482 if (r.thread != null) {
11483 try {
11484 r.thread.dispatchPackageBroadcast(cmd, packages);
11485 } catch (RemoteException ex) {
11486 }
11487 }
11488 }
11489 }
11490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011491 private final int broadcastIntentLocked(ProcessRecord callerApp,
11492 String callerPackage, Intent intent, String resolvedType,
11493 IIntentReceiver resultTo, int resultCode, String resultData,
11494 Bundle map, String requiredPermission,
11495 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11496 intent = new Intent(intent);
11497
Dianne Hackborne7f97212011-02-24 14:40:20 -080011498 // By default broadcasts do not go to stopped apps.
11499 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11500
Joe Onorato8a9b2202010-02-26 18:56:32 -080011501 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011502 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11503 + " ordered=" + ordered);
11504 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011505 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011506 }
11507
11508 // Handle special intents: if this broadcast is from the package
11509 // manager about a package being removed, we need to remove all of
11510 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011511 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011512 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011513 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11514 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011515 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011516 || uidRemoved) {
11517 if (checkComponentPermission(
11518 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011519 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011520 == PackageManager.PERMISSION_GRANTED) {
11521 if (uidRemoved) {
11522 final Bundle intentExtras = intent.getExtras();
11523 final int uid = intentExtras != null
11524 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11525 if (uid >= 0) {
11526 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11527 synchronized (bs) {
11528 bs.removeUidStatsLocked(uid);
11529 }
11530 }
11531 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011532 // If resources are unvailble just force stop all
11533 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011534 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011535 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11536 if (list != null && (list.length > 0)) {
11537 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011538 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011539 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011540 sendPackageBroadcastLocked(
11541 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011542 }
11543 } else {
11544 Uri data = intent.getData();
11545 String ssp;
11546 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11547 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11548 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011549 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011550 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011551 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011552 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11553 new String[] {ssp});
11554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011555 }
11556 }
11557 }
11558 } else {
11559 String msg = "Permission Denial: " + intent.getAction()
11560 + " broadcast from " + callerPackage + " (pid=" + callingPid
11561 + ", uid=" + callingUid + ")"
11562 + " requires "
11563 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011564 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011565 throw new SecurityException(msg);
11566 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011567
11568 // Special case for adding a package: by default turn on compatibility
11569 // mode.
11570 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011571 Uri data = intent.getData();
11572 String ssp;
11573 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11574 mCompatModePackages.handlePackageAddedLocked(ssp,
11575 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011577 }
11578
11579 /*
11580 * If this is the time zone changed action, queue up a message that will reset the timezone
11581 * of all currently running processes. This message will get queued up before the broadcast
11582 * happens.
11583 */
11584 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11585 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11586 }
11587
Robert Greenwalt03595d02010-11-02 14:08:23 -070011588 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11589 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11590 }
11591
Robert Greenwalt434203a2010-10-11 16:00:27 -070011592 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11593 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11594 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11595 }
11596
Dianne Hackborn854060af2009-07-09 18:14:31 -070011597 /*
11598 * Prevent non-system code (defined here to be non-persistent
11599 * processes) from sending protected broadcasts.
11600 */
11601 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11602 || callingUid == Process.SHELL_UID || callingUid == 0) {
11603 // Always okay.
11604 } else if (callerApp == null || !callerApp.persistent) {
11605 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011606 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011607 intent.getAction())) {
11608 String msg = "Permission Denial: not allowed to send broadcast "
11609 + intent.getAction() + " from pid="
11610 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011611 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011612 throw new SecurityException(msg);
11613 }
11614 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011615 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011616 return BROADCAST_SUCCESS;
11617 }
11618 }
11619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011620 // Add to the sticky list if requested.
11621 if (sticky) {
11622 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11623 callingPid, callingUid)
11624 != PackageManager.PERMISSION_GRANTED) {
11625 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11626 + callingPid + ", uid=" + callingUid
11627 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011628 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 throw new SecurityException(msg);
11630 }
11631 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011632 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011633 + " and enforce permission " + requiredPermission);
11634 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11635 }
11636 if (intent.getComponent() != null) {
11637 throw new SecurityException(
11638 "Sticky broadcasts can't target a specific component");
11639 }
11640 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11641 if (list == null) {
11642 list = new ArrayList<Intent>();
11643 mStickyBroadcasts.put(intent.getAction(), list);
11644 }
11645 int N = list.size();
11646 int i;
11647 for (i=0; i<N; i++) {
11648 if (intent.filterEquals(list.get(i))) {
11649 // This sticky already exists, replace it.
11650 list.set(i, new Intent(intent));
11651 break;
11652 }
11653 }
11654 if (i >= N) {
11655 list.add(new Intent(intent));
11656 }
11657 }
11658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011659 // Figure out who all will receive this broadcast.
11660 List receivers = null;
11661 List<BroadcastFilter> registeredReceivers = null;
11662 try {
11663 if (intent.getComponent() != null) {
11664 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011665 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011666 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011667 if (ai != null) {
11668 receivers = new ArrayList();
11669 ResolveInfo ri = new ResolveInfo();
11670 ri.activityInfo = ai;
11671 receivers.add(ri);
11672 }
11673 } else {
11674 // Need to resolve the intent to interested receivers...
11675 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11676 == 0) {
11677 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011678 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011679 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011680 }
Mihai Preda074edef2009-05-18 17:13:31 +020011681 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 }
11683 } catch (RemoteException ex) {
11684 // pm is in same process, this will never happen.
11685 }
11686
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011687 final boolean replacePending =
11688 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11689
Joe Onorato8a9b2202010-02-26 18:56:32 -080011690 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011691 + " replacePending=" + replacePending);
11692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011693 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11694 if (!ordered && NR > 0) {
11695 // If we are not serializing this broadcast, then send the
11696 // registered receivers separately so they don't wait for the
11697 // components to be launched.
11698 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11699 callerPackage, callingPid, callingUid, requiredPermission,
11700 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011701 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011702 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 TAG, "Enqueueing parallel broadcast " + r
11704 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011705 boolean replaced = false;
11706 if (replacePending) {
11707 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11708 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011709 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011710 "***** DROPPING PARALLEL: " + intent);
11711 mParallelBroadcasts.set(i, r);
11712 replaced = true;
11713 break;
11714 }
11715 }
11716 }
11717 if (!replaced) {
11718 mParallelBroadcasts.add(r);
11719 scheduleBroadcastsLocked();
11720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721 registeredReceivers = null;
11722 NR = 0;
11723 }
11724
11725 // Merge into one list.
11726 int ir = 0;
11727 if (receivers != null) {
11728 // A special case for PACKAGE_ADDED: do not allow the package
11729 // being added to see this broadcast. This prevents them from
11730 // using this as a back door to get run as soon as they are
11731 // installed. Maybe in the future we want to have a special install
11732 // broadcast or such for apps, but we'd like to deliberately make
11733 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011734 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011735 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11736 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11737 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011738 Uri data = intent.getData();
11739 if (data != null) {
11740 String pkgName = data.getSchemeSpecificPart();
11741 if (pkgName != null) {
11742 skipPackages = new String[] { pkgName };
11743 }
11744 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011745 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011746 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011747 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011748 if (skipPackages != null && (skipPackages.length > 0)) {
11749 for (String skipPackage : skipPackages) {
11750 if (skipPackage != null) {
11751 int NT = receivers.size();
11752 for (int it=0; it<NT; it++) {
11753 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11754 if (curt.activityInfo.packageName.equals(skipPackage)) {
11755 receivers.remove(it);
11756 it--;
11757 NT--;
11758 }
11759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 }
11761 }
11762 }
11763
11764 int NT = receivers != null ? receivers.size() : 0;
11765 int it = 0;
11766 ResolveInfo curt = null;
11767 BroadcastFilter curr = null;
11768 while (it < NT && ir < NR) {
11769 if (curt == null) {
11770 curt = (ResolveInfo)receivers.get(it);
11771 }
11772 if (curr == null) {
11773 curr = registeredReceivers.get(ir);
11774 }
11775 if (curr.getPriority() >= curt.priority) {
11776 // Insert this broadcast record into the final list.
11777 receivers.add(it, curr);
11778 ir++;
11779 curr = null;
11780 it++;
11781 NT++;
11782 } else {
11783 // Skip to the next ResolveInfo in the final list.
11784 it++;
11785 curt = null;
11786 }
11787 }
11788 }
11789 while (ir < NR) {
11790 if (receivers == null) {
11791 receivers = new ArrayList();
11792 }
11793 receivers.add(registeredReceivers.get(ir));
11794 ir++;
11795 }
11796
11797 if ((receivers != null && receivers.size() > 0)
11798 || resultTo != null) {
11799 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11800 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011801 receivers, resultTo, resultCode, resultData, map, ordered,
11802 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011803 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011804 TAG, "Enqueueing ordered broadcast " + r
11805 + ": prev had " + mOrderedBroadcasts.size());
11806 if (DEBUG_BROADCAST) {
11807 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011808 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011809 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011810 boolean replaced = false;
11811 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011812 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011813 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011814 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011815 "***** DROPPING ORDERED: " + intent);
11816 mOrderedBroadcasts.set(i, r);
11817 replaced = true;
11818 break;
11819 }
11820 }
11821 }
11822 if (!replaced) {
11823 mOrderedBroadcasts.add(r);
11824 scheduleBroadcastsLocked();
11825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011826 }
11827
11828 return BROADCAST_SUCCESS;
11829 }
11830
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011831 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011832 // Refuse possible leaked file descriptors
11833 if (intent != null && intent.hasFileDescriptors() == true) {
11834 throw new IllegalArgumentException("File descriptors passed in Intent");
11835 }
11836
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011837 int flags = intent.getFlags();
11838
11839 if (!mProcessesReady) {
11840 // if the caller really truly claims to know what they're doing, go
11841 // ahead and allow the broadcast without launching any receivers
11842 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11843 intent = new Intent(intent);
11844 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11845 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11846 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11847 + " before boot completion");
11848 throw new IllegalStateException("Cannot broadcast before boot completed");
11849 }
11850 }
11851
11852 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11853 throw new IllegalArgumentException(
11854 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11855 }
11856
11857 return intent;
11858 }
11859
11860 public final int broadcastIntent(IApplicationThread caller,
11861 Intent intent, String resolvedType, IIntentReceiver resultTo,
11862 int resultCode, String resultData, Bundle map,
11863 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011865 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11868 final int callingPid = Binder.getCallingPid();
11869 final int callingUid = Binder.getCallingUid();
11870 final long origId = Binder.clearCallingIdentity();
11871 int res = broadcastIntentLocked(callerApp,
11872 callerApp != null ? callerApp.info.packageName : null,
11873 intent, resolvedType, resultTo,
11874 resultCode, resultData, map, requiredPermission, serialized,
11875 sticky, callingPid, callingUid);
11876 Binder.restoreCallingIdentity(origId);
11877 return res;
11878 }
11879 }
11880
11881 int broadcastIntentInPackage(String packageName, int uid,
11882 Intent intent, String resolvedType, IIntentReceiver resultTo,
11883 int resultCode, String resultData, Bundle map,
11884 String requiredPermission, boolean serialized, boolean sticky) {
11885 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011886 intent = verifyBroadcastLocked(intent);
11887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011888 final long origId = Binder.clearCallingIdentity();
11889 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11890 resultTo, resultCode, resultData, map, requiredPermission,
11891 serialized, sticky, -1, uid);
11892 Binder.restoreCallingIdentity(origId);
11893 return res;
11894 }
11895 }
11896
11897 public final void unbroadcastIntent(IApplicationThread caller,
11898 Intent intent) {
11899 // Refuse possible leaked file descriptors
11900 if (intent != null && intent.hasFileDescriptors() == true) {
11901 throw new IllegalArgumentException("File descriptors passed in Intent");
11902 }
11903
11904 synchronized(this) {
11905 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11906 != PackageManager.PERMISSION_GRANTED) {
11907 String msg = "Permission Denial: unbroadcastIntent() from pid="
11908 + Binder.getCallingPid()
11909 + ", uid=" + Binder.getCallingUid()
11910 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011911 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011912 throw new SecurityException(msg);
11913 }
11914 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11915 if (list != null) {
11916 int N = list.size();
11917 int i;
11918 for (i=0; i<N; i++) {
11919 if (intent.filterEquals(list.get(i))) {
11920 list.remove(i);
11921 break;
11922 }
11923 }
11924 }
11925 }
11926 }
11927
11928 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11929 String resultData, Bundle resultExtras, boolean resultAbort,
11930 boolean explicit) {
11931 if (mOrderedBroadcasts.size() == 0) {
11932 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011933 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011934 }
11935 return false;
11936 }
11937 BroadcastRecord r = mOrderedBroadcasts.get(0);
11938 if (r.receiver == null) {
11939 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011940 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011941 }
11942 return false;
11943 }
11944 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011945 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011946 return false;
11947 }
11948 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011949 r.state = BroadcastRecord.IDLE;
11950 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011951 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011952 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011953 }
11954 }
11955 r.receiver = null;
11956 r.intent.setComponent(null);
11957 if (r.curApp != null) {
11958 r.curApp.curReceiver = null;
11959 }
11960 if (r.curFilter != null) {
11961 r.curFilter.receiverList.curBroadcast = null;
11962 }
11963 r.curFilter = null;
11964 r.curApp = null;
11965 r.curComponent = null;
11966 r.curReceiver = null;
11967 mPendingBroadcast = null;
11968
11969 r.resultCode = resultCode;
11970 r.resultData = resultData;
11971 r.resultExtras = resultExtras;
11972 r.resultAbort = resultAbort;
11973
11974 // We will process the next receiver right now if this is finishing
11975 // an app receiver (which is always asynchronous) or after we have
11976 // come back from calling a receiver.
11977 return state == BroadcastRecord.APP_RECEIVE
11978 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11979 }
11980
11981 public void finishReceiver(IBinder who, int resultCode, String resultData,
11982 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011983 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011984
11985 // Refuse possible leaked file descriptors
11986 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11987 throw new IllegalArgumentException("File descriptors passed in Bundle");
11988 }
11989
11990 boolean doNext;
11991
11992 final long origId = Binder.clearCallingIdentity();
11993
11994 synchronized(this) {
11995 doNext = finishReceiverLocked(
11996 who, resultCode, resultData, resultExtras, resultAbort, true);
11997 }
11998
11999 if (doNext) {
12000 processNextBroadcast(false);
12001 }
12002 trimApplications();
12003
12004 Binder.restoreCallingIdentity(origId);
12005 }
12006
Jeff Brown4d94a762010-09-23 11:33:28 -070012007 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008 if (r.nextReceiver > 0) {
12009 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12010 if (curReceiver instanceof BroadcastFilter) {
12011 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012012 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 System.identityHashCode(r),
12014 r.intent.getAction(),
12015 r.nextReceiver - 1,
12016 System.identityHashCode(bf));
12017 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012018 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012019 System.identityHashCode(r),
12020 r.intent.getAction(),
12021 r.nextReceiver - 1,
12022 ((ResolveInfo)curReceiver).toString());
12023 }
12024 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012025 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012027 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 System.identityHashCode(r),
12029 r.intent.getAction(),
12030 r.nextReceiver,
12031 "NONE");
12032 }
12033 }
12034
Jeff Brown4d94a762010-09-23 11:33:28 -070012035 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12036 if (! mPendingBroadcastTimeoutMessage) {
12037 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12038 mHandler.sendMessageAtTime(msg, timeoutTime);
12039 mPendingBroadcastTimeoutMessage = true;
12040 }
12041 }
12042
12043 private final void cancelBroadcastTimeoutLocked() {
12044 if (mPendingBroadcastTimeoutMessage) {
12045 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12046 mPendingBroadcastTimeoutMessage = false;
12047 }
12048 }
12049
12050 private final void broadcastTimeoutLocked(boolean fromMsg) {
12051 if (fromMsg) {
12052 mPendingBroadcastTimeoutMessage = false;
12053 }
12054
12055 if (mOrderedBroadcasts.size() == 0) {
12056 return;
12057 }
12058
12059 long now = SystemClock.uptimeMillis();
12060 BroadcastRecord r = mOrderedBroadcasts.get(0);
12061 if (fromMsg) {
12062 if (mDidDexOpt) {
12063 // Delay timeouts until dexopt finishes.
12064 mDidDexOpt = false;
12065 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12066 setBroadcastTimeoutLocked(timeoutTime);
12067 return;
12068 }
12069 if (! mProcessesReady) {
12070 // Only process broadcast timeouts if the system is ready. That way
12071 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12072 // to do heavy lifting for system up.
12073 return;
12074 }
12075
12076 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12077 if (timeoutTime > now) {
12078 // We can observe premature timeouts because we do not cancel and reset the
12079 // broadcast timeout message after each receiver finishes. Instead, we set up
12080 // an initial timeout then kick it down the road a little further as needed
12081 // when it expires.
12082 if (DEBUG_BROADCAST) Slog.v(TAG,
12083 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12084 + timeoutTime);
12085 setBroadcastTimeoutLocked(timeoutTime);
12086 return;
12087 }
12088 }
12089
12090 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12091 + ", started " + (now - r.receiverTime) + "ms ago");
12092 r.receiverTime = now;
12093 r.anrCount++;
12094
12095 // Current receiver has passed its expiration date.
12096 if (r.nextReceiver <= 0) {
12097 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12098 return;
12099 }
12100
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012101 ProcessRecord app = null;
12102 String anrMessage = null;
12103
Jeff Brown4d94a762010-09-23 11:33:28 -070012104 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12105 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12106 logBroadcastReceiverDiscardLocked(r);
12107 if (curReceiver instanceof BroadcastFilter) {
12108 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12109 if (bf.receiverList.pid != 0
12110 && bf.receiverList.pid != MY_PID) {
12111 synchronized (this.mPidsSelfLocked) {
12112 app = this.mPidsSelfLocked.get(
12113 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012115 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012116 } else {
12117 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012119
Jeff Brown4d94a762010-09-23 11:33:28 -070012120 if (app != null) {
12121 anrMessage = "Broadcast of " + r.intent.toString();
12122 }
12123
12124 if (mPendingBroadcast == r) {
12125 mPendingBroadcast = null;
12126 }
12127
12128 // Move on to the next receiver.
12129 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12130 r.resultExtras, r.resultAbort, true);
12131 scheduleBroadcastsLocked();
12132
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012133 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012134 // Post the ANR to the handler since we do not want to process ANRs while
12135 // potentially holding our lock.
12136 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012138 }
12139
12140 private final void processCurBroadcastLocked(BroadcastRecord r,
12141 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012142 if (DEBUG_BROADCAST) Slog.v(TAG,
12143 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012144 if (app.thread == null) {
12145 throw new RemoteException();
12146 }
12147 r.receiver = app.thread.asBinder();
12148 r.curApp = app;
12149 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012150 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012151
12152 // Tell the application to launch this receiver.
12153 r.intent.setComponent(r.curComponent);
12154
12155 boolean started = false;
12156 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012157 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012158 "Delivering to component " + r.curComponent
12159 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012160 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012161 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012162 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012163 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012164 if (DEBUG_BROADCAST) Slog.v(TAG,
12165 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012166 started = true;
12167 } finally {
12168 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012169 if (DEBUG_BROADCAST) Slog.v(TAG,
12170 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012171 r.receiver = null;
12172 r.curApp = null;
12173 app.curReceiver = null;
12174 }
12175 }
12176
12177 }
12178
Jeff Brown4d94a762010-09-23 11:33:28 -070012179 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012180 Intent intent, int resultCode, String data, Bundle extras,
12181 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012182 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012183 if (app != null && app.thread != null) {
12184 // If we have an app thread, do the call through that so it is
12185 // correctly ordered with other one-way calls.
12186 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012187 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012189 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012190 }
12191 }
12192
Jeff Brown4d94a762010-09-23 11:33:28 -070012193 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012194 BroadcastFilter filter, boolean ordered) {
12195 boolean skip = false;
12196 if (filter.requiredPermission != null) {
12197 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012198 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012200 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 + r.intent.toString()
12202 + " from " + r.callerPackage + " (pid="
12203 + r.callingPid + ", uid=" + r.callingUid + ")"
12204 + " requires " + filter.requiredPermission
12205 + " due to registered receiver " + filter);
12206 skip = true;
12207 }
12208 }
12209 if (r.requiredPermission != null) {
12210 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012211 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012212 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012213 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 + r.intent.toString()
12215 + " to " + filter.receiverList.app
12216 + " (pid=" + filter.receiverList.pid
12217 + ", uid=" + filter.receiverList.uid + ")"
12218 + " requires " + r.requiredPermission
12219 + " due to sender " + r.callerPackage
12220 + " (uid " + r.callingUid + ")");
12221 skip = true;
12222 }
12223 }
12224
12225 if (!skip) {
12226 // If this is not being sent as an ordered broadcast, then we
12227 // don't want to touch the fields that keep track of the current
12228 // state of ordered broadcasts.
12229 if (ordered) {
12230 r.receiver = filter.receiverList.receiver.asBinder();
12231 r.curFilter = filter;
12232 filter.receiverList.curBroadcast = r;
12233 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012234 if (filter.receiverList.app != null) {
12235 // Bump hosting application to no longer be in background
12236 // scheduling class. Note that we can't do that if there
12237 // isn't an app... but we can only be in that case for
12238 // things that directly call the IActivityManager API, which
12239 // are already core system stuff so don't matter for this.
12240 r.curApp = filter.receiverList.app;
12241 filter.receiverList.app.curReceiver = r;
12242 updateOomAdjLocked();
12243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012244 }
12245 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012246 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012247 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012248 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012249 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012250 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012251 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012252 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012253 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012254 if (ordered) {
12255 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12256 }
12257 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012258 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012259 if (ordered) {
12260 r.receiver = null;
12261 r.curFilter = null;
12262 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012263 if (filter.receiverList.app != null) {
12264 filter.receiverList.app.curReceiver = null;
12265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012266 }
12267 }
12268 }
12269 }
12270
Dianne Hackborn12527f92009-11-11 17:39:50 -080012271 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12272 if (r.callingUid < 0) {
12273 // This was from a registerReceiver() call; ignore it.
12274 return;
12275 }
12276 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12277 MAX_BROADCAST_HISTORY-1);
12278 r.finishTime = SystemClock.uptimeMillis();
12279 mBroadcastHistory[0] = r;
12280 }
12281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012282 private final void processNextBroadcast(boolean fromMsg) {
12283 synchronized(this) {
12284 BroadcastRecord r;
12285
Joe Onorato8a9b2202010-02-26 18:56:32 -080012286 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012287 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012288 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289
12290 updateCpuStats();
12291
12292 if (fromMsg) {
12293 mBroadcastsScheduled = false;
12294 }
12295
12296 // First, deliver any non-serialized broadcasts right away.
12297 while (mParallelBroadcasts.size() > 0) {
12298 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012299 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012300 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012301 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012302 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012303 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012304 for (int i=0; i<N; i++) {
12305 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012306 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012307 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012308 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012309 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012311 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012312 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012313 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012314 }
12315
12316 // Now take care of the next serialized one...
12317
12318 // If we are waiting for a process to come up to handle the next
12319 // broadcast, then do nothing at this point. Just in case, we
12320 // check that the process we're waiting for still exists.
12321 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012322 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012323 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012324 + mPendingBroadcast.curApp);
12325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012326
12327 boolean isDead;
12328 synchronized (mPidsSelfLocked) {
12329 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12330 }
12331 if (!isDead) {
12332 // It's still alive, so keep waiting
12333 return;
12334 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012335 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012337 mPendingBroadcast.state = BroadcastRecord.IDLE;
12338 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 mPendingBroadcast = null;
12340 }
12341 }
12342
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012343 boolean looped = false;
12344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012345 do {
12346 if (mOrderedBroadcasts.size() == 0) {
12347 // No more broadcasts pending, so all done!
12348 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012349 if (looped) {
12350 // If we had finished the last ordered broadcast, then
12351 // make sure all processes have correct oom and sched
12352 // adjustments.
12353 updateOomAdjLocked();
12354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 return;
12356 }
12357 r = mOrderedBroadcasts.get(0);
12358 boolean forceReceive = false;
12359
12360 // Ensure that even if something goes awry with the timeout
12361 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012362 // and continue to make progress.
12363 //
12364 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012365 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012366 // one time heavy lifting after system upgrades and can take
12367 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012368 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012369 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012370 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371 if ((numReceivers > 0) &&
12372 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012373 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 + " now=" + now
12375 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012376 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012377 + " intent=" + r.intent
12378 + " numReceivers=" + numReceivers
12379 + " nextReceiver=" + r.nextReceiver
12380 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012381 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012382 forceReceive = true;
12383 r.state = BroadcastRecord.IDLE;
12384 }
12385 }
12386
12387 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012388 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012389 "processNextBroadcast() called when not idle (state="
12390 + r.state + ")");
12391 return;
12392 }
12393
12394 if (r.receivers == null || r.nextReceiver >= numReceivers
12395 || r.resultAbort || forceReceive) {
12396 // No more receivers for this broadcast! Send the final
12397 // result if requested...
12398 if (r.resultTo != null) {
12399 try {
12400 if (DEBUG_BROADCAST) {
12401 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012402 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012403 + " seq=" + seq + " app=" + r.callerApp);
12404 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012405 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012406 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012407 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012408 // Set this to null so that the reference
12409 // (local and remote) isnt kept in the mBroadcastHistory.
12410 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012411 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012412 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413 }
12414 }
12415
Joe Onorato8a9b2202010-02-26 18:56:32 -080012416 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012417 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418
Joe Onorato8a9b2202010-02-26 18:56:32 -080012419 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012420 + r);
12421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012422 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012423 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012424 mOrderedBroadcasts.remove(0);
12425 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012426 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012427 continue;
12428 }
12429 } while (r == null);
12430
12431 // Get the next receiver...
12432 int recIdx = r.nextReceiver++;
12433
12434 // Keep track of when this receiver started, and make sure there
12435 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012436 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012437 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012438 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012439 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012440 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012441 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012442 }
12443 if (! mPendingBroadcastTimeoutMessage) {
12444 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012445 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012446 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12447 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012448 }
12449
12450 Object nextReceiver = r.receivers.get(recIdx);
12451 if (nextReceiver instanceof BroadcastFilter) {
12452 // Simple case: this is a registered receiver who gets
12453 // a direct call.
12454 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012455 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012456 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012457 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012458 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 if (r.receiver == null || !r.ordered) {
12460 // The receiver has already finished, so schedule to
12461 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012462 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12463 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 r.state = BroadcastRecord.IDLE;
12465 scheduleBroadcastsLocked();
12466 }
12467 return;
12468 }
12469
12470 // Hard case: need to instantiate the receiver, possibly
12471 // starting its application process to host it.
12472
12473 ResolveInfo info =
12474 (ResolveInfo)nextReceiver;
12475
12476 boolean skip = false;
12477 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012478 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12479 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012480 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012481 if (!info.activityInfo.exported) {
12482 Slog.w(TAG, "Permission Denial: broadcasting "
12483 + r.intent.toString()
12484 + " from " + r.callerPackage + " (pid=" + r.callingPid
12485 + ", uid=" + r.callingUid + ")"
12486 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12487 + " due to receiver " + info.activityInfo.packageName
12488 + "/" + info.activityInfo.name);
12489 } else {
12490 Slog.w(TAG, "Permission Denial: broadcasting "
12491 + r.intent.toString()
12492 + " from " + r.callerPackage + " (pid=" + r.callingPid
12493 + ", uid=" + r.callingUid + ")"
12494 + " requires " + info.activityInfo.permission
12495 + " due to receiver " + info.activityInfo.packageName
12496 + "/" + info.activityInfo.name);
12497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012498 skip = true;
12499 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012500 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012501 r.requiredPermission != null) {
12502 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012503 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 checkPermission(r.requiredPermission,
12505 info.activityInfo.applicationInfo.packageName);
12506 } catch (RemoteException e) {
12507 perm = PackageManager.PERMISSION_DENIED;
12508 }
12509 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012510 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012511 + r.intent + " to "
12512 + info.activityInfo.applicationInfo.packageName
12513 + " requires " + r.requiredPermission
12514 + " due to sender " + r.callerPackage
12515 + " (uid " + r.callingUid + ")");
12516 skip = true;
12517 }
12518 }
12519 if (r.curApp != null && r.curApp.crashing) {
12520 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012521 if (DEBUG_BROADCAST) Slog.v(TAG,
12522 "Skipping deliver ordered " + r + " to " + r.curApp
12523 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012524 skip = true;
12525 }
12526
12527 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012528 if (DEBUG_BROADCAST) Slog.v(TAG,
12529 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012530 r.receiver = null;
12531 r.curFilter = null;
12532 r.state = BroadcastRecord.IDLE;
12533 scheduleBroadcastsLocked();
12534 return;
12535 }
12536
12537 r.state = BroadcastRecord.APP_RECEIVE;
12538 String targetProcess = info.activityInfo.processName;
12539 r.curComponent = new ComponentName(
12540 info.activityInfo.applicationInfo.packageName,
12541 info.activityInfo.name);
12542 r.curReceiver = info.activityInfo;
12543
Dianne Hackborne7f97212011-02-24 14:40:20 -080012544 // Broadcast is being executed, its package can't be stopped.
12545 try {
12546 AppGlobals.getPackageManager().setPackageStoppedState(
12547 r.curComponent.getPackageName(), false);
12548 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012549 } catch (IllegalArgumentException e) {
12550 Slog.w(TAG, "Failed trying to unstop package "
12551 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012552 }
12553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012554 // Is this receiver's application already running?
12555 ProcessRecord app = getProcessRecordLocked(targetProcess,
12556 info.activityInfo.applicationInfo.uid);
12557 if (app != null && app.thread != null) {
12558 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012559 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012560 processCurBroadcastLocked(r, app);
12561 return;
12562 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012563 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012564 + r.curComponent, e);
12565 }
12566
12567 // If a dead object exception was thrown -- fall through to
12568 // restart the application.
12569 }
12570
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012571 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012572 if (DEBUG_BROADCAST) Slog.v(TAG,
12573 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574 if ((r.curApp=startProcessLocked(targetProcess,
12575 info.activityInfo.applicationInfo, true,
12576 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012577 "broadcast", r.curComponent,
12578 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12579 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012580 // Ah, this recipient is unavailable. Finish it if necessary,
12581 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012582 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012583 + info.activityInfo.applicationInfo.packageName + "/"
12584 + info.activityInfo.applicationInfo.uid + " for broadcast "
12585 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012586 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012587 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12588 r.resultExtras, r.resultAbort, true);
12589 scheduleBroadcastsLocked();
12590 r.state = BroadcastRecord.IDLE;
12591 return;
12592 }
12593
12594 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012595 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012596 }
12597 }
12598
12599 // =========================================================
12600 // INSTRUMENTATION
12601 // =========================================================
12602
12603 public boolean startInstrumentation(ComponentName className,
12604 String profileFile, int flags, Bundle arguments,
12605 IInstrumentationWatcher watcher) {
12606 // Refuse possible leaked file descriptors
12607 if (arguments != null && arguments.hasFileDescriptors()) {
12608 throw new IllegalArgumentException("File descriptors passed in Bundle");
12609 }
12610
12611 synchronized(this) {
12612 InstrumentationInfo ii = null;
12613 ApplicationInfo ai = null;
12614 try {
12615 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012616 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012617 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012618 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012619 } catch (PackageManager.NameNotFoundException e) {
12620 }
12621 if (ii == null) {
12622 reportStartInstrumentationFailure(watcher, className,
12623 "Unable to find instrumentation info for: " + className);
12624 return false;
12625 }
12626 if (ai == null) {
12627 reportStartInstrumentationFailure(watcher, className,
12628 "Unable to find instrumentation target package: " + ii.targetPackage);
12629 return false;
12630 }
12631
12632 int match = mContext.getPackageManager().checkSignatures(
12633 ii.targetPackage, ii.packageName);
12634 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12635 String msg = "Permission Denial: starting instrumentation "
12636 + className + " from pid="
12637 + Binder.getCallingPid()
12638 + ", uid=" + Binder.getCallingPid()
12639 + " not allowed because package " + ii.packageName
12640 + " does not have a signature matching the target "
12641 + ii.targetPackage;
12642 reportStartInstrumentationFailure(watcher, className, msg);
12643 throw new SecurityException(msg);
12644 }
12645
12646 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012647 // Instrumentation can kill and relaunch even persistent processes
12648 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012649 ProcessRecord app = addAppLocked(ai);
12650 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012651 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012652 app.instrumentationProfileFile = profileFile;
12653 app.instrumentationArguments = arguments;
12654 app.instrumentationWatcher = watcher;
12655 app.instrumentationResultClass = className;
12656 Binder.restoreCallingIdentity(origId);
12657 }
12658
12659 return true;
12660 }
12661
12662 /**
12663 * Report errors that occur while attempting to start Instrumentation. Always writes the
12664 * error to the logs, but if somebody is watching, send the report there too. This enables
12665 * the "am" command to report errors with more information.
12666 *
12667 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12668 * @param cn The component name of the instrumentation.
12669 * @param report The error report.
12670 */
12671 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12672 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012673 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012674 try {
12675 if (watcher != null) {
12676 Bundle results = new Bundle();
12677 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12678 results.putString("Error", report);
12679 watcher.instrumentationStatus(cn, -1, results);
12680 }
12681 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012682 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012683 }
12684 }
12685
12686 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12687 if (app.instrumentationWatcher != null) {
12688 try {
12689 // NOTE: IInstrumentationWatcher *must* be oneway here
12690 app.instrumentationWatcher.instrumentationFinished(
12691 app.instrumentationClass,
12692 resultCode,
12693 results);
12694 } catch (RemoteException e) {
12695 }
12696 }
12697 app.instrumentationWatcher = null;
12698 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012699 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 app.instrumentationProfileFile = null;
12701 app.instrumentationArguments = null;
12702
Christopher Tate3dacd842011-08-19 14:56:15 -070012703 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012704 }
12705
12706 public void finishInstrumentation(IApplicationThread target,
12707 int resultCode, Bundle results) {
12708 // Refuse possible leaked file descriptors
12709 if (results != null && results.hasFileDescriptors()) {
12710 throw new IllegalArgumentException("File descriptors passed in Intent");
12711 }
12712
12713 synchronized(this) {
12714 ProcessRecord app = getRecordForAppLocked(target);
12715 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012716 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012717 return;
12718 }
12719 final long origId = Binder.clearCallingIdentity();
12720 finishInstrumentationLocked(app, resultCode, results);
12721 Binder.restoreCallingIdentity(origId);
12722 }
12723 }
12724
12725 // =========================================================
12726 // CONFIGURATION
12727 // =========================================================
12728
12729 public ConfigurationInfo getDeviceConfigurationInfo() {
12730 ConfigurationInfo config = new ConfigurationInfo();
12731 synchronized (this) {
12732 config.reqTouchScreen = mConfiguration.touchscreen;
12733 config.reqKeyboardType = mConfiguration.keyboard;
12734 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012735 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12736 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012737 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12738 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012739 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12740 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012741 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12742 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012743 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012744 }
12745 return config;
12746 }
12747
12748 public Configuration getConfiguration() {
12749 Configuration ci;
12750 synchronized(this) {
12751 ci = new Configuration(mConfiguration);
12752 }
12753 return ci;
12754 }
12755
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012756 public void updatePersistentConfiguration(Configuration values) {
12757 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12758 "updateConfiguration()");
12759 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12760 "updateConfiguration()");
12761 if (values == null) {
12762 throw new NullPointerException("Configuration must not be null");
12763 }
12764
12765 synchronized(this) {
12766 final long origId = Binder.clearCallingIdentity();
12767 updateConfigurationLocked(values, null, true);
12768 Binder.restoreCallingIdentity(origId);
12769 }
12770 }
12771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012772 public void updateConfiguration(Configuration values) {
12773 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12774 "updateConfiguration()");
12775
12776 synchronized(this) {
12777 if (values == null && mWindowManager != null) {
12778 // sentinel: fetch the current configuration from the window manager
12779 values = mWindowManager.computeNewConfiguration();
12780 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012781
12782 if (mWindowManager != null) {
12783 mProcessList.applyDisplaySize(mWindowManager);
12784 }
12785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012786 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012787 if (values != null) {
12788 Settings.System.clearConfiguration(values);
12789 }
12790 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012791 Binder.restoreCallingIdentity(origId);
12792 }
12793 }
12794
12795 /**
12796 * Do either or both things: (1) change the current configuration, and (2)
12797 * make sure the given activity is running with the (now) current
12798 * configuration. Returns true if the activity has been left running, or
12799 * false if <var>starting</var> is being destroyed to match the new
12800 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012801 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 */
12803 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012804 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012805 int changes = 0;
12806
12807 boolean kept = true;
12808
12809 if (values != null) {
12810 Configuration newConfig = new Configuration(mConfiguration);
12811 changes = newConfig.updateFrom(values);
12812 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012813 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012814 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012815 }
12816
Doug Zongker2bec3d42009-12-04 12:52:44 -080012817 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012818
12819 if (values.locale != null) {
12820 saveLocaleLocked(values.locale,
12821 !values.locale.equals(mConfiguration.locale),
12822 values.userSetLocale);
12823 }
12824
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012825 mConfigurationSeq++;
12826 if (mConfigurationSeq <= 0) {
12827 mConfigurationSeq = 1;
12828 }
12829 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012830 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012831 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012832
12833 AttributeCache ac = AttributeCache.instance();
12834 if (ac != null) {
12835 ac.updateConfiguration(mConfiguration);
12836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012837
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012838 // Make sure all resources in our process are updated
12839 // right now, so that anyone who is going to retrieve
12840 // resource values after we return will be sure to get
12841 // the new ones. This is especially important during
12842 // boot, where the first config change needs to guarantee
12843 // all resources have that config before following boot
12844 // code is executed.
12845 mSystemThread.applyConfigurationToResources(newConfig);
12846
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012847 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012848 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12849 msg.obj = new Configuration(mConfiguration);
12850 mHandler.sendMessage(msg);
12851 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012852
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012853 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12854 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012855 try {
12856 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012857 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012858 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 app.thread.scheduleConfigurationChanged(mConfiguration);
12860 }
12861 } catch (Exception e) {
12862 }
12863 }
12864 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012865 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12866 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012867 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12868 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012869 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12870 broadcastIntentLocked(null, null,
12871 new Intent(Intent.ACTION_LOCALE_CHANGED),
12872 null, null, 0, null, null,
12873 null, false, false, MY_PID, Process.SYSTEM_UID);
12874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012875 }
12876 }
12877
12878 if (changes != 0 && starting == null) {
12879 // If the configuration changed, and the caller is not already
12880 // in the process of starting an activity, then find the top
12881 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012882 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012883 }
12884
12885 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012886 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012887 // And we need to make sure at this point that all other activities
12888 // are made visible with the correct configuration.
12889 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 }
12891
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012892 if (values != null && mWindowManager != null) {
12893 mWindowManager.setNewConfiguration(mConfiguration);
12894 }
12895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896 return kept;
12897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012898
12899 /**
12900 * Save the locale. You must be inside a synchronized (this) block.
12901 */
12902 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12903 if(isDiff) {
12904 SystemProperties.set("user.language", l.getLanguage());
12905 SystemProperties.set("user.region", l.getCountry());
12906 }
12907
12908 if(isPersist) {
12909 SystemProperties.set("persist.sys.language", l.getLanguage());
12910 SystemProperties.set("persist.sys.country", l.getCountry());
12911 SystemProperties.set("persist.sys.localevar", l.getVariant());
12912 }
12913 }
12914
12915 // =========================================================
12916 // LIFETIME MANAGEMENT
12917 // =========================================================
12918
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012919 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12920 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012921 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012922 // This adjustment has already been computed. If we are calling
12923 // from the top, we may have already computed our adjustment with
12924 // an earlier hidden adjustment that isn't really for us... if
12925 // so, use the new hidden adjustment.
12926 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012927 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012928 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012929 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012930 }
12931
12932 if (app.thread == null) {
12933 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012934 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012935 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012936 }
12937
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012938 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12939 app.adjSource = null;
12940 app.adjTarget = null;
12941 app.empty = false;
12942 app.hidden = false;
12943
12944 final int activitiesSize = app.activities.size();
12945
Dianne Hackborn7d608422011-08-07 16:24:18 -070012946 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012947 // The max adjustment doesn't allow this app to be anything
12948 // below foreground, so it is not worth doing work for it.
12949 app.adjType = "fixed";
12950 app.adjSeq = mAdjSeq;
12951 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012952 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012953 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012954 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012955 // System process can do UI, and when they do we want to have
12956 // them trim their memory after the user leaves the UI. To
12957 // facilitate this, here we need to determine whether or not it
12958 // is currently showing UI.
12959 app.systemNoUi = true;
12960 if (app == TOP_APP) {
12961 app.systemNoUi = false;
12962 } else if (activitiesSize > 0) {
12963 for (int j = 0; j < activitiesSize; j++) {
12964 final ActivityRecord r = app.activities.get(j);
12965 if (r.visible) {
12966 app.systemNoUi = false;
12967 break;
12968 }
12969 }
12970 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012971 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012972 }
12973
12974 final boolean hadForegroundActivities = app.foregroundActivities;
12975
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012976 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012977 app.keeping = false;
12978 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012979
The Android Open Source Project4df24232009-03-05 14:34:35 -080012980 // Determine the importance of the process, starting with most
12981 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012982 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012983 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012984 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012985 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012986 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012987 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012988 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012989 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012990 } else if (app.instrumentationClass != null) {
12991 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012992 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012993 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012994 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 } else if (app.curReceiver != null ||
12996 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12997 // An app that is currently receiving a broadcast also
12998 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012999 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013000 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013001 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013002 } else if (app.executingServices.size() > 0) {
13003 // An app that is currently executing a service callback also
13004 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013005 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013006 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013007 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013008 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013009 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013010 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013012 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013013 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013014 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013015 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013016 // A very not-needed process. If this is lower in the lru list,
13017 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013018 adj = hiddenAdj;
13019 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013020 app.hidden = true;
13021 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013022 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013023 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013024
13025 // Examine all activities if not already foreground.
13026 if (!app.foregroundActivities && activitiesSize > 0) {
13027 for (int j = 0; j < activitiesSize; j++) {
13028 final ActivityRecord r = app.activities.get(j);
13029 if (r.visible) {
13030 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013031 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13032 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013033 app.adjType = "visible";
13034 }
13035 schedGroup = Process.THREAD_GROUP_DEFAULT;
13036 app.hidden = false;
13037 app.foregroundActivities = true;
13038 break;
13039 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13040 || r.state == ActivityState.STOPPING) {
13041 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013042 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13043 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013044 app.adjType = "stopping";
13045 }
13046 app.foregroundActivities = true;
13047 }
13048 }
13049 }
13050
Dianne Hackborn7d608422011-08-07 16:24:18 -070013051 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013052 if (app.foregroundServices) {
13053 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013054 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013055 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013056 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013057 } else if (app.forcingToForeground != null) {
13058 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013059 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013060 app.adjType = "force-foreground";
13061 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013062 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013063 }
13064 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013065
Dianne Hackborn7d608422011-08-07 16:24:18 -070013066 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013067 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013068 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013069 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13070 app.adjType = "heavy";
13071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013072
Dianne Hackborn7d608422011-08-07 16:24:18 -070013073 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013074 // This process is hosting what we currently consider to be the
13075 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013076 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013077 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13078 app.adjType = "home";
13079 }
13080
Joe Onorato8a9b2202010-02-26 18:56:32 -080013081 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013082
The Android Open Source Project4df24232009-03-05 14:34:35 -080013083 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013084 // there are applications dependent on our services or providers, but
13085 // this gives us a baseline and makes sure we don't get into an
13086 // infinite recursion.
13087 app.adjSeq = mAdjSeq;
13088 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013089
Christopher Tate6fa95972009-06-05 18:43:55 -070013090 if (mBackupTarget != null && app == mBackupTarget.app) {
13091 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013092 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013093 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013094 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013095 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013096 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013097 }
13098 }
13099
Dianne Hackborn7d608422011-08-07 16:24:18 -070013100 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013101 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013102 final long now = SystemClock.uptimeMillis();
13103 // This process is more important if the top activity is
13104 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013105 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013106 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013107 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013108 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013109 if (app.hasShownUi) {
13110 // If this process has shown some UI, let it immediately
13111 // go to the LRU list because it may be pretty heavy with
13112 // UI stuff. We'll tag it with a label just to help
13113 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013114 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013115 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013116 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013117 } else {
13118 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13119 // This service has seen some activity within
13120 // recent memory, so we will keep its process ahead
13121 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013122 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13123 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013124 app.adjType = "started-services";
13125 app.hidden = false;
13126 }
13127 }
13128 // If we have let the service slide into the background
13129 // state, still have some text describing what it is doing
13130 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013131 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013132 app.adjType = "started-bg-services";
13133 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013134 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013135 // Don't kill this process because it is doing work; it
13136 // has said it is doing work.
13137 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013139 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013140 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013141 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013142 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013143 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013144 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013145 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013146 // XXX should compute this based on the max of
13147 // all connected clients.
13148 ConnectionRecord cr = clist.get(i);
13149 if (cr.binding.client == app) {
13150 // Binding to ourself is not interesting.
13151 continue;
13152 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013153 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013154 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013155 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013156 int myHiddenAdj = hiddenAdj;
13157 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013158 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013159 myHiddenAdj = client.hiddenAdj;
13160 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013161 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013162 }
13163 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013164 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013165 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013166 String adjType = null;
13167 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13168 // Not doing bind OOM management, so treat
13169 // this guy more like a started service.
13170 if (app.hasShownUi) {
13171 // If this process has shown some UI, let it immediately
13172 // go to the LRU list because it may be pretty heavy with
13173 // UI stuff. We'll tag it with a label just to help
13174 // debug and understand what is going on.
13175 if (adj > clientAdj) {
13176 adjType = "bound-bg-ui-services";
13177 }
13178 clientAdj = adj;
13179 } else {
13180 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13181 // This service has not seen activity within
13182 // recent memory, so allow it to drop to the
13183 // LRU list if there is no other reason to keep
13184 // it around. We'll also tag it with a label just
13185 // to help debug and undertand what is going on.
13186 if (adj > clientAdj) {
13187 adjType = "bound-bg-services";
13188 }
13189 clientAdj = adj;
13190 }
13191 }
13192 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013193 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013194 // If this process has recently shown UI, and
13195 // the process that is binding to it is less
13196 // important than being visible, then we don't
13197 // care about the binding as much as we care
13198 // about letting this process get into the LRU
13199 // list to be killed and restarted if needed for
13200 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013201 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013202 adjType = "bound-bg-ui-services";
13203 } else {
13204 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13205 |Context.BIND_IMPORTANT)) != 0) {
13206 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013207 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013208 adj = clientAdj;
13209 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013210 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013211 }
13212 if (!client.hidden) {
13213 app.hidden = false;
13214 }
13215 if (client.keeping) {
13216 app.keeping = true;
13217 }
13218 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013219 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013220 }
13221 if (adjType != null) {
13222 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013223 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13224 .REASON_SERVICE_IN_USE;
13225 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013226 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013227 app.adjTarget = s.name;
13228 }
13229 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13230 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13231 schedGroup = Process.THREAD_GROUP_DEFAULT;
13232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013233 }
13234 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013235 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13236 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013237 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013238 (a.visible || a.state == ActivityState.RESUMED
13239 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013240 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013241 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13242 schedGroup = Process.THREAD_GROUP_DEFAULT;
13243 }
13244 app.hidden = false;
13245 app.adjType = "service";
13246 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13247 .REASON_SERVICE_IN_USE;
13248 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013249 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013250 app.adjTarget = s.name;
13251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013253 }
13254 }
13255 }
13256 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013257
Dianne Hackborn287952c2010-09-22 22:34:31 -070013258 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013259 // would like to avoid killing it unless it would prevent the current
13260 // application from running. By default we put the process in
13261 // with the rest of the background processes; as we scan through
13262 // its services we may bump it up from there.
13263 if (adj > hiddenAdj) {
13264 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013265 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013266 app.adjType = "bg-services";
13267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013268 }
13269
Dianne Hackborn7d608422011-08-07 16:24:18 -070013270 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013271 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013272 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013273 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013274 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013275 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013276 if (cpr.clients.size() != 0) {
13277 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013278 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013279 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013280 if (client == app) {
13281 // Being our own client is not interesting.
13282 continue;
13283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013284 int myHiddenAdj = hiddenAdj;
13285 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013286 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013287 myHiddenAdj = client.hiddenAdj;
13288 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013289 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013290 }
13291 }
13292 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013293 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013294 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013295 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013296 app.adjType = "bg-ui-provider";
13297 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013298 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13299 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013300 app.adjType = "provider";
13301 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013302 if (!client.hidden) {
13303 app.hidden = false;
13304 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013305 if (client.keeping) {
13306 app.keeping = true;
13307 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013308 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13309 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013310 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013311 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013312 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013313 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013314 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13315 schedGroup = Process.THREAD_GROUP_DEFAULT;
13316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013317 }
13318 }
13319 // If the provider has external (non-framework) process
13320 // dependencies, ensure that its adjustment is at least
13321 // FOREGROUND_APP_ADJ.
13322 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013323 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13324 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013325 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013326 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013327 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013328 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013329 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013330 }
13331 }
13332 }
13333 }
13334
13335 app.curRawAdj = adj;
13336
Joe Onorato8a9b2202010-02-26 18:56:32 -080013337 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013338 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13339 if (adj > app.maxAdj) {
13340 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013341 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013342 schedGroup = Process.THREAD_GROUP_DEFAULT;
13343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013344 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013345 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013346 app.keeping = true;
13347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013348
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013349 if (app.hasAboveClient) {
13350 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13351 // then we need to drop its adjustment to be lower than the service's
13352 // in order to honor the request. We want to drop it by one adjustment
13353 // level... but there is special meaning applied to various levels so
13354 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013355 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013356 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013357 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13358 adj = ProcessList.VISIBLE_APP_ADJ;
13359 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13360 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13361 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13362 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13363 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013364 adj++;
13365 }
13366 }
13367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013368 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013369 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013370
13371 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013372 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13373 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013374 }
13375
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013376 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013377 }
13378
13379 /**
13380 * Ask a given process to GC right now.
13381 */
13382 final void performAppGcLocked(ProcessRecord app) {
13383 try {
13384 app.lastRequestedGc = SystemClock.uptimeMillis();
13385 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013386 if (app.reportLowMemory) {
13387 app.reportLowMemory = false;
13388 app.thread.scheduleLowMemory();
13389 } else {
13390 app.thread.processInBackground();
13391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013392 }
13393 } catch (Exception e) {
13394 // whatever.
13395 }
13396 }
13397
13398 /**
13399 * Returns true if things are idle enough to perform GCs.
13400 */
Josh Bartel7f208742010-02-25 11:01:44 -060013401 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013402 return mParallelBroadcasts.size() == 0
13403 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013404 && (mSleeping || (mMainStack.mResumedActivity != null &&
13405 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013406 }
13407
13408 /**
13409 * Perform GCs on all processes that are waiting for it, but only
13410 * if things are idle.
13411 */
13412 final void performAppGcsLocked() {
13413 final int N = mProcessesToGc.size();
13414 if (N <= 0) {
13415 return;
13416 }
Josh Bartel7f208742010-02-25 11:01:44 -060013417 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013418 while (mProcessesToGc.size() > 0) {
13419 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013420 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013421 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13422 <= SystemClock.uptimeMillis()) {
13423 // To avoid spamming the system, we will GC processes one
13424 // at a time, waiting a few seconds between each.
13425 performAppGcLocked(proc);
13426 scheduleAppGcsLocked();
13427 return;
13428 } else {
13429 // It hasn't been long enough since we last GCed this
13430 // process... put it in the list to wait for its time.
13431 addProcessToGcListLocked(proc);
13432 break;
13433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013434 }
13435 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013436
13437 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013438 }
13439 }
13440
13441 /**
13442 * If all looks good, perform GCs on all processes waiting for them.
13443 */
13444 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013445 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013446 performAppGcsLocked();
13447 return;
13448 }
13449 // Still not idle, wait some more.
13450 scheduleAppGcsLocked();
13451 }
13452
13453 /**
13454 * Schedule the execution of all pending app GCs.
13455 */
13456 final void scheduleAppGcsLocked() {
13457 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013458
13459 if (mProcessesToGc.size() > 0) {
13460 // Schedule a GC for the time to the next process.
13461 ProcessRecord proc = mProcessesToGc.get(0);
13462 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13463
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013464 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013465 long now = SystemClock.uptimeMillis();
13466 if (when < (now+GC_TIMEOUT)) {
13467 when = now + GC_TIMEOUT;
13468 }
13469 mHandler.sendMessageAtTime(msg, when);
13470 }
13471 }
13472
13473 /**
13474 * Add a process to the array of processes waiting to be GCed. Keeps the
13475 * list in sorted order by the last GC time. The process can't already be
13476 * on the list.
13477 */
13478 final void addProcessToGcListLocked(ProcessRecord proc) {
13479 boolean added = false;
13480 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13481 if (mProcessesToGc.get(i).lastRequestedGc <
13482 proc.lastRequestedGc) {
13483 added = true;
13484 mProcessesToGc.add(i+1, proc);
13485 break;
13486 }
13487 }
13488 if (!added) {
13489 mProcessesToGc.add(0, proc);
13490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013491 }
13492
13493 /**
13494 * Set up to ask a process to GC itself. This will either do it
13495 * immediately, or put it on the list of processes to gc the next
13496 * time things are idle.
13497 */
13498 final void scheduleAppGcLocked(ProcessRecord app) {
13499 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013500 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013501 return;
13502 }
13503 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013504 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013505 scheduleAppGcsLocked();
13506 }
13507 }
13508
Dianne Hackborn287952c2010-09-22 22:34:31 -070013509 final void checkExcessivePowerUsageLocked(boolean doKills) {
13510 updateCpuStatsNow();
13511
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013512 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013513 boolean doWakeKills = doKills;
13514 boolean doCpuKills = doKills;
13515 if (mLastPowerCheckRealtime == 0) {
13516 doWakeKills = false;
13517 }
13518 if (mLastPowerCheckUptime == 0) {
13519 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013520 }
13521 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013522 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013523 }
13524 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013525 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13526 final long curUptime = SystemClock.uptimeMillis();
13527 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13528 mLastPowerCheckRealtime = curRealtime;
13529 mLastPowerCheckUptime = curUptime;
13530 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13531 doWakeKills = false;
13532 }
13533 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13534 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013535 }
13536 int i = mLruProcesses.size();
13537 while (i > 0) {
13538 i--;
13539 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013540 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013541 long wtime;
13542 synchronized (stats) {
13543 wtime = stats.getProcessWakeTime(app.info.uid,
13544 app.pid, curRealtime);
13545 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013546 long wtimeUsed = wtime - app.lastWakeTime;
13547 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13548 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013549 StringBuilder sb = new StringBuilder(128);
13550 sb.append("Wake for ");
13551 app.toShortString(sb);
13552 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013553 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013554 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013555 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013556 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013557 sb.append((wtimeUsed*100)/realtimeSince);
13558 sb.append("%)");
13559 Slog.i(TAG, sb.toString());
13560 sb.setLength(0);
13561 sb.append("CPU for ");
13562 app.toShortString(sb);
13563 sb.append(": over ");
13564 TimeUtils.formatDuration(uptimeSince, sb);
13565 sb.append(" used ");
13566 TimeUtils.formatDuration(cputimeUsed, sb);
13567 sb.append(" (");
13568 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013569 sb.append("%)");
13570 Slog.i(TAG, sb.toString());
13571 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013572 // If a process has held a wake lock for more
13573 // than 50% of the time during this period,
13574 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013575 if (doWakeKills && realtimeSince > 0
13576 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13577 synchronized (stats) {
13578 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13579 realtimeSince, wtimeUsed);
13580 }
13581 Slog.w(TAG, "Excessive wake lock in " + app.processName
13582 + " (pid " + app.pid + "): held " + wtimeUsed
13583 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013584 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13585 app.processName, app.setAdj, "excessive wake lock");
13586 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013587 } else if (doCpuKills && uptimeSince > 0
13588 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13589 synchronized (stats) {
13590 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13591 uptimeSince, cputimeUsed);
13592 }
13593 Slog.w(TAG, "Excessive CPU in " + app.processName
13594 + " (pid " + app.pid + "): used " + cputimeUsed
13595 + " during " + uptimeSince);
13596 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13597 app.processName, app.setAdj, "excessive cpu");
13598 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013599 } else {
13600 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013601 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013602 }
13603 }
13604 }
13605 }
13606
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013607 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013608 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013609 app.hiddenAdj = hiddenAdj;
13610
13611 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013612 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013613 }
13614
Dianne Hackborn287952c2010-09-22 22:34:31 -070013615 final boolean wasKeeping = app.keeping;
13616
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013617 boolean success = true;
13618
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013619 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013620
Jeff Brown10e89712011-07-08 18:52:57 -070013621 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013622 if (false) {
13623 // Removing for now. Forcing GCs is not so useful anymore
13624 // with Dalvik, and the new memory level hint facility is
13625 // better for what we need to do these days.
13626 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13627 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13628 // If this app is transitioning from foreground to
13629 // non-foreground, have it do a gc.
13630 scheduleAppGcLocked(app);
13631 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13632 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13633 // Likewise do a gc when an app is moving in to the
13634 // background (such as a service stopping).
13635 scheduleAppGcLocked(app);
13636 }
Jeff Brown10e89712011-07-08 18:52:57 -070013637 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013638
Jeff Brown10e89712011-07-08 18:52:57 -070013639 if (wasKeeping && !app.keeping) {
13640 // This app is no longer something we want to keep. Note
13641 // its current wake lock time to later know to kill it if
13642 // it is not behaving well.
13643 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13644 synchronized (stats) {
13645 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13646 app.pid, SystemClock.elapsedRealtime());
13647 }
13648 app.lastCpuTime = app.curCpuTime;
13649 }
13650
13651 app.setRawAdj = app.curRawAdj;
13652 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013653 if (app.curAdj != app.setAdj) {
13654 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013655 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13656 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013657 " oom adj to " + app.curAdj + " because " + app.adjType);
13658 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013659 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013660 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013661 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013662 }
13663 }
13664 if (app.setSchedGroup != app.curSchedGroup) {
13665 app.setSchedGroup = app.curSchedGroup;
13666 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13667 "Setting process group of " + app.processName
13668 + " to " + app.curSchedGroup);
13669 if (app.waitingToKill != null &&
13670 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13671 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13672 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13673 app.processName, app.setAdj, app.waitingToKill);
13674 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013675 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013676 } else {
13677 if (true) {
13678 long oldId = Binder.clearCallingIdentity();
13679 try {
13680 Process.setProcessGroup(app.pid, app.curSchedGroup);
13681 } catch (Exception e) {
13682 Slog.w(TAG, "Failed setting process group of " + app.pid
13683 + " to " + app.curSchedGroup);
13684 e.printStackTrace();
13685 } finally {
13686 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013687 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013688 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013689 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013690 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013691 app.thread.setSchedulingGroup(app.curSchedGroup);
13692 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013693 }
13694 }
13695 }
13696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013697 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013698 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013699 }
13700
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013701 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013702 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013703 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013704 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013705 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013706 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013707 }
13708 }
13709 return resumedActivity;
13710 }
13711
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013712 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013713 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013714 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13715 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013716 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13717 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013718
13719 mAdjSeq++;
13720
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013721 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013722 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13723 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013724 if (nowHidden != wasHidden) {
13725 // Changed to/from hidden state, so apps after it in the LRU
13726 // list may also be changed.
13727 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013728 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013729 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013730 }
13731
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013732 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013733 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013734 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13735
13736 if (false) {
13737 RuntimeException e = new RuntimeException();
13738 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013739 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013740 }
13741
13742 mAdjSeq++;
13743
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013744 // Let's determine how many processes we have running vs.
13745 // how many slots we have for background processes; we may want
13746 // to put multiple processes in a slot of there are enough of
13747 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013748 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013749 int factor = (mLruProcesses.size()-4)/numSlots;
13750 if (factor < 1) factor = 1;
13751 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013752 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013753
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013754 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013755 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013756 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013757 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013758 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013759 while (i > 0) {
13760 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013761 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013762 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013763 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013764 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013765 && app.curAdj == curHiddenAdj) {
13766 step++;
13767 if (step >= factor) {
13768 step = 0;
13769 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013770 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013771 }
13772 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013773 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013774 numHidden++;
13775 if (numHidden > mProcessLimit) {
13776 Slog.i(TAG, "No longer want " + app.processName
13777 + " (pid " + app.pid + "): hidden #" + numHidden);
13778 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13779 app.processName, app.setAdj, "too many background");
13780 app.killedBackground = true;
13781 Process.killProcessQuiet(app.pid);
13782 } else {
13783 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013784 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013785 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013786 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013787 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013788 }
13789 }
13790
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013791 // Now determine the memory trimming level of background processes.
13792 // Unfortunately we need to start at the back of the list to do this
13793 // properly. We only do this if the number of background apps we
13794 // are managing to keep around is less than half the maximum we desire;
13795 // if we are keeping a good number around, we'll let them use whatever
13796 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013797 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013798 final int N = mLruProcesses.size();
13799 factor = numBg/3;
13800 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013801 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013802 for (i=0; i<N; i++) {
13803 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013804 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013805 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13806 try {
13807 app.thread.scheduleTrimMemory(curLevel);
13808 } catch (RemoteException e) {
13809 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013810 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013811 // For these apps we will also finish their activities
13812 // to help them free memory.
13813 mMainStack.destroyActivitiesLocked(app, false);
13814 }
13815 }
13816 app.trimMemoryLevel = curLevel;
13817 step++;
13818 if (step >= factor) {
13819 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013820 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13821 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013822 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013823 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13824 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013825 break;
13826 }
13827 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013828 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013829 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013830 && app.thread != null) {
13831 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013832 app.thread.scheduleTrimMemory(
13833 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013834 } catch (RemoteException e) {
13835 }
13836 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013837 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013838 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013839 && app.pendingUiClean) {
13840 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13841 && app.thread != null) {
13842 try {
13843 app.thread.scheduleTrimMemory(
13844 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13845 } catch (RemoteException e) {
13846 }
13847 }
13848 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13849 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013850 } else {
13851 app.trimMemoryLevel = 0;
13852 }
13853 }
13854 } else {
13855 final int N = mLruProcesses.size();
13856 for (i=0; i<N; i++) {
13857 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013858 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013859 && app.pendingUiClean) {
13860 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13861 && app.thread != null) {
13862 try {
13863 app.thread.scheduleTrimMemory(
13864 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13865 } catch (RemoteException e) {
13866 }
13867 }
13868 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13869 app.pendingUiClean = false;
13870 } else {
13871 app.trimMemoryLevel = 0;
13872 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013873 }
13874 }
13875
13876 if (mAlwaysFinishActivities) {
13877 mMainStack.destroyActivitiesLocked(null, false);
13878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013879 }
13880
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013881 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013882 synchronized (this) {
13883 int i;
13884
13885 // First remove any unused application processes whose package
13886 // has been removed.
13887 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13888 final ProcessRecord app = mRemovedProcesses.get(i);
13889 if (app.activities.size() == 0
13890 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013891 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013892 TAG, "Exiting empty application process "
13893 + app.processName + " ("
13894 + (app.thread != null ? app.thread.asBinder() : null)
13895 + ")\n");
13896 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013897 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13898 app.processName, app.setAdj, "empty");
13899 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013900 } else {
13901 try {
13902 app.thread.scheduleExit();
13903 } catch (Exception e) {
13904 // Ignore exceptions.
13905 }
13906 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013907 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013908 mRemovedProcesses.remove(i);
13909
13910 if (app.persistent) {
13911 if (app.persistent) {
13912 addAppLocked(app.info);
13913 }
13914 }
13915 }
13916 }
13917
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013918 // Now update the oom adj for all processes.
13919 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013920 }
13921 }
13922
13923 /** This method sends the specified signal to each of the persistent apps */
13924 public void signalPersistentProcesses(int sig) throws RemoteException {
13925 if (sig != Process.SIGNAL_USR1) {
13926 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13927 }
13928
13929 synchronized (this) {
13930 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13931 != PackageManager.PERMISSION_GRANTED) {
13932 throw new SecurityException("Requires permission "
13933 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13934 }
13935
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013936 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13937 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013938 if (r.thread != null && r.persistent) {
13939 Process.sendSignal(r.pid, sig);
13940 }
13941 }
13942 }
13943 }
13944
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013945 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13946 if (proc == null || proc == mProfileProc) {
13947 proc = mProfileProc;
13948 path = mProfileFile;
13949 profileType = mProfileType;
13950 clearProfilerLocked();
13951 }
13952 if (proc == null) {
13953 return;
13954 }
13955 try {
13956 proc.thread.profilerControl(false, path, null, profileType);
13957 } catch (RemoteException e) {
13958 throw new IllegalStateException("Process disappeared");
13959 }
13960 }
13961
13962 private void clearProfilerLocked() {
13963 if (mProfileFd != null) {
13964 try {
13965 mProfileFd.close();
13966 } catch (IOException e) {
13967 }
13968 }
13969 mProfileApp = null;
13970 mProfileProc = null;
13971 mProfileFile = null;
13972 mProfileType = 0;
13973 mAutoStopProfiler = false;
13974 }
13975
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013976 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013977 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013978
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013979 try {
13980 synchronized (this) {
13981 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13982 // its own permission.
13983 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13984 != PackageManager.PERMISSION_GRANTED) {
13985 throw new SecurityException("Requires permission "
13986 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013987 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013988
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013989 if (start && fd == null) {
13990 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013991 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013992
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013993 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013994 if (process != null) {
13995 try {
13996 int pid = Integer.parseInt(process);
13997 synchronized (mPidsSelfLocked) {
13998 proc = mPidsSelfLocked.get(pid);
13999 }
14000 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014001 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014002
14003 if (proc == null) {
14004 HashMap<String, SparseArray<ProcessRecord>> all
14005 = mProcessNames.getMap();
14006 SparseArray<ProcessRecord> procs = all.get(process);
14007 if (procs != null && procs.size() > 0) {
14008 proc = procs.valueAt(0);
14009 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014010 }
14011 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014012
14013 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014014 throw new IllegalArgumentException("Unknown process: " + process);
14015 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014016
14017 if (start) {
14018 stopProfilerLocked(null, null, 0);
14019 setProfileApp(proc.info, proc.processName, path, fd, false);
14020 mProfileProc = proc;
14021 mProfileType = profileType;
14022 try {
14023 fd = fd.dup();
14024 } catch (IOException e) {
14025 fd = null;
14026 }
14027 proc.thread.profilerControl(start, path, fd, profileType);
14028 fd = null;
14029 mProfileFd = null;
14030 } else {
14031 stopProfilerLocked(proc, path, profileType);
14032 if (fd != null) {
14033 try {
14034 fd.close();
14035 } catch (IOException e) {
14036 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014037 }
14038 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014039
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014040 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014041 }
14042 } catch (RemoteException e) {
14043 throw new IllegalStateException("Process disappeared");
14044 } finally {
14045 if (fd != null) {
14046 try {
14047 fd.close();
14048 } catch (IOException e) {
14049 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014050 }
14051 }
14052 }
Andy McFadden824c5102010-07-09 16:26:57 -070014053
14054 public boolean dumpHeap(String process, boolean managed,
14055 String path, ParcelFileDescriptor fd) throws RemoteException {
14056
14057 try {
14058 synchronized (this) {
14059 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14060 // its own permission (same as profileControl).
14061 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14062 != PackageManager.PERMISSION_GRANTED) {
14063 throw new SecurityException("Requires permission "
14064 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14065 }
14066
14067 if (fd == null) {
14068 throw new IllegalArgumentException("null fd");
14069 }
14070
14071 ProcessRecord proc = null;
14072 try {
14073 int pid = Integer.parseInt(process);
14074 synchronized (mPidsSelfLocked) {
14075 proc = mPidsSelfLocked.get(pid);
14076 }
14077 } catch (NumberFormatException e) {
14078 }
14079
14080 if (proc == null) {
14081 HashMap<String, SparseArray<ProcessRecord>> all
14082 = mProcessNames.getMap();
14083 SparseArray<ProcessRecord> procs = all.get(process);
14084 if (procs != null && procs.size() > 0) {
14085 proc = procs.valueAt(0);
14086 }
14087 }
14088
14089 if (proc == null || proc.thread == null) {
14090 throw new IllegalArgumentException("Unknown process: " + process);
14091 }
14092
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014093 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14094 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014095 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14096 throw new SecurityException("Process not debuggable: " + proc);
14097 }
14098 }
14099
14100 proc.thread.dumpHeap(managed, path, fd);
14101 fd = null;
14102 return true;
14103 }
14104 } catch (RemoteException e) {
14105 throw new IllegalStateException("Process disappeared");
14106 } finally {
14107 if (fd != null) {
14108 try {
14109 fd.close();
14110 } catch (IOException e) {
14111 }
14112 }
14113 }
14114 }
14115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014116 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14117 public void monitor() {
14118 synchronized (this) { }
14119 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014120
14121 public void onCoreSettingsChange(Bundle settings) {
14122 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14123 ProcessRecord processRecord = mLruProcesses.get(i);
14124 try {
14125 if (processRecord.thread != null) {
14126 processRecord.thread.setCoreSettings(settings);
14127 }
14128 } catch (RemoteException re) {
14129 /* ignore */
14130 }
14131 }
14132 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014133
14134 // Multi-user methods
14135
14136 public boolean switchUser(int userid) {
14137 // TODO
14138 return true;
14139 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014140}